diff --git a/AndEngine/.classpath b/AndEngine/.classpath new file mode 100644 index 0000000..6e9239f --- /dev/null +++ b/AndEngine/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/AndEngine/.hg/00changelog.i b/AndEngine/.hg/00changelog.i new file mode 100644 index 0000000..d3a8311 Binary files /dev/null and b/AndEngine/.hg/00changelog.i differ diff --git a/AndEngine/.hg/branch b/AndEngine/.hg/branch new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/AndEngine/.hg/branch @@ -0,0 +1 @@ +default diff --git a/AndEngine/.hg/cache/branchheads b/AndEngine/.hg/cache/branchheads new file mode 100644 index 0000000..c61da8a --- /dev/null +++ b/AndEngine/.hg/cache/branchheads @@ -0,0 +1,19 @@ +029966d918208057cef0cffcb84d0e32c3beb646 784 +2dee11d83d693d785195343f6fbe7d2ce0b567ac TouchEventsOnUpdateThread +2e844c1a354a71a73ccf30e9737f0eea7d8d17a1 FastFloatBuffer +36c43bb33de64566d43330b1fa73c1cb7884bfec MergeBranch +029966d918208057cef0cffcb84d0e32c3beb646 default +f44e9357b96930bcfdbbe42722e4aafeabcb5348 LayoutGameActivity +e34e17d611e5ad0a09a8763176fa7acce4194b94 NonPreMultipliedAlpha +1799f91abd4f320b173f3696ae8f930a6ff5f292 EntityContainer +d700719293bf02ed46a99e98dc86073d7b90b324 GL10.GL_TRIANGLES +36ab3f06a0f47bb8eaee4000c198024bdab015ba Android 1.5 +84c4e96d721f4757786a339c3ca67eb6b0820ca2 MultiTouch +41f112ad6fc0befe771dee174215d4d69fc43ecb OfficialParticleSystemsPimpingBranch +5ad7ab3a9b3e33a33d2b5eddcf9806031f72a3a2 SmoothBranch +209ea10ffd40e43ee2f4e1422b91a53b25b93ee0 TMXTiledLayer +fcb4ac4290d9697d40cbe407a0754cd45ae0c657 Performance +e37a873800764d2834bd37fe7a5b3ff539da2ee8 TMX-FlickerLines-Fix-Branch +b07091650a82148d68803af644f6ee64ea48ce3b DualThread +f9385530a6648a44244a627b1e23c05ea6462de1 glDrawTexfOES +d39c15639104b5f4eb1dbc398639cabd8daba680 RenderHandlerBranch diff --git a/AndEngine/.hg/cache/tags b/AndEngine/.hg/cache/tags new file mode 100644 index 0000000..daa840b --- /dev/null +++ b/AndEngine/.hg/cache/tags @@ -0,0 +1,6 @@ +784 029966d918208057cef0cffcb84d0e32c3beb646 +686 d39c15639104b5f4eb1dbc398639cabd8daba680 +427 e37a873800764d2834bd37fe7a5b3ff539da2ee8 +313 d700719293bf02ed46a99e98dc86073d7b90b324 +289 36ab3f06a0f47bb8eaee4000c198024bdab015ba + diff --git a/AndEngine/.hg/dirstate b/AndEngine/.hg/dirstate new file mode 100644 index 0000000..b45e07a Binary files /dev/null and b/AndEngine/.hg/dirstate differ diff --git a/AndEngine/.hg/hgrc b/AndEngine/.hg/hgrc new file mode 100644 index 0000000..b305abe --- /dev/null +++ b/AndEngine/.hg/hgrc @@ -0,0 +1,2 @@ +[paths] +default = https://andengine.googlecode.com/hg/ diff --git a/AndEngine/.hg/requires b/AndEngine/.hg/requires new file mode 100644 index 0000000..ca69271 --- /dev/null +++ b/AndEngine/.hg/requires @@ -0,0 +1,4 @@ +revlogv1 +store +fncache +dotencode diff --git a/AndEngine/.hg/store/00changelog.d b/AndEngine/.hg/store/00changelog.d new file mode 100644 index 0000000..62cd6cb Binary files /dev/null and b/AndEngine/.hg/store/00changelog.d differ diff --git a/AndEngine/.hg/store/00changelog.i b/AndEngine/.hg/store/00changelog.i new file mode 100644 index 0000000..a73d9ff Binary files /dev/null and b/AndEngine/.hg/store/00changelog.i differ diff --git a/AndEngine/.hg/store/00manifest.d b/AndEngine/.hg/store/00manifest.d new file mode 100644 index 0000000..9002f6b Binary files /dev/null and b/AndEngine/.hg/store/00manifest.d differ diff --git a/AndEngine/.hg/store/00manifest.i b/AndEngine/.hg/store/00manifest.i new file mode 100644 index 0000000..5cce68b Binary files /dev/null and b/AndEngine/.hg/store/00manifest.i differ diff --git a/AndEngine/.hg/store/data/_android_manifest.xml.i b/AndEngine/.hg/store/data/_android_manifest.xml.i new file mode 100644 index 0000000..8ff49fc Binary files /dev/null and b/AndEngine/.hg/store/data/_android_manifest.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_examples.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_examples.xml.i new file mode 100644 index 0000000..76a4bf4 Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_examples.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_live_wallpaper.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_live_wallpaper.xml.i new file mode 100644 index 0000000..2b094a9 Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_physics_box2_d.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_physics_box2_d.xml.i new file mode 100644 index 0000000..8978b3b Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_physics_box2_d.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_playground.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_playground.xml.i new file mode 100644 index 0000000..77ed4fd Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_and_engine_playground.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_box_face_stacker.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_box_face_stacker.xml.i new file mode 100644 index 0000000..5e75fa5 Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_box_face_stacker.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_campfire_live_wallpaper.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_campfire_live_wallpaper.xml.i new file mode 100644 index 0000000..6378c4f Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_campfire_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_cigarette_live_wallpaper.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_cigarette_live_wallpaper.xml.i new file mode 100644 index 0000000..8201d6e Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_cigarette_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi.xml.i new file mode 100644 index 0000000..77ff3b9 Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi_live_wallpaper.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi_live_wallpaper.xml.i new file mode 100644 index 0000000..c74525e Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi_shared.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi_shared.xml.i new file mode 100644 index 0000000..e1cd76d Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_heli_taxi_shared.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_high_rise.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_high_rise.xml.i new file mode 100644 index 0000000..32ea5bb Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_high_rise.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_lava_lamp_live_wallpaper.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_lava_lamp_live_wallpaper.xml.i new file mode 100644 index 0000000..d454ede Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_lava_lamp_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_super_droid.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_super_droid.xml.i new file mode 100644 index 0000000..7b55bbf Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_super_droid.xml.i differ diff --git a/AndEngine/.hg/store/data/ant/export_jar_to_volcano_live_wallpaper.xml.i b/AndEngine/.hg/store/data/ant/export_jar_to_volcano_live_wallpaper.xml.i new file mode 100644 index 0000000..23ea584 Binary files /dev/null and b/AndEngine/.hg/store/data/ant/export_jar_to_volcano_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/build__hudson.xml.i b/AndEngine/.hg/store/data/build__hudson.xml.i new file mode 100644 index 0000000..872fd7e Binary files /dev/null and b/AndEngine/.hg/store/data/build__hudson.xml.i differ diff --git a/AndEngine/.hg/store/data/default.properties.i b/AndEngine/.hg/store/data/default.properties.i new file mode 100644 index 0000000..a77bce9 Binary files /dev/null and b/AndEngine/.hg/store/data/default.properties.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_all.xml.i b/AndEngine/.hg/store/data/export_jar_to_all.xml.i new file mode 100644 index 0000000..385e489 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_all.xml.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_and_engine_examples.xml.i b/AndEngine/.hg/store/data/export_jar_to_and_engine_examples.xml.i new file mode 100644 index 0000000..e7dbcb9 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_and_engine_examples.xml.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_and_engine_live_wallpaper.xml.i b/AndEngine/.hg/store/data/export_jar_to_and_engine_live_wallpaper.xml.i new file mode 100644 index 0000000..18b36a5 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_and_engine_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_heli_taxi.xml.i b/AndEngine/.hg/store/data/export_jar_to_heli_taxi.xml.i new file mode 100644 index 0000000..a256388 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_heli_taxi.xml.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_heli_taxi_live_wallpaper.xml.i b/AndEngine/.hg/store/data/export_jar_to_heli_taxi_live_wallpaper.xml.i new file mode 100644 index 0000000..ec9a210 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_heli_taxi_live_wallpaper.xml.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_heli_taxi_shared.xml.i b/AndEngine/.hg/store/data/export_jar_to_heli_taxi_shared.xml.i new file mode 100644 index 0000000..73fb0f2 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_heli_taxi_shared.xml.i differ diff --git a/AndEngine/.hg/store/data/export_jar_to_space_taxi.xml.i b/AndEngine/.hg/store/data/export_jar_to_space_taxi.xml.i new file mode 100644 index 0000000..0e41c01 Binary files /dev/null and b/AndEngine/.hg/store/data/export_jar_to_space_taxi.xml.i differ diff --git a/AndEngine/.hg/store/data/ext/img/android.svg.i b/AndEngine/.hg/store/data/ext/img/android.svg.i new file mode 100644 index 0000000..786678d Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/android.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/badge.png.i b/AndEngine/.hg/store/data/ext/img/badge.png.i new file mode 100644 index 0000000..1123830 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/badge.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/badge.svg.i b/AndEngine/.hg/store/data/ext/img/badge.svg.i new file mode 100644 index 0000000..2c16a40 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/badge.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/clapboard.png.i b/AndEngine/.hg/store/data/ext/img/clapboard.png.i new file mode 100644 index 0000000..096ca62 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/clapboard.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/clapboard.svg.i b/AndEngine/.hg/store/data/ext/img/clapboard.svg.i new file mode 100644 index 0000000..41f05b5 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/clapboard.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/favicon.png.i b/AndEngine/.hg/store/data/ext/img/favicon.png.i new file mode 100644 index 0000000..4527dc8 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/favicon.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/favicon.svg.i b/AndEngine/.hg/store/data/ext/img/favicon.svg.i new file mode 100644 index 0000000..a3cbc7c Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/favicon.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/icon.svg.i b/AndEngine/.hg/store/data/ext/img/icon.svg.i new file mode 100644 index 0000000..61600d1 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/icon.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/index.html.i b/AndEngine/.hg/store/data/ext/img/index.html.i new file mode 100644 index 0000000..d487b92 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/index.html.i differ diff --git a/AndEngine/.hg/store/data/ext/img/logo.png.i b/AndEngine/.hg/store/data/ext/img/logo.png.i new file mode 100644 index 0000000..b08e4fc Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/logo.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/logo.svg.i b/AndEngine/.hg/store/data/ext/img/logo.svg.i new file mode 100644 index 0000000..de2a9cf Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/logo.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/logo2.png.i b/AndEngine/.hg/store/data/ext/img/logo2.png.i new file mode 100644 index 0000000..6bd42dc Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/logo2.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/logo3.png.i b/AndEngine/.hg/store/data/ext/img/logo3.png.i new file mode 100644 index 0000000..2139d41 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/logo3.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/logo4.png.i b/AndEngine/.hg/store/data/ext/img/logo4.png.i new file mode 100644 index 0000000..aa92247 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/logo4.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/logo__icon.svg.i b/AndEngine/.hg/store/data/ext/img/logo__icon.svg.i new file mode 100644 index 0000000..ba30bd9 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/logo__icon.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/source.png.i b/AndEngine/.hg/store/data/ext/img/source.png.i new file mode 100644 index 0000000..d46c426 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/source.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/source.svg.i b/AndEngine/.hg/store/data/ext/img/source.svg.i new file mode 100644 index 0000000..fcaf0fb Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/source.svg.i differ diff --git a/AndEngine/.hg/store/data/ext/img/splash.png.i b/AndEngine/.hg/store/data/ext/img/splash.png.i new file mode 100644 index 0000000..8463ed5 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/splash.png.i differ diff --git a/AndEngine/.hg/store/data/ext/img/splash.svg.i b/AndEngine/.hg/store/data/ext/img/splash.svg.i new file mode 100644 index 0000000..fbf2158 Binary files /dev/null and b/AndEngine/.hg/store/data/ext/img/splash.svg.i differ diff --git a/AndEngine/.hg/store/data/hudson__build.xml.i b/AndEngine/.hg/store/data/hudson__build.xml.i new file mode 100644 index 0000000..21299c0 Binary files /dev/null and b/AndEngine/.hg/store/data/hudson__build.xml.i differ diff --git a/AndEngine/.hg/store/data/lib/lib_progress_monitor.jar.i b/AndEngine/.hg/store/data/lib/lib_progress_monitor.jar.i new file mode 100644 index 0000000..7eaf3b1 Binary files /dev/null and b/AndEngine/.hg/store/data/lib/lib_progress_monitor.jar.i differ diff --git a/AndEngine/.hg/store/data/push__buxs.bat.i b/AndEngine/.hg/store/data/push__buxs.bat.i new file mode 100644 index 0000000..05a881d Binary files /dev/null and b/AndEngine/.hg/store/data/push__buxs.bat.i differ diff --git a/AndEngine/.hg/store/data/push__google__code.bat.i b/AndEngine/.hg/store/data/push__google__code.bat.i new file mode 100644 index 0000000..cf9833b Binary files /dev/null and b/AndEngine/.hg/store/data/push__google__code.bat.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_base_audio_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_base_audio_entity.java.i new file mode 100644 index 0000000..0d68b79 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_base_audio_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_base_audio_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_base_audio_manager.java.i new file mode 100644 index 0000000..7f10a99 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_base_audio_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_i_audio_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_i_audio_entity.java.i new file mode 100644 index 0000000..83edab7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_i_audio_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_i_audio_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_i_audio_manager.java.i new file mode 100644 index 0000000..f14c4be Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/_i_audio_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music.java.i new file mode 100644 index 0000000..5c19008 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music_factory.java.i new file mode 100644 index 0000000..a654486 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music_manager.java.i new file mode 100644 index 0000000..6be5bde Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/music/_music_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound.java.i new file mode 100644 index 0000000..b944494 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_factory.java.i new file mode 100644 index 0000000..0ecac65 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_library.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_library.java.i new file mode 100644 index 0000000..2f487ca Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_library.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_manager.java.i new file mode 100644 index 0000000..c885423 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/audio/sound/_sound_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_base_collision_checker.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_base_collision_checker.java.i new file mode 100644 index 0000000..da414a5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_base_collision_checker.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_collision_checker.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_collision_checker.java.i new file mode 100644 index 0000000..77110e0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_collision_checker.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_line_collision_checker.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_line_collision_checker.java.i new file mode 100644 index 0000000..99f6f96 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_line_collision_checker.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_rectangular_shape_collision_checker.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_rectangular_shape_collision_checker.java.i new file mode 100644 index 0000000..8d01ae1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_rectangular_shape_collision_checker.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_shape_collision_checker.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_shape_collision_checker.java.i new file mode 100644 index 0000000..5603dc9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/collision/_shape_collision_checker.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_double_scene_split_screen_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_double_scene_split_screen_engine.java.i new file mode 100644 index 0000000..ef8c962 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_double_scene_split_screen_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine.java.i new file mode 100644 index 0000000..62ad7c9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine_hook.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine_hook.java.i new file mode 100644 index 0000000..0e49f99 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine_hook.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine_options.java.i new file mode 100644 index 0000000..e65a13f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_engine_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_fixed_f_p_s_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_fixed_f_p_s_engine.java.i new file mode 100644 index 0000000..d9f09aa Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_fixed_f_p_s_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_fixed_step_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_fixed_step_engine.java.i new file mode 100644 index 0000000..3b98038 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_fixed_step_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_i_scene_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_i_scene_touch_listener.java.i new file mode 100644 index 0000000..926008f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_i_scene_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_i_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_i_update_handler.java.i new file mode 100644 index 0000000..65cf7ec Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_i_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_limited_f_p_s_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_limited_f_p_s_engine.java.i new file mode 100644 index 0000000..778c455 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_limited_f_p_s_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_single_scene_split_screen_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_single_scene_split_screen_engine.java.i new file mode 100644 index 0000000..705b45a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_single_scene_split_screen_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_smooth_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_smooth_engine.java.i new file mode 100644 index 0000000..c2501b7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_smooth_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_split_screen_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_split_screen_engine.java.i new file mode 100644 index 0000000..34dc2db Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_split_screen_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_split_screen_engine_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_split_screen_engine_options.java.i new file mode 100644 index 0000000..8a94320 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_split_screen_engine_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_update_handler_list.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_update_handler_list.java.i new file mode 100644 index 0000000..20e4c61 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/_update_handler_list.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_bound_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_bound_camera.java.i new file mode 100644 index 0000000..7d7dae1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_bound_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_camera.java.i new file mode 100644 index 0000000..2129a29 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_camera_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_camera_factory.java.i new file mode 100644 index 0000000..f52b1a1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_camera_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_chase_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_chase_camera.java.i new file mode 100644 index 0000000..a28a7e3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_chase_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_smooth_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_smooth_camera.java.i new file mode 100644 index 0000000..efaf997 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_smooth_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_smooth_chase_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_smooth_chase_camera.java.i new file mode 100644 index 0000000..db6ed9e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_smooth_chase_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_zoom_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_zoom_camera.java.i new file mode 100644 index 0000000..6f107d8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/_zoom_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/_h_u_d.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/_h_u_d.java.i new file mode 100644 index 0000000..186121f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/_h_u_d.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_analog_on_screen_control.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_analog_on_screen_control.java.i new file mode 100644 index 0000000..c93428f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_analog_on_screen_control.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_base_on_screen_control.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_base_on_screen_control.java.i new file mode 100644 index 0000000..6a0c124 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_base_on_screen_control.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_digital_on_screen_control.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_digital_on_screen_control.java.i new file mode 100644 index 0000000..c064541 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/camera/hud/controls/_digital_on_screen_control.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/easying/_easing.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/easying/_easing.java.i new file mode 100644 index 0000000..4e7206a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/easying/_easing.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_base_entity_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_base_entity_update_handler.java.i new file mode 100644 index 0000000..04d9b27 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_base_entity_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_i_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_i_update_handler.java.i new file mode 100644 index 0000000..dd96a68 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_i_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_update_handler_list.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_update_handler_list.java.i new file mode 100644 index 0000000..802188e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/_update_handler_list.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/collision/_collision_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/collision/_collision_handler.java.i new file mode 100644 index 0000000..364aa69 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/collision/_collision_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/collision/_i_collision_callback.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/collision/_i_collision_callback.java.i new file mode 100644 index 0000000..f6f08ba Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/collision/_i_collision_callback.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/physics/_physics_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/physics/_physics_handler.java.i new file mode 100644 index 0000000..a8e39be Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/physics/_physics_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/runnable/_runnable_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/runnable/_runnable_handler.java.i new file mode 100644 index 0000000..553413e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/runnable/_runnable_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/timer/_i_timer_callback.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/timer/_i_timer_callback.java.i new file mode 100644 index 0000000..a551fef Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/timer/_i_timer_callback.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/timer/_timer_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/timer/_timer_handler.java.i new file mode 100644 index 0000000..e96cdcb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/handler/timer/_timer_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_engine_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_engine_options.java.i new file mode 100644 index 0000000..a8a93dc Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_engine_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_fixed_f_p_s_engine_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_fixed_f_p_s_engine_options.java.i new file mode 100644 index 0000000..de12e55 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_fixed_f_p_s_engine_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_fixed_step_engine_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_fixed_step_engine_options.java.i new file mode 100644 index 0000000..2ccfa1b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_fixed_step_engine_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_render_hints.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_render_hints.java.i new file mode 100644 index 0000000..1715534 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_render_hints.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_render_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_render_options.java.i new file mode 100644 index 0000000..4839ab3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_render_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_split_screen_engine_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_split_screen_engine_options.java.i new file mode 100644 index 0000000..2cd8d3f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_split_screen_engine_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_touch_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_touch_options.java.i new file mode 100644 index 0000000..e9cb8f7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_touch_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_wake_lock_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_wake_lock_options.java.i new file mode 100644 index 0000000..2fdad6f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/_wake_lock_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_base_resolution_policy.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_base_resolution_policy.java.i new file mode 100644 index 0000000..5ce768c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_base_resolution_policy.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_fill_resolution_policy.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_fill_resolution_policy.java.i new file mode 100644 index 0000000..21fbc05 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_fill_resolution_policy.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_fixed_resolution_policy.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_fixed_resolution_policy.java.i new file mode 100644 index 0000000..723d252 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_fixed_resolution_policy.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_i_resolution_policy.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_i_resolution_policy.java.i new file mode 100644 index 0000000..900fe51 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_i_resolution_policy.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_ratio_resolution_policy.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_ratio_resolution_policy.java.i new file mode 100644 index 0000000..14e33af Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_ratio_resolution_policy.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_relative_resolution_policy.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_relative_resolution_policy.java.i new file mode 100644 index 0000000..ca23674 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/engine/options/resolutionpolicy/_relative_resolution_policy.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_dynamic_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_dynamic_entity.java.i new file mode 100644 index 0000000..a6a8478 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_dynamic_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_entity.java.i new file mode 100644 index 0000000..c5d5f3c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_static_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_static_entity.java.i new file mode 100644 index 0000000..b870ffc Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_base_static_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_camera_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_camera_scene.java.i new file mode 100644 index 0000000..5ec6537 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_camera_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_dynamic_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_dynamic_entity.java.i new file mode 100644 index 0000000..54acd4a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_dynamic_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_entity.java.i new file mode 100644 index 0000000..5c2a334 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_f_p_s_counter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_f_p_s_counter.java.i new file mode 100644 index 0000000..b994688 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_f_p_s_counter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_frame_counter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_frame_counter.java.i new file mode 100644 index 0000000..b8f9524 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_frame_counter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_frame_length_logger.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_frame_length_logger.java.i new file mode 100644 index 0000000..441f5f9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_frame_length_logger.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_horizontal_align.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_horizontal_align.java.i new file mode 100644 index 0000000..98b3f21 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_horizontal_align.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_base_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_base_entity.java.i new file mode 100644 index 0000000..c048688 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_base_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_dynamic_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_dynamic_entity.java.i new file mode 100644 index 0000000..297e71a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_dynamic_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_entity.java.i new file mode 100644 index 0000000..93d3944 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_on_scene_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_on_scene_touch_listener.java.i new file mode 100644 index 0000000..440a9fb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_on_scene_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_scene_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_scene_touch_listener.java.i new file mode 100644 index 0000000..043aec3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_scene_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_static_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_static_entity.java.i new file mode 100644 index 0000000..68bef52 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_static_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_update_handler.java.i new file mode 100644 index 0000000..ac68af6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_i_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_layer.java.i new file mode 100644 index 0000000..60c218a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_scene.java.i new file mode 100644 index 0000000..f7d84c2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_scene_with_child.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_scene_with_child.java.i new file mode 100644 index 0000000..81c6e77 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_scene_with_child.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_screen_capture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_screen_capture.java.i new file mode 100644 index 0000000..29262a7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_screen_capture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_splash_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_splash_scene.java.i new file mode 100644 index 0000000..2bfd8bf Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_splash_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_static_entity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_static_entity.java.i new file mode 100644 index 0000000..13dddd1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_static_entity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_update_handler_list.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_update_handler_list.java.i new file mode 100644 index 0000000..7b93109 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/_update_handler_list.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/background/_base_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/background/_base_background.java.i new file mode 100644 index 0000000..a326ea1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/background/_base_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/background/_fixed_color_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/background/_fixed_color_background.java.i new file mode 100644 index 0000000..0b9ef38 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/background/_fixed_color_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/group/_transformation_group.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/group/_transformation_group.java.i new file mode 100644 index 0000000..1f31089 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/group/_transformation_group.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/collision/_collision_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/collision/_collision_handler.java.i new file mode 100644 index 0000000..cba9eca Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/collision/_collision_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/collision/_i_collision_callback.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/collision/_i_collision_callback.java.i new file mode 100644 index 0000000..d9f6f8b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/collision/_i_collision_callback.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/runnable/_runnable_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/runnable/_runnable_handler.java.i new file mode 100644 index 0000000..11d6f0c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/runnable/_runnable_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/timer/_i_timer_callback.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/timer/_i_timer_callback.java.i new file mode 100644 index 0000000..89fadd8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/timer/_i_timer_callback.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/timer/_timer_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/timer/_timer_handler.java.i new file mode 100644 index 0000000..0bfc1b3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/handler/timer/_timer_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_base_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_base_layer.java.i new file mode 100644 index 0000000..4023f0d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_base_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_dynamic_capacity_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_dynamic_capacity_layer.java.i new file mode 100644 index 0000000..1b17ecd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_dynamic_capacity_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_fixed_capacity_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_fixed_capacity_layer.java.i new file mode 100644 index 0000000..15796ec Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_fixed_capacity_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_i_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_i_layer.java.i new file mode 100644 index 0000000..271cc5b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_i_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_layer.java.i new file mode 100644 index 0000000..361ad4e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_layer_sorter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_layer_sorter.java.i new file mode 100644 index 0000000..893a5fc Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_layer_sorter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_z_index_sorter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_z_index_sorter.java.i new file mode 100644 index 0000000..7dbcda8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/_z_index_sorter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_i_t_m_x_tile_properties_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_i_t_m_x_tile_properties_listener.java.i new file mode 100644 index 0000000..27cd3e9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_i_t_m_x_tile_properties_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_layer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_layer.java.i new file mode 100644 index 0000000..3a10f9f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_layer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_layer_property.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_layer_property.java.i new file mode 100644 index 0000000..0e9c0b7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_layer_property.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_loader.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_loader.java.i new file mode 100644 index 0000000..349a1f6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_loader.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object.java.i new file mode 100644 index 0000000..1a3d1a4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_group.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_group.java.i new file mode 100644 index 0000000..b9b7e82 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_group.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_group_property.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_group_property.java.i new file mode 100644 index 0000000..22d83a6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_group_property.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_property.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_property.java.i new file mode 100644 index 0000000..f1d75e4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_object_property.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_parser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_parser.java.i new file mode 100644 index 0000000..ca51f8a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_parser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_properties.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_properties.java.i new file mode 100644 index 0000000..c42131f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_properties.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_property.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_property.java.i new file mode 100644 index 0000000..185d32b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_property.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile.java.i new file mode 100644 index 0000000..379d665 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile_property.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile_property.java.i new file mode 100644 index 0000000..c91df18 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile_property.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile_set.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile_set.java.i new file mode 100644 index 0000000..346142b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tile_set.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tiled_map.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tiled_map.java.i new file mode 100644 index 0000000..9340d81 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tiled_map.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tiled_map_property.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tiled_map_property.java.i new file mode 100644 index 0000000..9ad80d7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_m_x_tiled_map_property.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_s_x_loader.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_s_x_loader.java.i new file mode 100644 index 0000000..43d89fa Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_s_x_loader.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_s_x_parser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_s_x_parser.java.i new file mode 100644 index 0000000..0bc9b9d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/_t_s_x_parser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/_t_m_x_constants.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/_t_m_x_constants.java.i new file mode 100644 index 0000000..11f4b4e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/_t_m_x_constants.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_exception.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_exception.java.i new file mode 100644 index 0000000..1487861 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_exception.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_load_exception.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_load_exception.java.i new file mode 100644 index 0000000..cd0e0ef Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_load_exception.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_parse_exception.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_parse_exception.java.i new file mode 100644 index 0000000..ce18898 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_m_x_parse_exception.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_s_x_load_exception.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_s_x_load_exception.java.i new file mode 100644 index 0000000..59db88d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_s_x_load_exception.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_s_x_parse_exception.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_s_x_parse_exception.java.i new file mode 100644 index 0000000..ee571c8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/_t_s_x_parse_exception.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_menu_animator.java.i new file mode 100644 index 0000000..de750de Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_on_menu_item_click_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_on_menu_item_click_listener.java.i new file mode 100644 index 0000000..35d4e29 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_on_menu_item_click_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_on_menu_item_clicker_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_on_menu_item_clicker_listener.java.i new file mode 100644 index 0000000..ea1a37b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_i_on_menu_item_clicker_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_menu_item.java.i new file mode 100644 index 0000000..7db5006 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_menu_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_menu_scene.java.i new file mode 100644 index 0000000..6a203d5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/_menu_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_alpha_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_alpha_menu_animator.java.i new file mode 100644 index 0000000..d4cddc4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_alpha_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_base_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_base_menu_animator.java.i new file mode 100644 index 0000000..2444538 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_base_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_direct_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_direct_menu_animator.java.i new file mode 100644 index 0000000..43bc9b1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_direct_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_slide_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_slide_menu_animator.java.i new file mode 100644 index 0000000..3ba2207 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/menu/animator/_slide_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_alpha_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_alpha_modifier.java.i new file mode 100644 index 0000000..1098304 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_alpha_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_color_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_color_modifier.java.i new file mode 100644 index 0000000..60dcc79 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_color_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_delay_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_delay_modifier.java.i new file mode 100644 index 0000000..36e668c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_delay_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_double_value_span_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_double_value_span_shape_modifier.java.i new file mode 100644 index 0000000..9b1c55a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_double_value_span_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_duration_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_duration_shape_modifier.java.i new file mode 100644 index 0000000..9f17f6b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_duration_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_entity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_entity_modifier.java.i new file mode 100644 index 0000000..2b7378c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_entity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_entity_modifier_list.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_entity_modifier_list.java.i new file mode 100644 index 0000000..d7ebf15 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_entity_modifier_list.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_fade_in_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_fade_in_modifier.java.i new file mode 100644 index 0000000..64597cd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_fade_in_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_fade_out_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_fade_out_modifier.java.i new file mode 100644 index 0000000..d575e88 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_fade_out_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_i_entity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_i_entity_modifier.java.i new file mode 100644 index 0000000..a1e1e8b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_i_entity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_loop_entity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_loop_entity_modifier.java.i new file mode 100644 index 0000000..305f325 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_loop_entity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_modifier.java.i new file mode 100644 index 0000000..74553e3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_x_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_x_modifier.java.i new file mode 100644 index 0000000..e0ec346 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_x_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_y_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_y_modifier.java.i new file mode 100644 index 0000000..e4114ad Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_move_y_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_parallel_entity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_parallel_entity_modifier.java.i new file mode 100644 index 0000000..6c58275 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_parallel_entity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_path_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_path_modifier.java.i new file mode 100644 index 0000000..72f88ef Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_path_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_at_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_at_modifier.java.i new file mode 100644 index 0000000..2c7ea13 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_at_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_by_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_by_modifier.java.i new file mode 100644 index 0000000..6d779a1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_by_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_modifier.java.i new file mode 100644 index 0000000..5cda5ee Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_rotation_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_scale_at_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_scale_at_modifier.java.i new file mode 100644 index 0000000..6e97f11 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_scale_at_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_scale_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_scale_modifier.java.i new file mode 100644 index 0000000..a7927f1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_scale_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_sequence_entity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_sequence_entity_modifier.java.i new file mode 100644 index 0000000..2308e60 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_sequence_entity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_single_value_change_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_single_value_change_shape_modifier.java.i new file mode 100644 index 0000000..ef0cf97 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_single_value_change_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_single_value_span_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_single_value_span_shape_modifier.java.i new file mode 100644 index 0000000..f8fcfcd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_single_value_span_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_triple_value_span_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_triple_value_span_shape_modifier.java.i new file mode 100644 index 0000000..6a25ff3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/modifier/_triple_value_span_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_i_particle_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_i_particle_initializer.java.i new file mode 100644 index 0000000..ab6fbe1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_i_particle_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_i_particle_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_i_particle_modifier.java.i new file mode 100644 index 0000000..c323749 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_i_particle_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle.java.i new file mode 100644 index 0000000..3e07b0e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle_engine.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle_engine.java.i new file mode 100644 index 0000000..86f352c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle_engine.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle_system.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle_system.java.i new file mode 100644 index 0000000..11c2e67 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/_particle_system.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_circle_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_circle_particle_emitter.java.i new file mode 100644 index 0000000..2222afd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_circle_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_particle_emitter.java.i new file mode 100644 index 0000000..82ae269 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_rectangle_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_rectangle_particle_emitter.java.i new file mode 100644 index 0000000..4c49fd0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_base_rectangle_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_circle_outline_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_circle_outline_particle_emitter.java.i new file mode 100644 index 0000000..eb5655c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_circle_outline_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_circle_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_circle_particle_emitter.java.i new file mode 100644 index 0000000..46e731c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_circle_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_i_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_i_particle_emitter.java.i new file mode 100644 index 0000000..d33354f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_i_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_point_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_point_particle_emitter.java.i new file mode 100644 index 0000000..189d6b7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_point_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_rectangle_outline_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_rectangle_outline_particle_emitter.java.i new file mode 100644 index 0000000..ff40a5e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_rectangle_outline_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_rectangle_particle_emitter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_rectangle_particle_emitter.java.i new file mode 100644 index 0000000..0a8bb0f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/emitter/_rectangle_particle_emitter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_acceleration_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_acceleration_initializer.java.i new file mode 100644 index 0000000..7561348 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_acceleration_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_alpha_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_alpha_initializer.java.i new file mode 100644 index 0000000..2cf9c04 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_alpha_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_double_value_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_double_value_initializer.java.i new file mode 100644 index 0000000..1a82ac5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_double_value_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_single_value_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_single_value_initializer.java.i new file mode 100644 index 0000000..9b57689 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_single_value_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_triple_value_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_triple_value_initializer.java.i new file mode 100644 index 0000000..376fe2c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_base_triple_value_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_color_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_color_initializer.java.i new file mode 100644 index 0000000..09cc3d9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_color_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_gravity_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_gravity_initializer.java.i new file mode 100644 index 0000000..c17f64a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_gravity_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_i_particle_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_i_particle_initializer.java.i new file mode 100644 index 0000000..f5e1eae Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_i_particle_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_rotation_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_rotation_initializer.java.i new file mode 100644 index 0000000..63b8d5b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_rotation_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_velocity_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_velocity_initializer.java.i new file mode 100644 index 0000000..d799136 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/initializer/_velocity_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_acceleration_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_acceleration_initializer.java.i new file mode 100644 index 0000000..381b27a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_acceleration_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_acceleration_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_acceleration_modifier.java.i new file mode 100644 index 0000000..dad6f42 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_acceleration_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_alpha_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_alpha_initializer.java.i new file mode 100644 index 0000000..14007f8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_alpha_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_alpha_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_alpha_modifier.java.i new file mode 100644 index 0000000..b346aec Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_alpha_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_double_value_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_double_value_initializer.java.i new file mode 100644 index 0000000..8814434 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_double_value_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_double_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_double_value_span_modifier.java.i new file mode 100644 index 0000000..34879d7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_double_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_from_to_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_from_to_modifier.java.i new file mode 100644 index 0000000..e94b429 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_from_to_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_initializer.java.i new file mode 100644 index 0000000..db7ad41 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_pair_initialize_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_pair_initialize_modifier.java.i new file mode 100644 index 0000000..0698b77 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_pair_initialize_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_pair_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_pair_initializer.java.i new file mode 100644 index 0000000..b047292 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_pair_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_single_value_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_single_value_initializer.java.i new file mode 100644 index 0000000..8992877 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_single_value_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_single_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_single_value_span_modifier.java.i new file mode 100644 index 0000000..b47439a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_single_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_triple_value_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_triple_value_initializer.java.i new file mode 100644 index 0000000..ab1f74e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_triple_value_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_triple_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_triple_value_span_modifier.java.i new file mode 100644 index 0000000..0fbe762 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_base_triple_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_color_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_color_initializer.java.i new file mode 100644 index 0000000..6e71783 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_color_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_color_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_color_modifier.java.i new file mode 100644 index 0000000..af09256 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_color_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_expire_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_expire_modifier.java.i new file mode 100644 index 0000000..f1c9aeb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_expire_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_gravity_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_gravity_initializer.java.i new file mode 100644 index 0000000..35a749c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_gravity_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_gravity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_gravity_modifier.java.i new file mode 100644 index 0000000..7fdb241 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_gravity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_i_particle_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_i_particle_initializer.java.i new file mode 100644 index 0000000..d77845c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_i_particle_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_i_particle_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_i_particle_modifier.java.i new file mode 100644 index 0000000..f5334c9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_i_particle_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_off_camera_expire_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_off_camera_expire_modifier.java.i new file mode 100644 index 0000000..48bbb07 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_off_camera_expire_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_initialize.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_initialize.java.i new file mode 100644 index 0000000..174b2a5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_initialize.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_initializer.java.i new file mode 100644 index 0000000..d1ff810 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_modifier.java.i new file mode 100644 index 0000000..ca84866 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotate_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotation_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotation_initializer.java.i new file mode 100644 index 0000000..f338446 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotation_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotation_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotation_modifier.java.i new file mode 100644 index 0000000..0ecfcd4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_rotation_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_scale_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_scale_modifier.java.i new file mode 100644 index 0000000..fa3eb64 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_scale_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_velocity_initializer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_velocity_initializer.java.i new file mode 100644 index 0000000..b2b5aa6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_velocity_initializer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_velocity_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_velocity_modifier.java.i new file mode 100644 index 0000000..f4d193e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/particle/modifier/_velocity_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_base_rectangle.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_base_rectangle.java.i new file mode 100644 index 0000000..b06bee4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_base_rectangle.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_line.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_line.java.i new file mode 100644 index 0000000..4d17702 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_line.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_rectangle.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_rectangle.java.i new file mode 100644 index 0000000..1001a35 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_rectangle.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_rectangular_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_rectangular_shape.java.i new file mode 100644 index 0000000..6ca2d62 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitive/_rectangular_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_base_rectangle.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_base_rectangle.java.i new file mode 100644 index 0000000..509ac4a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_base_rectangle.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_line.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_line.java.i new file mode 100644 index 0000000..895db04 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_line.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_rectangle.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_rectangle.java.i new file mode 100644 index 0000000..4428bac Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_rectangle.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_rectangular_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_rectangular_shape.java.i new file mode 100644 index 0000000..792e766 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_rectangular_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_shape.java.i new file mode 100644 index 0000000..1092957 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/primitives/_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_camera_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_camera_scene.java.i new file mode 100644 index 0000000..8e68fe1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_camera_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_scene.java.i new file mode 100644 index 0000000..9798f96 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_splash_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_splash_scene.java.i new file mode 100644 index 0000000..bb23bac Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/_splash_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_auto_parallax_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_auto_parallax_background.java.i new file mode 100644 index 0000000..9732837 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_auto_parallax_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_base_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_base_background.java.i new file mode 100644 index 0000000..fa5ae81 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_base_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_color_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_color_background.java.i new file mode 100644 index 0000000..12c2d60 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_color_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_entity_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_entity_background.java.i new file mode 100644 index 0000000..8dec976 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_entity_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_i_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_i_background.java.i new file mode 100644 index 0000000..defb29a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_i_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_parallax_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_parallax_background.java.i new file mode 100644 index 0000000..acddbfb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_parallax_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_repeating_sprite_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_repeating_sprite_background.java.i new file mode 100644 index 0000000..126ddb7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_repeating_sprite_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_sprite_background.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_sprite_background.java.i new file mode 100644 index 0000000..da7e1ee Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/_sprite_background.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_color_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_color_modifier.java.i new file mode 100644 index 0000000..d200c5e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_color_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_i_background_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_i_background_modifier.java.i new file mode 100644 index 0000000..1310dd1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_i_background_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_loop_background_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_loop_background_modifier.java.i new file mode 100644 index 0000000..a23a183 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_loop_background_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_parallel_background_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_parallel_background_modifier.java.i new file mode 100644 index 0000000..2edb677 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_parallel_background_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_sequence_background_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_sequence_background_modifier.java.i new file mode 100644 index 0000000..b1ceeb9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/background/modifier/_sequence_background_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/_menu_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/_menu_scene.java.i new file mode 100644 index 0000000..35b0471 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/_menu_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_alpha_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_alpha_menu_animator.java.i new file mode 100644 index 0000000..8455778 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_alpha_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_base_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_base_menu_animator.java.i new file mode 100644 index 0000000..fdf4546 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_base_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_direct_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_direct_menu_animator.java.i new file mode 100644 index 0000000..13a598c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_direct_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_i_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_i_menu_animator.java.i new file mode 100644 index 0000000..455bc35 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_i_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_slide_menu_animator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_slide_menu_animator.java.i new file mode 100644 index 0000000..5e5553e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/animator/_slide_menu_animator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_animated_sprite_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_animated_sprite_menu_item.java.i new file mode 100644 index 0000000..0e0f1a7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_animated_sprite_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_color_text_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_color_text_menu_item.java.i new file mode 100644 index 0000000..3494a41 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_color_text_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_colored_text_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_colored_text_menu_item.java.i new file mode 100644 index 0000000..7a6c889 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_colored_text_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_i_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_i_menu_item.java.i new file mode 100644 index 0000000..194b500 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_i_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_scale_text_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_scale_text_menu_item.java.i new file mode 100644 index 0000000..67746ec Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_scale_text_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_sprite_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_sprite_menu_item.java.i new file mode 100644 index 0000000..378d04c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_sprite_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_text_menu_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_text_menu_item.java.i new file mode 100644 index 0000000..b7133a2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/_text_menu_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_base_menu_item_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_base_menu_item_decorator.java.i new file mode 100644 index 0000000..e18d206 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_base_menu_item_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_color_menu_item_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_color_menu_item_decorator.java.i new file mode 100644 index 0000000..a3ab301 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_color_menu_item_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_scale_menu_item_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_scale_menu_item_decorator.java.i new file mode 100644 index 0000000..a9272da Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/menu/item/decorator/_scale_menu_item_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/popup/_popup_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/popup/_popup_scene.java.i new file mode 100644 index 0000000..29bbed5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/popup/_popup_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/popup/_text_popup_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/popup/_text_popup_scene.java.i new file mode 100644 index 0000000..d571f67 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/popup/_text_popup_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/transition/_base_transition_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/transition/_base_transition_scene.java.i new file mode 100644 index 0000000..af7f3a9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/transition/_base_transition_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/transition/_fade_transition_scene.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/transition/_fade_transition_scene.java.i new file mode 100644 index 0000000..2854e6d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/scene/transition/_fade_transition_scene.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_base_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_base_renderer.java.i new file mode 100644 index 0000000..379ff14 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_base_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_g_l_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_g_l_shape.java.i new file mode 100644 index 0000000..bcffbf2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_g_l_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_modifier_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_modifier_listener.java.i new file mode 100644 index 0000000..f71a0e7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_modifier_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_renderer.java.i new file mode 100644 index 0000000..169d1e7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_shape.java.i new file mode 100644 index 0000000..470a16e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_shape_modifier.java.i new file mode 100644 index 0000000..3c8bc2a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_i_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_rectangle_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_rectangle_renderer.java.i new file mode 100644 index 0000000..69d2b6f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_rectangle_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_rectangular_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_rectangular_shape.java.i new file mode 100644 index 0000000..a52224f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_rectangular_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_shape.java.i new file mode 100644 index 0000000..38f1a41 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_alpha_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_alpha_modifier.java.i new file mode 100644 index 0000000..f9c315f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_alpha_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_change_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_change_modifier.java.i new file mode 100644 index 0000000..b4586cd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_change_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_double_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_double_value_span_modifier.java.i new file mode 100644 index 0000000..c9f2a96 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_double_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_from_to_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_from_to_modifier.java.i new file mode 100644 index 0000000..6cbc1dd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_from_to_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_modifier.java.i new file mode 100644 index 0000000..13b3118 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_pair_from_to_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_pair_from_to_modifier.java.i new file mode 100644 index 0000000..bcba9e1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_pair_from_to_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_shape_duration_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_shape_duration_modifier.java.i new file mode 100644 index 0000000..85de475 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_shape_duration_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_shape_modifier.java.i new file mode 100644 index 0000000..b4670d3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_single_value_change_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_single_value_change_modifier.java.i new file mode 100644 index 0000000..ab3a682 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_single_value_change_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_single_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_single_value_span_modifier.java.i new file mode 100644 index 0000000..d58ab92 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_single_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_triple_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_triple_value_span_modifier.java.i new file mode 100644 index 0000000..e7cd5aa Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_base_triple_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_color_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_color_modifier.java.i new file mode 100644 index 0000000..6663bda Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_color_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_delay_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_delay_modifier.java.i new file mode 100644 index 0000000..0b767db Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_delay_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_double_value_span_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_double_value_span_shape_modifier.java.i new file mode 100644 index 0000000..b0fc174 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_double_value_span_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_duration_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_duration_shape_modifier.java.i new file mode 100644 index 0000000..1d98e24 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_duration_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_fade_in_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_fade_in_modifier.java.i new file mode 100644 index 0000000..96e79f9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_fade_in_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_fade_out_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_fade_out_modifier.java.i new file mode 100644 index 0000000..0aa8f28 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_fade_out_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_i_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_i_shape_modifier.java.i new file mode 100644 index 0000000..d72b4af Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_i_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_i_shape_modifier_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_i_shape_modifier_listener.java.i new file mode 100644 index 0000000..0164e27 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_i_shape_modifier_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_loop_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_loop_modifier.java.i new file mode 100644 index 0000000..508284a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_loop_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_loop_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_loop_shape_modifier.java.i new file mode 100644 index 0000000..d1f683c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_loop_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_modifier.java.i new file mode 100644 index 0000000..9f06321 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_x_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_x_modifier.java.i new file mode 100644 index 0000000..e8158f1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_x_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_y_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_y_modifier.java.i new file mode 100644 index 0000000..4eea32a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_move_y_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_parallel_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_parallel_modifier.java.i new file mode 100644 index 0000000..b4a755f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_parallel_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_parallel_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_parallel_shape_modifier.java.i new file mode 100644 index 0000000..0e38bd7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_parallel_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_path_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_path_modifier.java.i new file mode 100644 index 0000000..d7c2abd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_path_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotate_by_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotate_by_modifier.java.i new file mode 100644 index 0000000..88e3578 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotate_by_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotate_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotate_modifier.java.i new file mode 100644 index 0000000..3095802 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotate_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_at_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_at_modifier.java.i new file mode 100644 index 0000000..16a735b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_at_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_by_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_by_modifier.java.i new file mode 100644 index 0000000..53a436e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_by_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_modifier.java.i new file mode 100644 index 0000000..6fa6cdd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_rotation_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_scale_at_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_scale_at_modifier.java.i new file mode 100644 index 0000000..f5ea7e1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_scale_at_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_scale_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_scale_modifier.java.i new file mode 100644 index 0000000..b2d3dcd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_scale_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_sequence_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_sequence_modifier.java.i new file mode 100644 index 0000000..c1dc3b4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_sequence_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_sequence_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_sequence_shape_modifier.java.i new file mode 100644 index 0000000..e7c9879 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_sequence_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_shape_modifier.java.i new file mode 100644 index 0000000..d3692f5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_single_value_change_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_single_value_change_shape_modifier.java.i new file mode 100644 index 0000000..34c4f04 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_single_value_change_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_single_value_span_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_single_value_span_shape_modifier.java.i new file mode 100644 index 0000000..fc52e06 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_single_value_span_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_triple_value_span_shape_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_triple_value_span_shape_modifier.java.i new file mode 100644 index 0000000..fd591d9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/_triple_value_span_shape_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_in.java.i new file mode 100644 index 0000000..8fb1177 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_in_out.java.i new file mode 100644 index 0000000..ff0f9be Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_out.java.i new file mode 100644 index 0000000..e29dd60 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_back_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_in.java.i new file mode 100644 index 0000000..4f7b336 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_in_out.java.i new file mode 100644 index 0000000..ade5bcd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_out.java.i new file mode 100644 index 0000000..00311a4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_bounce_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_in.java.i new file mode 100644 index 0000000..8efde4b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_in_out.java.i new file mode 100644 index 0000000..d18aba9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_out.java.i new file mode 100644 index 0000000..f3586b8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_circular_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_in.java.i new file mode 100644 index 0000000..33626f2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_in_out.java.i new file mode 100644 index 0000000..997ad43 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_out.java.i new file mode 100644 index 0000000..c584027 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_cubic_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_in.java.i new file mode 100644 index 0000000..a7a3dec Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_in_out.java.i new file mode 100644 index 0000000..9dc361e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_out.java.i new file mode 100644 index 0000000..38f9a3b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_elastic_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_in.java.i new file mode 100644 index 0000000..64d87f7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_in_out.java.i new file mode 100644 index 0000000..7ded010 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_out.java.i new file mode 100644 index 0000000..b1b6aa5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_exponential_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_linear.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_linear.java.i new file mode 100644 index 0000000..a7d7be6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_linear.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_in.java.i new file mode 100644 index 0000000..13dd537 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_in_out.java.i new file mode 100644 index 0000000..d53cd1d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_out.java.i new file mode 100644 index 0000000..35013d7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quad_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_in.java.i new file mode 100644 index 0000000..fde9e17 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_in_out.java.i new file mode 100644 index 0000000..808281d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_out.java.i new file mode 100644 index 0000000..dcb7bdd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quart_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_in.java.i new file mode 100644 index 0000000..84ab9e8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_in_out.java.i new file mode 100644 index 0000000..8ef55ef Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_out.java.i new file mode 100644 index 0000000..37a9b22 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_quint_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_in.java.i new file mode 100644 index 0000000..ba3e375 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_in_out.java.i new file mode 100644 index 0000000..6ad3ed8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_out.java.i new file mode 100644 index 0000000..6e1a92f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_sine_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_in.java.i new file mode 100644 index 0000000..40bdab0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_in_out.java.i new file mode 100644 index 0000000..0c33efb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_out.java.i new file mode 100644 index 0000000..0b68c70 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_ease_strong_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_i_ease_function.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_i_ease_function.java.i new file mode 100644 index 0000000..613f2ec Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/ease/_i_ease_function.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/util/_shape_modifier_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/util/_shape_modifier_utils.java.i new file mode 100644 index 0000000..e2cda47 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/modifier/util/_shape_modifier_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/util/_shape_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/util/_shape_utils.java.i new file mode 100644 index 0000000..97fa16e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/shape/util/_shape_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_animated_sprite.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_animated_sprite.java.i new file mode 100644 index 0000000..96fc613 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_animated_sprite.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_animated_sprite_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_animated_sprite_renderer.java.i new file mode 100644 index 0000000..92996ab Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_animated_sprite_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_base_sprite.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_base_sprite.java.i new file mode 100644 index 0000000..3cf3785 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_base_sprite.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_modification_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_modification_listener.java.i new file mode 100644 index 0000000..9b0be04 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_modification_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_modifier_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_modifier_listener.java.i new file mode 100644 index 0000000..dab29c7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_modifier_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_sprite_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_sprite_modifier.java.i new file mode 100644 index 0000000..b3cce97 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_i_sprite_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_sprite.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_sprite.java.i new file mode 100644 index 0000000..79d14c2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_sprite.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_sprite_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_sprite_renderer.java.i new file mode 100644 index 0000000..ebddd63 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_sprite_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_tiled_sprite.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_tiled_sprite.java.i new file mode 100644 index 0000000..7ed6eb6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_tiled_sprite.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_tiled_sprite_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_tiled_sprite_renderer.java.i new file mode 100644 index 0000000..4162beb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/_tiled_sprite_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_alpha_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_alpha_modifier.java.i new file mode 100644 index 0000000..1ad03e3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_alpha_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_from_to_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_from_to_modifier.java.i new file mode 100644 index 0000000..16e0aa2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_from_to_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_modifier.java.i new file mode 100644 index 0000000..cefcc02 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_pair_from_to_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_pair_from_to_modifier.java.i new file mode 100644 index 0000000..7d2f09f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_base_pair_from_to_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_delay_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_delay_modifier.java.i new file mode 100644 index 0000000..f1ae140 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_delay_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_move_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_move_modifier.java.i new file mode 100644 index 0000000..2853e50 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_move_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_rotate_by_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_rotate_by_modifier.java.i new file mode 100644 index 0000000..402f353 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_rotate_by_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_rotate_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_rotate_modifier.java.i new file mode 100644 index 0000000..79401b2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_rotate_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_scale_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_scale_modifier.java.i new file mode 100644 index 0000000..ebbad40 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_scale_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_sequence_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_sequence_modifier.java.i new file mode 100644 index 0000000..e65189d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/sprite/modifier/_sequence_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_changeable_text.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_changeable_text.java.i new file mode 100644 index 0000000..c52a97c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_changeable_text.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_text.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_text.java.i new file mode 100644 index 0000000..9302346 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_text.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_text_renderer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_text_renderer.java.i new file mode 100644 index 0000000..2e6aef1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_text_renderer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_ticker_text.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_ticker_text.java.i new file mode 100644 index 0000000..e7fa1cd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/text/_ticker_text.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_average_f_p_s_counter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_average_f_p_s_counter.java.i new file mode 100644 index 0000000..c3fa630 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_average_f_p_s_counter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_f_p_s_counter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_f_p_s_counter.java.i new file mode 100644 index 0000000..24fe3ab Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_f_p_s_counter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_f_p_s_logger.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_f_p_s_logger.java.i new file mode 100644 index 0000000..9faeeb9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_f_p_s_logger.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_count_crasher.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_count_crasher.java.i new file mode 100644 index 0000000..c4f4ab5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_count_crasher.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_counter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_counter.java.i new file mode 100644 index 0000000..0a75483 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_counter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_length_logger.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_length_logger.java.i new file mode 100644 index 0000000..b29b853 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_frame_length_logger.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_on_area_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_on_area_touch_listener.java.i new file mode 100644 index 0000000..d1ec501 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_on_area_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_on_scene_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_on_scene_touch_listener.java.i new file mode 100644 index 0000000..2611576 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_on_scene_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_touch_area.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_touch_area.java.i new file mode 100644 index 0000000..bc59002 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_i_touch_area.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_screen_capture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_screen_capture.java.i new file mode 100644 index 0000000..9dddddd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_screen_capture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_screen_grabber.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_screen_grabber.java.i new file mode 100644 index 0000000..9f5feaa Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/entity/util/_screen_grabber.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/game/_base_game_activity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/game/_base_game_activity.java.i new file mode 100644 index 0000000..e95b2bd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/game/_base_game_activity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_on_area_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_on_area_touch_listener.java.i new file mode 100644 index 0000000..667c7f6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_on_area_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_on_scene_touch_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_on_scene_touch_listener.java.i new file mode 100644 index 0000000..5261c92 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_on_scene_touch_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_touch_area.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_touch_area.java.i new file mode 100644 index 0000000..ba5b7cf Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_i_touch_area.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_touch_event.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_touch_event.java.i new file mode 100644 index 0000000..06f4829 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/_touch_event.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_base_touch_controller.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_base_touch_controller.java.i new file mode 100644 index 0000000..4729a5c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_base_touch_controller.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_i_touch_controller.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_i_touch_controller.java.i new file mode 100644 index 0000000..b9a666e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_i_touch_controller.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_multi_touch_controler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_multi_touch_controler.java.i new file mode 100644 index 0000000..f2687a4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_multi_touch_controler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_single_touch_controler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_single_touch_controler.java.i new file mode 100644 index 0000000..9953171 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/controller/_single_touch_controler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_base_detector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_base_detector.java.i new file mode 100644 index 0000000..3c453f3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_base_detector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_click_detector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_click_detector.java.i new file mode 100644 index 0000000..fc0ff08 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_click_detector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_hold_detector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_hold_detector.java.i new file mode 100644 index 0000000..9806368 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_hold_detector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_scroll_detector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_scroll_detector.java.i new file mode 100644 index 0000000..ca32927 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_scroll_detector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_surface_gesture_detector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_surface_gesture_detector.java.i new file mode 100644 index 0000000..0fe84e3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_surface_gesture_detector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_surface_scroll_detector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_surface_scroll_detector.java.i new file mode 100644 index 0000000..30ff1f5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/input/touch/detector/_surface_scroll_detector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/level/_level_loader.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/level/_level_loader.java.i new file mode 100644 index 0000000..dfcec82 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/level/_level_loader.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/level/_level_parser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/level/_level_parser.java.i new file mode 100644 index 0000000..82c7acc Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/level/_level_parser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/level/util/constants/_level_constants.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/level/util/constants/_level_constants.java.i new file mode 100644 index 0000000..e0ad51b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/level/util/constants/_level_constants.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_base_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_base_buffer.java.i new file mode 100644 index 0000000..ed54867 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_base_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_g_l_helper.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_g_l_helper.java.i new file mode 100644 index 0000000..1856a32 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_g_l_helper.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_drawable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_drawable.java.i new file mode 100644 index 0000000..c47844f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_drawable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_render_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_render_handler.java.i new file mode 100644 index 0000000..12d947e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_render_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_renderable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_renderable.java.i new file mode 100644 index 0000000..78f780f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/_i_renderable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_base_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_base_buffer.java.i new file mode 100644 index 0000000..a6d80f2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_base_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_buffer_object.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_buffer_object.java.i new file mode 100644 index 0000000..da2e066 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_buffer_object.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_buffer_object_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_buffer_object_manager.java.i new file mode 100644 index 0000000..788fe16 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/buffer/_buffer_object_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font.java.i new file mode 100644 index 0000000..b06e4fb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_factory.java.i new file mode 100644 index 0000000..57f1287 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_library.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_library.java.i new file mode 100644 index 0000000..c490041 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_library.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_manager.java.i new file mode 100644 index 0000000..1925634 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_font_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_letter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_letter.java.i new file mode 100644 index 0000000..9ebbf0e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_letter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_size.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_size.java.i new file mode 100644 index 0000000..79dec06 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_size.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_stroke_font.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_stroke_font.java.i new file mode 100644 index 0000000..767b63c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/font/_stroke_font.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_font.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_font.java.i new file mode 100644 index 0000000..6866f24 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_font.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_glyph.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_glyph.java.i new file mode 100644 index 0000000..170944e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_glyph.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_letter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_letter.java.i new file mode 100644 index 0000000..17f7efb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_letter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_rectangle.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_rectangle.java.i new file mode 100644 index 0000000..3ecede7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_rectangle.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_size.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_size.java.i new file mode 100644 index 0000000..ede1c53 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/text/_size.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_asset_texture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_asset_texture.java.i new file mode 100644 index 0000000..fc17212 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_asset_texture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_buildable_texture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_buildable_texture.java.i new file mode 100644 index 0000000..f468b00 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_buildable_texture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_font_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_font_manager.java.i new file mode 100644 index 0000000..50e1fc3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_font_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_i_texture_state_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_i_texture_state_listener.java.i new file mode 100644 index 0000000..52846d4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_i_texture_state_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_packable_texture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_packable_texture.java.i new file mode 100644 index 0000000..83a0368 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_packable_texture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_resource_texture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_resource_texture.java.i new file mode 100644 index 0000000..35fbe58 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_resource_texture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture.java.i new file mode 100644 index 0000000..19bb1c1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_atlas.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_atlas.java.i new file mode 100644 index 0000000..e27b5f6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_atlas.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_buffer.java.i new file mode 100644 index 0000000..b6e3c44 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_factory.java.i new file mode 100644 index 0000000..f465e31 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_manager.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_manager.java.i new file mode 100644 index 0000000..cf0eca7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_manager.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_options.java.i new file mode 100644 index 0000000..1bb1ad3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_region.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_region.java.i new file mode 100644 index 0000000..4e378f1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_region.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_region_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_region_factory.java.i new file mode 100644 index 0000000..b676bce Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_texture_region_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_tiled_texture.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_tiled_texture.java.i new file mode 100644 index 0000000..328b6a9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_tiled_texture.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_tiled_texture_region.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_tiled_texture_region.java.i new file mode 100644 index 0000000..8897f99 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/_tiled_texture_region.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_base_texture_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_base_texture_buffer.java.i new file mode 100644 index 0000000..279db8a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_base_texture_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_base_texture_region_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_base_texture_region_buffer.java.i new file mode 100644 index 0000000..1f1d9d2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_base_texture_region_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_text_texture_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_text_texture_buffer.java.i new file mode 100644 index 0000000..bce2704 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_text_texture_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_texture_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_texture_buffer.java.i new file mode 100644 index 0000000..5afe3f8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_texture_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_texture_region_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_texture_region_buffer.java.i new file mode 100644 index 0000000..42def8d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_texture_region_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_tiled_texture_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_tiled_texture_buffer.java.i new file mode 100644 index 0000000..92ddaff Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_tiled_texture_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_tiled_texture_region_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_tiled_texture_region_buffer.java.i new file mode 100644 index 0000000..18d9e84 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/buffer/_tiled_texture_region_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/builder/_black_pawn_texture_builder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/builder/_black_pawn_texture_builder.java.i new file mode 100644 index 0000000..f785810 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/builder/_black_pawn_texture_builder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/builder/_i_texture_builder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/builder/_i_texture_builder.java.i new file mode 100644 index 0000000..434df99 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/builder/_i_texture_builder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/factory/_texture_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/factory/_texture_factory.java.i new file mode 100644 index 0000000..f22838b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/factory/_texture_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/factory/_texture_region_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/factory/_texture_region_factory.java.i new file mode 100644 index 0000000..92cecc9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/factory/_texture_region_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_base_texture_region.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_base_texture_region.java.i new file mode 100644 index 0000000..aa041f4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_base_texture_region.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region.java.i new file mode 100644 index 0000000..e6b38fa Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region_factory.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region_factory.java.i new file mode 100644 index 0000000..f9577d7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region_factory.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region_library.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region_library.java.i new file mode 100644 index 0000000..54fe480 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_texture_region_library.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_tiled_texture_region.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_tiled_texture_region.java.i new file mode 100644 index 0000000..21a9554 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/_tiled_texture_region.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_base_texture_region_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_base_texture_region_buffer.java.i new file mode 100644 index 0000000..8c9f7a9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_base_texture_region_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_texture_region_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_texture_region_buffer.java.i new file mode 100644 index 0000000..ba1d096 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_texture_region_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_tiled_texture_region_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_tiled_texture_region_buffer.java.i new file mode 100644 index 0000000..38e996d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/region/buffer/_tiled_texture_region_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_asset_texture_source.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_asset_texture_source.java.i new file mode 100644 index 0000000..93732eb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_asset_texture_source.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_color_key_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_color_key_texture_source_decorator.java.i new file mode 100644 index 0000000..1cc0460 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_color_key_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_empty_bitmap_texture_source.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_empty_bitmap_texture_source.java.i new file mode 100644 index 0000000..6cb051a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_empty_bitmap_texture_source.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_file_texture_source.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_file_texture_source.java.i new file mode 100644 index 0000000..05a193d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_file_texture_source.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_i_texture_source.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_i_texture_source.java.i new file mode 100644 index 0000000..4d094ca Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_i_texture_source.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_outline_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_outline_texture_source_decorator.java.i new file mode 100644 index 0000000..da77c52 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_outline_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_resource_texture_source.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_resource_texture_source.java.i new file mode 100644 index 0000000..7c8f072 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_resource_texture_source.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_texture_source_decorator.java.i new file mode 100644 index 0000000..66fd40b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_base_shape_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_base_shape_texture_source_decorator.java.i new file mode 100644 index 0000000..2da3282 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_base_shape_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_base_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_base_texture_source_decorator.java.i new file mode 100644 index 0000000..dbfab08 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_base_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_circle_fill_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_circle_fill_texture_source_decorator.java.i new file mode 100644 index 0000000..d289dff Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_circle_fill_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_circle_outline_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_circle_outline_texture_source_decorator.java.i new file mode 100644 index 0000000..707273e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_circle_outline_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_color_key_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_color_key_texture_source_decorator.java.i new file mode 100644 index 0000000..2c5a215 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_color_key_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_fill_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_fill_texture_source_decorator.java.i new file mode 100644 index 0000000..ee88a50 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_fill_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_linear_gradient_fill_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_linear_gradient_fill_texture_source_decorator.java.i new file mode 100644 index 0000000..364000c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_linear_gradient_fill_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_outline_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_outline_texture_source_decorator.java.i new file mode 100644 index 0000000..8342003 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_outline_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_radial_gradient_fill_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_radial_gradient_fill_texture_source_decorator.java.i new file mode 100644 index 0000000..a56ddd7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_radial_gradient_fill_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_rectangle_fill_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_rectangle_fill_texture_source_decorator.java.i new file mode 100644 index 0000000..b07b394 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_rectangle_fill_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_texture_source_decorator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_texture_source_decorator.java.i new file mode 100644 index 0000000..03f4d6f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/_texture_source_decorator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_arc_texture_source_decorator_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_arc_texture_source_decorator_shape.java.i new file mode 100644 index 0000000..5955c19 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_arc_texture_source_decorator_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_circle_texture_source_decorator_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_circle_texture_source_decorator_shape.java.i new file mode 100644 index 0000000..05a5f9e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_circle_texture_source_decorator_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_ellipse_texture_source_decorator_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_ellipse_texture_source_decorator_shape.java.i new file mode 100644 index 0000000..60fafba Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_ellipse_texture_source_decorator_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_i_texture_source_decorator_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_i_texture_source_decorator_shape.java.i new file mode 100644 index 0000000..4d39c4c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_i_texture_source_decorator_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_rectangle_texture_source_decorator_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_rectangle_texture_source_decorator_shape.java.i new file mode 100644 index 0000000..32e6081 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/_rectangle_texture_source_decorator_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/packing/_black_pawn_texture_source_packing_algorithm.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/packing/_black_pawn_texture_source_packing_algorithm.java.i new file mode 100644 index 0000000..b84a47f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/packing/_black_pawn_texture_source_packing_algorithm.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/packing/_i_texture_source_packing_algorithm.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/packing/_i_texture_source_packing_algorithm.java.i new file mode 100644 index 0000000..f2a8155 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/texture/source/packing/_i_texture_source_packing_algorithm.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/util/_fast_float_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/util/_fast_float_buffer.java.i new file mode 100644 index 0000000..d435559 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/util/_fast_float_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/util/_g_l_helper.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/util/_g_l_helper.java.i new file mode 100644 index 0000000..d1f2a9f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/util/_g_l_helper.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_line_vertex_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_line_vertex_buffer.java.i new file mode 100644 index 0000000..e9e242c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_line_vertex_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_rectangle_vertex_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_rectangle_vertex_buffer.java.i new file mode 100644 index 0000000..ac5b5df Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_rectangle_vertex_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_text_vertex_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_text_vertex_buffer.java.i new file mode 100644 index 0000000..0825d28 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_text_vertex_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_vertex_buffer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_vertex_buffer.java.i new file mode 100644 index 0000000..0ce5059 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/vertex/_vertex_buffer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_base_config_chooser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_base_config_chooser.java.i new file mode 100644 index 0000000..4bd59ea Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_base_config_chooser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_component_size_chooser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_component_size_chooser.java.i new file mode 100644 index 0000000..8b2ff42 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_component_size_chooser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_e_g_l_config_chooser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_e_g_l_config_chooser.java.i new file mode 100644 index 0000000..9dbfa0f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_e_g_l_config_chooser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_g_l_surface_view.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_g_l_surface_view.java.i new file mode 100644 index 0000000..f690c76 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_g_l_surface_view.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_g_l_wrapper.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_g_l_wrapper.java.i new file mode 100644 index 0000000..3bb55f3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_g_l_wrapper.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_log_writer.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_log_writer.java.i new file mode 100644 index 0000000..50551bf Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_log_writer.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_render_surface_view.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_render_surface_view.java.i new file mode 100644 index 0000000..2d44cfd Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_render_surface_view.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_simple_e_g_l_config_chooser.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_simple_e_g_l_config_chooser.java.i new file mode 100644 index 0000000..92db901 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/_simple_e_g_l_config_chooser.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_camera.java.i new file mode 100644 index 0000000..4a1205f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_chase_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_chase_camera.java.i new file mode 100644 index 0000000..2ecdcc6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_chase_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_smooth_camera.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_smooth_camera.java.i new file mode 100644 index 0000000..f3e5e17 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/opengl/view/camera/_smooth_camera.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_base_physics_body.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_base_physics_body.java.i new file mode 100644 index 0000000..a685eab Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_base_physics_body.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_dynamic_physics_body.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_dynamic_physics_body.java.i new file mode 100644 index 0000000..e031541 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_dynamic_physics_body.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_i_physics_space.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_i_physics_space.java.i new file mode 100644 index 0000000..66fdf7b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_i_physics_space.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_physics_data.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_physics_data.java.i new file mode 100644 index 0000000..55acd39 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_physics_data.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_physics_shape.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_physics_shape.java.i new file mode 100644 index 0000000..4d20457 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_physics_shape.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_static_physics_body.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_static_physics_body.java.i new file mode 100644 index 0000000..009c535 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/_static_physics_body.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/collision/_collision_checker.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/collision/_collision_checker.java.i new file mode 100644 index 0000000..846d7ee Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/collision/_collision_checker.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/collision/_intersector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/collision/_intersector.java.i new file mode 100644 index 0000000..70349ab Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/physics/collision/_intersector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/_base_sensor_data.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/_base_sensor_data.java.i new file mode 100644 index 0000000..b3f0bd3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/_base_sensor_data.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/_sensor_delay.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/_sensor_delay.java.i new file mode 100644 index 0000000..07c0b49 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/_sensor_delay.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_data.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_data.java.i new file mode 100644 index 0000000..08bd742 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_data.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_listener.java.i new file mode 100644 index 0000000..02e85e9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_sensor_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_sensor_options.java.i new file mode 100644 index 0000000..a15ede7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_accelerometer_sensor_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_i_accelerometer_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_i_accelerometer_listener.java.i new file mode 100644 index 0000000..5a7ec82 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/accelerometer/_i_accelerometer_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_i_location_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_i_location_listener.java.i new file mode 100644 index 0000000..41f4d3f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_i_location_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_location_provider_status.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_location_provider_status.java.i new file mode 100644 index 0000000..7a1388d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_location_provider_status.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_location_sensor_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_location_sensor_options.java.i new file mode 100644 index 0000000..d2a420f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/location/_location_sensor_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_i_orientation_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_i_orientation_listener.java.i new file mode 100644 index 0000000..7ad36f5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_i_orientation_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_orientation_data.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_orientation_data.java.i new file mode 100644 index 0000000..0b97156 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_orientation_data.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_orientation_sensor_options.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_orientation_sensor_options.java.i new file mode 100644 index 0000000..d3f048f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/sensor/orientation/_orientation_sensor_options.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/_i_game_interface.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/_i_game_interface.java.i new file mode 100644 index 0000000..4ff0f11 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/_i_game_interface.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_activity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_activity.java.i new file mode 100644 index 0000000..21d89d5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_activity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_game_activity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_game_activity.java.i new file mode 100644 index 0000000..832bc00 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_game_activity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_splash_activity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_splash_activity.java.i new file mode 100644 index 0000000..8ade054 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_base_splash_activity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_layout_game_activity.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_layout_game_activity.java.i new file mode 100644 index 0000000..f20dcea Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/activity/_layout_game_activity.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_generic_input_dialog_builder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_generic_input_dialog_builder.java.i new file mode 100644 index 0000000..8c22c97 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_generic_input_dialog_builder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_string_input_dialog_builder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_string_input_dialog_builder.java.i new file mode 100644 index 0000000..9283166 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_string_input_dialog_builder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_string_input_dialoguilder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_string_input_dialoguilder.java.i new file mode 100644 index 0000000..8ff2f2a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/ui/dialog/_string_input_dialoguilder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_activity_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_activity_utils.java.i new file mode 100644 index 0000000..c0e6f7e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_activity_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_array_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_array_utils.java.i new file mode 100644 index 0000000..0da7fa8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_array_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_async_callable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_async_callable.java.i new file mode 100644 index 0000000..a57521d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_async_callable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_base64.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_base64.java.i new file mode 100644 index 0000000..8df646c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_base64.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_base64_input_stream.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_base64_input_stream.java.i new file mode 100644 index 0000000..42a4580 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_base64_input_stream.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_beta_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_beta_utils.java.i new file mode 100644 index 0000000..0a34fb7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_beta_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_callable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_callable.java.i new file mode 100644 index 0000000..4a27178 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_callable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_callback.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_callback.java.i new file mode 100644 index 0000000..187101f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_callback.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_color_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_color_utils.java.i new file mode 100644 index 0000000..e3cd454 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_color_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_data_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_data_utils.java.i new file mode 100644 index 0000000..2076164 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_data_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_debug.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_debug.java.i new file mode 100644 index 0000000..bb15f56 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_debug.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_file_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_file_utils.java.i new file mode 100644 index 0000000..b943dc5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_file_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_hashtable_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_hashtable_utils.java.i new file mode 100644 index 0000000..20d7420 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_hashtable_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_horizontal_align.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_horizontal_align.java.i new file mode 100644 index 0000000..c3a36d8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_horizontal_align.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_i_entity_matcher.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_i_entity_matcher.java.i new file mode 100644 index 0000000..d625f33 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_i_entity_matcher.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_i_matcher.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_i_matcher.java.i new file mode 100644 index 0000000..58da8ef Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_i_matcher.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_library.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_library.java.i new file mode 100644 index 0000000..cd3d9f6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_library.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_list_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_list_utils.java.i new file mode 100644 index 0000000..a2e683e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_list_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_math_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_math_utils.java.i new file mode 100644 index 0000000..412daee Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_math_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_multi_key.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_multi_key.java.i new file mode 100644 index 0000000..f1ddc77 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_multi_key.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_multi_key_hash_map.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_multi_key_hash_map.java.i new file mode 100644 index 0000000..ac727b8 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_multi_key_hash_map.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_parameter_callable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_parameter_callable.java.i new file mode 100644 index 0000000..7842ded Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_parameter_callable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_path.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_path.java.i new file mode 100644 index 0000000..b6d8218 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_path.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_probability_generator.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_probability_generator.java.i new file mode 100644 index 0000000..ca17ea4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_probability_generator.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_progress_callable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_progress_callable.java.i new file mode 100644 index 0000000..9c761a9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_progress_callable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_s_a_x_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_s_a_x_utils.java.i new file mode 100644 index 0000000..e221563 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_s_a_x_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_simple_preferences.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_simple_preferences.java.i new file mode 100644 index 0000000..058bfd6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_simple_preferences.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_smart_list.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_smart_list.java.i new file mode 100644 index 0000000..92bb834 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_smart_list.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_socket_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_socket_utils.java.i new file mode 100644 index 0000000..5ac8fc2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_socket_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_stream_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_stream_utils.java.i new file mode 100644 index 0000000..f92143b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_stream_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_string_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_string_utils.java.i new file mode 100644 index 0000000..496576b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_string_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_system_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_system_utils.java.i new file mode 100644 index 0000000..a1f8212 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_system_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_time_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_time_utils.java.i new file mode 100644 index 0000000..b374d5c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_time_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_transformation.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_transformation.java.i new file mode 100644 index 0000000..2e8268b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_transformation.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_transformation_pool.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_transformation_pool.java.i new file mode 100644 index 0000000..b737bcb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_transformation_pool.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_user_task.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_user_task.java.i new file mode 100644 index 0000000..23ff119 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_user_task.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_vertical_align.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_vertical_align.java.i new file mode 100644 index 0000000..656a0f5 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_vertical_align.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_view_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_view_utils.java.i new file mode 100644 index 0000000..9f556e0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/_view_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/cache/_rectangle_vertex_buffer_cache.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/cache/_rectangle_vertex_buffer_cache.java.i new file mode 100644 index 0000000..9731ba9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/cache/_rectangle_vertex_buffer_cache.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_color_constants.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_color_constants.java.i new file mode 100644 index 0000000..a8dc6de Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_color_constants.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_constants.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_constants.java.i new file mode 100644 index 0000000..9d30773 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_constants.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_m_i_m_e_types.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_m_i_m_e_types.java.i new file mode 100644 index 0000000..53c9b2c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_m_i_m_e_types.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_math_constants.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_math_constants.java.i new file mode 100644 index 0000000..2938bcb Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_math_constants.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_time_constants.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_time_constants.java.i new file mode 100644 index 0000000..1076a83 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/constants/_time_constants.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/levelstats/_level_stats_d_b_connector.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/levelstats/_level_stats_d_b_connector.java.i new file mode 100644 index 0000000..bb277b7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/levelstats/_level_stats_d_b_connector.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_double_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_double_value_span_modifier.java.i new file mode 100644 index 0000000..d692fe1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_double_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_duration_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_duration_modifier.java.i new file mode 100644 index 0000000..6fa6df1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_duration_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_modifier.java.i new file mode 100644 index 0000000..21e91ae Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_single_value_change_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_single_value_change_modifier.java.i new file mode 100644 index 0000000..e6545ba Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_single_value_change_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_single_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_single_value_span_modifier.java.i new file mode 100644 index 0000000..326ff0e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_single_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_triple_value_span_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_triple_value_span_modifier.java.i new file mode 100644 index 0000000..7bd001f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_base_triple_value_span_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_i_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_i_modifier.java.i new file mode 100644 index 0000000..2c33cef Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_i_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_loop_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_loop_modifier.java.i new file mode 100644 index 0000000..611f2e7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_loop_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_modifier_list.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_modifier_list.java.i new file mode 100644 index 0000000..32be5b2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_modifier_list.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_parallel_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_parallel_modifier.java.i new file mode 100644 index 0000000..67cf9ac Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_parallel_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_sequence_modifier.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_sequence_modifier.java.i new file mode 100644 index 0000000..f1dabc7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/_sequence_modifier.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_in.java.i new file mode 100644 index 0000000..cbcbb9f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_in_out.java.i new file mode 100644 index 0000000..e36a5d6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_out.java.i new file mode 100644 index 0000000..6518fa4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_back_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_in.java.i new file mode 100644 index 0000000..cd968b1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_in_out.java.i new file mode 100644 index 0000000..f4a4c98 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_out.java.i new file mode 100644 index 0000000..cc60a53 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_bounce_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_in.java.i new file mode 100644 index 0000000..39f02d0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_in_out.java.i new file mode 100644 index 0000000..323ef9f Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_out.java.i new file mode 100644 index 0000000..4d9e930 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_circular_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_in.java.i new file mode 100644 index 0000000..d9fa12d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_in_out.java.i new file mode 100644 index 0000000..8696f74 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_out.java.i new file mode 100644 index 0000000..512793a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_cubic_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_in.java.i new file mode 100644 index 0000000..fb4fcd6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_in_out.java.i new file mode 100644 index 0000000..197f3c3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_out.java.i new file mode 100644 index 0000000..5a70c69 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_elastic_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_in.java.i new file mode 100644 index 0000000..a48b2e1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_in_out.java.i new file mode 100644 index 0000000..4c1ba36 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_out.java.i new file mode 100644 index 0000000..096fa21 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_exponential_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_linear.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_linear.java.i new file mode 100644 index 0000000..a94ca4c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_linear.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_in.java.i new file mode 100644 index 0000000..5a872a6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_in_out.java.i new file mode 100644 index 0000000..1da3369 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_out.java.i new file mode 100644 index 0000000..e9d2b90 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quad_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_in.java.i new file mode 100644 index 0000000..44766ce Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_in_out.java.i new file mode 100644 index 0000000..6f7bb8a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_out.java.i new file mode 100644 index 0000000..94203dc Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quart_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_in.java.i new file mode 100644 index 0000000..6c550bf Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_in_out.java.i new file mode 100644 index 0000000..834398c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_out.java.i new file mode 100644 index 0000000..7e32da0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_quint_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_in.java.i new file mode 100644 index 0000000..7cf84e0 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_in_out.java.i new file mode 100644 index 0000000..99dc35d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_out.java.i new file mode 100644 index 0000000..2154580 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_sine_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_in.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_in.java.i new file mode 100644 index 0000000..a72916e Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_in.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_in_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_in_out.java.i new file mode 100644 index 0000000..5e795b9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_in_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_out.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_out.java.i new file mode 100644 index 0000000..5406636 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_ease_strong_out.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_i_ease_function.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_i_ease_function.java.i new file mode 100644 index 0000000..4dc6451 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/ease/_i_ease_function.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/util/_modifier_utils.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/util/_modifier_utils.java.i new file mode 100644 index 0000000..ab77576 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/modifier/util/_modifier_utils.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_direction.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_direction.java.i new file mode 100644 index 0000000..effdbca Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_direction.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_i_path_finder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_i_path_finder.java.i new file mode 100644 index 0000000..5d516ce Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_i_path_finder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_i_tiled_map.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_i_tiled_map.java.i new file mode 100644 index 0000000..d21ad8c Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_i_tiled_map.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_path.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_path.java.i new file mode 100644 index 0000000..dbf3db2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/_path.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_a_star_path_finder.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_a_star_path_finder.java.i new file mode 100644 index 0000000..8b8ffc3 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_a_star_path_finder.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_euclidean_heuristic.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_euclidean_heuristic.java.i new file mode 100644 index 0000000..f0c4dc7 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_euclidean_heuristic.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_i_a_star_heuristic.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_i_a_star_heuristic.java.i new file mode 100644 index 0000000..3d552c2 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_i_a_star_heuristic.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_manhattan_heuristic.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_manhattan_heuristic.java.i new file mode 100644 index 0000000..16a3eac Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_manhattan_heuristic.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_null_heuristic.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_null_heuristic.java.i new file mode 100644 index 0000000..69cb8ea Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/path/astar/_null_heuristic.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_detach_runnable_pool_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_detach_runnable_pool_item.java.i new file mode 100644 index 0000000..624ea56 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_detach_runnable_pool_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_detach_runnable_pool_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_detach_runnable_pool_update_handler.java.i new file mode 100644 index 0000000..063b553 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_detach_runnable_pool_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_remove_runnable_pool_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_remove_runnable_pool_item.java.i new file mode 100644 index 0000000..e579102 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_remove_runnable_pool_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_remove_runnable_pool_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_remove_runnable_pool_update_handler.java.i new file mode 100644 index 0000000..d9cb3e6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_entity_remove_runnable_pool_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_generic_pool.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_generic_pool.java.i new file mode 100644 index 0000000..95967a1 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_generic_pool.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_multi_pool.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_multi_pool.java.i new file mode 100644 index 0000000..742d9a9 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_multi_pool.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool.java.i new file mode 100644 index 0000000..4ad13b6 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool_item.java.i new file mode 100644 index 0000000..2de5f2b Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool_update_handler.java.i new file mode 100644 index 0000000..b96b0a4 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_pool_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_runnable_pool_item.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_runnable_pool_item.java.i new file mode 100644 index 0000000..76364af Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_runnable_pool_item.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_runnable_pool_update_handler.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_runnable_pool_update_handler.java.i new file mode 100644 index 0000000..5fdc935 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/pool/_runnable_pool_update_handler.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_i_progress_listener.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_i_progress_listener.java.i new file mode 100644 index 0000000..dfeb637 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_i_progress_listener.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_progress_callable.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_progress_callable.java.i new file mode 100644 index 0000000..56c272d Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_progress_callable.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_progress_monitor.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_progress_monitor.java.i new file mode 100644 index 0000000..eca8119 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/progress/_progress_monitor.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/sort/_insertion_sorter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/sort/_insertion_sorter.java.i new file mode 100644 index 0000000..769e34a Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/sort/_insertion_sorter.java.i differ diff --git a/AndEngine/.hg/store/data/src/org/anddev/andengine/util/sort/_sorter.java.i b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/sort/_sorter.java.i new file mode 100644 index 0000000..1be8681 Binary files /dev/null and b/AndEngine/.hg/store/data/src/org/anddev/andengine/util/sort/_sorter.java.i differ diff --git a/AndEngine/.hg/store/data/test/org/anddev/andengine/util/_string_utils_test.java.i b/AndEngine/.hg/store/data/test/org/anddev/andengine/util/_string_utils_test.java.i new file mode 100644 index 0000000..78c892e Binary files /dev/null and b/AndEngine/.hg/store/data/test/org/anddev/andengine/util/_string_utils_test.java.i differ diff --git a/AndEngine/.hg/store/data/uml/andengine__classdiagram.png.i b/AndEngine/.hg/store/data/uml/andengine__classdiagram.png.i new file mode 100644 index 0000000..567644b Binary files /dev/null and b/AndEngine/.hg/store/data/uml/andengine__classdiagram.png.i differ diff --git a/AndEngine/.hg/store/data/uml/andengine__classdiagram.ucls.i b/AndEngine/.hg/store/data/uml/andengine__classdiagram.ucls.i new file mode 100644 index 0000000..4fb11cc Binary files /dev/null and b/AndEngine/.hg/store/data/uml/andengine__classdiagram.ucls.i differ diff --git a/AndEngine/.hg/store/data/~2eclasspath.i b/AndEngine/.hg/store/data/~2eclasspath.i new file mode 100644 index 0000000..07a7ab7 Binary files /dev/null and b/AndEngine/.hg/store/data/~2eclasspath.i differ diff --git a/AndEngine/.hg/store/data/~2ehgignore.i b/AndEngine/.hg/store/data/~2ehgignore.i new file mode 100644 index 0000000..39931bf Binary files /dev/null and b/AndEngine/.hg/store/data/~2ehgignore.i differ diff --git a/AndEngine/.hg/store/data/~2eproject.i b/AndEngine/.hg/store/data/~2eproject.i new file mode 100644 index 0000000..290dbbc Binary files /dev/null and b/AndEngine/.hg/store/data/~2eproject.i differ diff --git a/AndEngine/.hg/store/dh/src/org/anddev/andengin/opengl/texture/source/decorato/rectanglelineargradi557b574af419ce9da084d7cb2edd96c8167e414d.i b/AndEngine/.hg/store/dh/src/org/anddev/andengin/opengl/texture/source/decorato/rectanglelineargradi557b574af419ce9da084d7cb2edd96c8167e414d.i new file mode 100644 index 0000000..b1576e0 Binary files /dev/null and b/AndEngine/.hg/store/dh/src/org/anddev/andengin/opengl/texture/source/decorato/rectanglelineargradi557b574af419ce9da084d7cb2edd96c8167e414d.i differ diff --git a/AndEngine/.hg/store/dh/src/org/anddev/andengin/opengl/texture/source/decorato/shape/roundedrectangca23493c2bf9765f3a9663ef116bd36864da9289.i b/AndEngine/.hg/store/dh/src/org/anddev/andengin/opengl/texture/source/decorato/shape/roundedrectangca23493c2bf9765f3a9663ef116bd36864da9289.i new file mode 100644 index 0000000..9c92dd5 Binary files /dev/null and b/AndEngine/.hg/store/dh/src/org/anddev/andengin/opengl/texture/source/decorato/shape/roundedrectangca23493c2bf9765f3a9663ef116bd36864da9289.i differ diff --git a/AndEngine/.hg/store/fncache b/AndEngine/.hg/store/fncache new file mode 100644 index 0000000..d6b232f --- /dev/null +++ b/AndEngine/.hg/store/fncache @@ -0,0 +1,698 @@ +data/src/org/anddev/andengine/ui/activity/BaseActivity.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BasePairFromToModifier.java.i +data/src/org/anddev/andengine/util/modifier/util/ModifierUtils.java.i +data/src/org/anddev/andengine/entity/particle/initializer/RotationInitializer.java.i +data/src/org/anddev/andengine/opengl/texture/builder/BlackPawnTextureBuilder.java.i +data/src/org/anddev/andengine/util/modifier/SequenceModifier.java.i +data/src/org/anddev/andengine/util/ListUtils.java.i +data/src/org/anddev/andengine/entity/scene/background/BaseBackground.java.i +data/src/org/anddev/andengine/entity/FrameLengthLogger.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseBackIn.java.i +data/src/org/anddev/andengine/entity/particle/emitter/RectangleOutlineParticleEmitter.java.i +data/src/org/anddev/andengine/util/Base64InputStream.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/SequenceModifier.java.i +data/src/org/anddev/andengine/entity/handler/collision/ICollisionCallback.java.i +data/src/org/anddev/andengine/sensor/BaseSensorData.java.i +data/src/org/anddev/andengine/entity/menu/animator/DirectMenuAnimator.java.i +data/src/org/anddev/andengine/entity/primitives/Shape.java.i +data/src/org/anddev/andengine/entity/particle/modifier/ExpireModifier.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroupProperty.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseSineOut.java.i +data/src/org/anddev/andengine/collision/BaseCollisionChecker.java.i +data/src/org/anddev/andengine/entity/scene/menu/animator/BaseMenuAnimator.java.i +data/src/org/anddev/andengine/util/Path.java.i +data/src/org/anddev/andengine/util/MathUtils.java.i +data/src/org/anddev/andengine/sensor/location/ILocationListener.java.i +data/src/org/anddev/andengine/entity/util/ScreenGrabber.java.i +data/src/org/anddev/andengine/engine/camera/hud/controls/BaseOnScreenControl.java.i +data/src/org/anddev/andengine/entity/text/Text.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/ColoredTextMenuItem.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/MoveModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/RotationByModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseBackOut.java.i +data/src/org/anddev/andengine/opengl/texture/region/BaseTextureRegion.java.i +data/src/org/anddev/andengine/engine/easying/Easing.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuintOut.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseSingleValueChangeModifier.java.i +data/src/org/anddev/andengine/util/TransformationPool.java.i +data/src/org/anddev/andengine/opengl/view/EGLConfigChooser.java.i +data/src/org/anddev/andengine/opengl/font/Font.java.i +data/src/org/anddev/andengine/entity/modifier/ColorModifier.java.i +data/src/org/anddev/andengine/util/modifier/BaseDoubleValueSpanModifier.java.i +data/src/org/anddev/andengine/opengl/view/BaseConfigChooser.java.i +data/src/org/anddev/andengine/entity/HorizontalAlign.java.i +data/src/org/anddev/andengine/opengl/texture/TextureRegion.java.i +data/src/org/anddev/andengine/opengl/texture/TiledTextureRegion.java.i +data/src/org/anddev/andengine/util/MultiKeyHashMap.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseStrongIn.java.i +data/src/org/anddev/andengine/entity/shape/modifier/FadeInModifier.java.i +data/src/org/anddev/andengine/input/touch/controller/ITouchController.java.i +data/ant/exportJarToVolcanoLiveWallpaper.xml.i +data/src/org/anddev/andengine/entity/util/FPSCounter.java.i +data/src/org/anddev/andengine/ui/dialog/StringInputDialoguilder.java.i +data/src/org/anddev/andengine/entity/menu/animator/AlphaMenuAnimator.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/IMenuItem.java.i +data/src/org/anddev/andengine/engine/handler/runnable/RunnableHandler.java.i +data/src/org/anddev/andengine/util/levelstats/LevelStatsDBConnector.java.i +data/src/org/anddev/andengine/util/ProgressCallable.java.i +data/src/org/anddev/andengine/sensor/accelerometer/AccelerometerSensorOptions.java.i +data/src/org/anddev/andengine/level/util/constants/LevelConstants.java.i +data/src/org/anddev/andengine/entity/sprite/AnimatedSpriteRenderer.java.i +data/src/org/anddev/andengine/util/VerticalAlign.java.i +data/src/org/anddev/andengine/util/HashtableUtils.java.i +data/ext/img/logo4.png.i +data/src/org/anddev/andengine/engine/camera/Camera.java.i +data/src/org/anddev/andengine/engine/handler/IUpdateHandler.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseExponentialOut.java.i +data/src/org/anddev/andengine/entity/layer/LayerSorter.java.i +data/src/org/anddev/andengine/entity/modifier/MoveModifier.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BasePairInitializer.java.i +data/src/org/anddev/andengine/util/progress/ProgressCallable.java.i +data/src/org/anddev/andengine/entity/scene/background/ParallaxBackground.java.i +data/src/org/anddev/andengine/entity/particle/modifier/RotationInitializer.java.i +data/ant/exportJarToAndEnginePlayground.xml.i +data/ant/exportJarToAndEnginePhysicsBox2D.xml.i +data/src/org/anddev/andengine/entity/util/AverageFPSCounter.java.i +data/src/org/anddev/andengine/entity/scene/background/AutoParallaxBackground.java.i +data/src/org/anddev/andengine/entity/shape/modifier/SingleValueSpanShapeModifier.java.i +data/src/org/anddev/andengine/util/pool/EntityRemoveRunnablePoolUpdateHandler.java.i +data/src/org/anddev/andengine/entity/particle/emitter/IParticleEmitter.java.i +data/ant/exportJarToHeliTaxi.xml.i +data/src/org/anddev/andengine/entity/particle/modifier/OffCameraExpireModifier.java.i +data/src/org/anddev/andengine/entity/scene/background/modifier/IBackgroundModifier.java.i +data/src/org/anddev/andengine/entity/layer/BaseLayer.java.i +data/src/org/anddev/andengine/util/modifier/LoopModifier.java.i +data/src/org/anddev/andengine/physics/PhysicsData.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseStrongInOut.java.i +data/src/org/anddev/andengine/opengl/text/Rectangle.java.i +data/src/org/anddev/andengine/engine/camera/hud/controls/DigitalOnScreenControl.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseStrongInOut.java.i +data/src/org/anddev/andengine/opengl/texture/region/buffer/TextureRegionBuffer.java.i +data/src/org/anddev/andengine/entity/modifier/SingleValueSpanShapeModifier.java.i +data/ext/img/splash.svg.i +data/src/org/anddev/andengine/opengl/view/LogWriter.java.i +data/src/org/anddev/andengine/opengl/view/camera/ChaseCamera.java.i +data/src/org/anddev/andengine/entity/IStaticEntity.java.i +data/src/org/anddev/andengine/collision/ShapeCollisionChecker.java.i +data/src/org/anddev/andengine/util/path/astar/EuclideanHeuristic.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuadOut.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroup.java.i +data/src/org/anddev/andengine/opengl/texture/PackableTexture.java.i +data/push_buxs.bat.i +data/src/org/anddev/andengine/entity/shape/modifier/MoveYModifier.java.i +data/src/org/anddev/andengine/engine/options/RenderOptions.java.i +data/ext/img/logo.png.i +data/src/org/anddev/andengine/entity/sprite/TiledSprite.java.i +data/src/org/anddev/andengine/opengl/font/FontFactory.java.i +data/src/org/anddev/andengine/entity/scene/menu/animator/AlphaMenuAnimator.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayer.java.i +data/src/org/anddev/andengine/opengl/text/Glyph.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMap.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseDoubleValueSpanModifier.java.i +data/src/org/anddev/andengine/engine/camera/ZoomCamera.java.i +data/src/org/anddev/andengine/entity/modifier/PathModifier.java.i +data/src/org/anddev/andengine/entity/IUpdateHandler.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectProperty.java.i +data/src/org/anddev/andengine/util/path/Path.java.i +data/src/org/anddev/andengine/engine/camera/ChaseCamera.java.i +data/src/org/anddev/andengine/opengl/texture/region/buffer/BaseTextureRegionBuffer.java.i +data/src/org/anddev/andengine/sensor/location/LocationProviderStatus.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseSineIn.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ArcTextureSourceDecoratorShape.java.i +data/src/org/anddev/andengine/entity/StaticEntity.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTile.java.i +data/src/org/anddev/andengine/entity/particle/modifier/AccelerationInitializer.java.i +data/src/org/anddev/andengine/opengl/view/camera/SmoothCamera.java.i +data/src/org/anddev/andengine/entity/primitive/BaseRectangle.java.i +data/src/org/anddev/andengine/entity/particle/initializer/BaseTripleValueInitializer.java.i +data/src/org/anddev/andengine/entity/scene/popup/TextPopupScene.java.i +data/src/org/anddev/andengine/entity/handler/runnable/RunnableHandler.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuartOut.java.i +data/src/org/anddev/andengine/collision/CollisionChecker.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileSet.java.i +data/src/org/anddev/andengine/ui/dialog/GenericInputDialogBuilder.java.i +data/src/org/anddev/andengine/util/StreamUtils.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseCubicOut.java.i +data/src/org/anddev/andengine/util/HorizontalAlign.java.i +data/src/org/anddev/andengine/entity/sprite/Sprite.java.i +data/src/org/anddev/andengine/entity/util/FrameLengthLogger.java.i +data/src/org/anddev/andengine/opengl/view/camera/Camera.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseBackInOut.java.i +data/src/org/anddev/andengine/entity/particle/ParticleEngine.java.i +data/src/org/anddev/andengine/util/progress/ProgressMonitor.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/decorator/ColorMenuItemDecorator.java.i +data/src/org/anddev/andengine/util/path/astar/IAStarHeuristic.java.i +data/src/org/anddev/andengine/opengl/texture/source/AssetTextureSource.java.i +data/src/org/anddev/andengine/entity/shape/modifier/LoopModifier.java.i +data/src/org/anddev/andengine/entity/primitives/BaseRectangle.java.i +data/src/org/anddev/andengine/entity/util/FrameCountCrasher.java.i +data/src/org/anddev/andengine/ui/activity/BaseGameActivity.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/BaseFromToModifier.java.i +data/src/org/anddev/andengine/entity/sprite/TiledSpriteRenderer.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/RectangleFillTextureSourceDecorator.java.i +data/.project.i +data/src/org/anddev/andengine/util/IMatcher.java.i +data/exportJarToAll.xml.i +data/src/org/anddev/andengine/opengl/font/Size.java.i +data/src/org/anddev/andengine/util/modifier/ease/IEaseFunction.java.i +data/src/org/anddev/andengine/entity/FPSCounter.java.i +data/src/org/anddev/andengine/entity/util/ITouchArea.java.i +data/ant/exportJarToCigaretteLiveWallpaper.xml.i +data/src/org/anddev/andengine/level/LevelParser.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseCircularInOut.java.i +data/src/org/anddev/andengine/opengl/vertex/LineVertexBuffer.java.i +data/src/org/anddev/andengine/entity/modifier/MoveYModifier.java.i +data/src/org/anddev/andengine/audio/BaseAudioManager.java.i +data/src/org/anddev/andengine/engine/FixedFPSEngine.java.i +data/src/org/anddev/andengine/entity/shape/IRenderer.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/decorator/BaseMenuItemDecorator.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuadIn.java.i +data/src/org/anddev/andengine/engine/options/TouchOptions.java.i +data/src/org/anddev/andengine/util/SmartList.java.i +data/src/org/anddev/andengine/entity/particle/initializer/AlphaInitializer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/MoveXModifier.java.i +data/src/org/anddev/andengine/util/constants/ColorConstants.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ITextureSourceDecoratorShape.java.i +data/src/org/anddev/andengine/entity/particle/initializer/BaseSingleValueInitializer.java.i +data/src/org/anddev/andengine/entity/particle/modifier/VelocityModifier.java.i +data/ant/exportJarToBoxFaceStacker.xml.i +data/src/org/anddev/andengine/opengl/vertex/VertexBuffer.java.i +data/src/org/anddev/andengine/entity/particle/modifier/ScaleModifier.java.i +data/src/org/anddev/andengine/collision/RectangularShapeCollisionChecker.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseCubicInOut.java.i +data/src/org/anddev/andengine/opengl/texture/source/ResourceTextureSource.java.i +data/src/org/anddev/andengine/engine/options/resolutionpolicy/FixedResolutionPolicy.java.i +data/test/org/anddev/andengine/util/StringUtilsTest.java.i +data/src/org/anddev/andengine/opengl/texture/ResourceTexture.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseTripleValueSpanModifier.java.i +data/exportJarToAndEngineLiveWallpaper.xml.i +data/src/org/anddev/andengine/util/modifier/BaseSingleValueChangeModifier.java.i +data/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolItem.java.i +data/ant/exportJarToSuperDroid.xml.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/TMXConstants.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXException.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseBounceInOut.java.i +data/exportJarToHeliTaxi.xml.i +data/src/org/anddev/andengine/entity/particle/initializer/BaseDoubleValueInitializer.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuartIn.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/TextureRegionBuffer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/DurationShapeModifier.java.i +data/src/org/anddev/andengine/entity/text/TextRenderer.java.i +data/src/org/anddev/andengine/entity/menu/IOnMenuItemClickerListener.java.i +data/src/org/anddev/andengine/sensor/orientation/OrientationSensorOptions.java.i +data/src/org/anddev/andengine/entity/particle/initializer/VelocityInitializer.java.i +data/src/org/anddev/andengine/entity/ScreenCapture.java.i +data/src/org/anddev/andengine/entity/scene/background/RepeatingSpriteBackground.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/ScaleTextMenuItem.java.i +data/src/org/anddev/andengine/entity/shape/modifier/RotateModifier.java.i +data/src/org/anddev/andengine/entity/layer/ILayer.java.i +data/src/org/anddev/andengine/entity/BaseEntity.java.i +data/src/org/anddev/andengine/entity/modifier/SequenceEntityModifier.java.i +data/src/org/anddev/andengine/entity/text/ChangeableText.java.i +data/src/org/anddev/andengine/engine/DoubleSceneSplitScreenEngine.java.i +data/src/org/anddev/andengine/engine/SingleSceneSplitScreenEngine.java.i +data/src/org/anddev/andengine/entity/particle/IParticleModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseCircularInOut.java.i +data/src/org/anddev/andengine/entity/scene/background/modifier/LoopBackgroundModifier.java.i +data/src/org/anddev/andengine/entity/modifier/RotationModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseCubicInOut.java.i +data/src/org/anddev/andengine/engine/SplitScreenEngineOptions.java.i +data/src/org/anddev/andengine/util/modifier/BaseSingleValueSpanModifier.java.i +data/src/org/anddev/andengine/audio/IAudioManager.java.i +data/src/org/anddev/andengine/opengl/view/SimpleEGLConfigChooser.java.i +data/src/org/anddev/andengine/entity/particle/initializer/GravityInitializer.java.i +data/src/org/anddev/andengine/sensor/accelerometer/IAccelerometerListener.java.i +data/exportJarToSpaceTaxi.xml.i +data/ext/img/logo.svg.i +data/src/org/anddev/andengine/entity/particle/initializer/ColorInitializer.java.i +data/src/org/anddev/andengine/entity/particle/modifier/GravityInitializer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuartIn.java.i +data/src/org/anddev/andengine/opengl/texture/TextureRegionFactory.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseBounceIn.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLoader.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXLoadException.java.i +data/src/org/anddev/andengine/util/FileUtils.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/EllipseTextureSourceDecoratorShape.java.i +data/src/org/anddev/andengine/opengl/texture/source/ITextureSource.java.i +data/src/org/anddev/andengine/opengl/buffer/BufferObjectManager.java.i +data/src/org/anddev/andengine/entity/particle/modifier/VelocityInitializer.java.i +data/src/org/anddev/andengine/engine/handler/BaseEntityUpdateHandler.java.i +data/src/org/anddev/andengine/opengl/vertex/TextVertexBuffer.java.i +data/src/org/anddev/andengine/util/path/ITiledMap.java.i +data/src/org/anddev/andengine/engine/camera/BoundCamera.java.i +data/src/org/anddev/andengine/entity/particle/initializer/IParticleInitializer.java.i +data/src/org/anddev/andengine/entity/particle/ParticleSystem.java.i +data/src/org/anddev/andengine/entity/particle/modifier/AlphaModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseCircularIn.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/AlphaModifier.java.i +data/src/org/anddev/andengine/entity/handler/timer/TimerHandler.java.i +data/src/org/anddev/andengine/audio/music/Music.java.i +data/ant/exportJarToAndEngineLiveWallpaper.xml.i +data/src/org/anddev/andengine/entity/FrameCounter.java.i +data/src/org/anddev/andengine/entity/shape/Shape.java.i +data/src/org/anddev/andengine/util/Transformation.java.i +data/src/org/anddev/andengine/input/touch/controller/MultiTouchControler.java.i +data/ext/img/badge.svg.i +data/src/org/anddev/andengine/entity/particle/modifier/AlphaInitializer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseShapeModifier.java.i +data/src/org/anddev/andengine/util/pool/Pool.java.i +data/src/org/anddev/andengine/entity/text/TickerText.java.i +data/src/org/anddev/andengine/entity/particle/emitter/CircleParticleEmitter.java.i +data/src/org/anddev/andengine/sensor/accelerometer/AccelerometerData.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/BaseModifier.java.i +data/src/org/anddev/andengine/entity/shape/IModifierListener.java.i +data/ext/img/icon.svg.i +data/src/org/anddev/andengine/entity/shape/modifier/MoveModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseCubicOut.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/TiledTextureBuffer.java.i +data/src/org/anddev/andengine/entity/BaseStaticEntity.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/ColorKeyTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/sprite/ISpriteModifier.java.i +data/src/org/anddev/andengine/engine/camera/hud/HUD.java.i +data/src/org/anddev/andengine/util/constants/MathConstants.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/ITMXTilePropertiesListener.java.i +data/src/org/anddev/andengine/input/touch/ITouchArea.java.i +data/src/org/anddev/andengine/engine/options/WakeLockOptions.java.i +data/src/org/anddev/andengine/opengl/texture/source/OutlineTextureSourceDecorator.java.i +data/src/org/anddev/andengine/util/UserTask.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/RectangleLinearGradientFillTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/scene/SplashScene.java.i +data/src/org/anddev/andengine/util/SystemUtils.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/BaseTextureBuffer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseLinear.java.i +data/src/org/anddev/andengine/engine/options/resolutionpolicy/FillResolutionPolicy.java.i +data/src/org/anddev/andengine/entity/Layer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ScaleModifier.java.i +data/src/org/anddev/andengine/entity/handler/timer/ITimerCallback.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/FillTextureSourceDecorator.java.i +data/src/org/anddev/andengine/input/touch/IOnSceneTouchListener.java.i +data/exportJarToAndEngineExamples.xml.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseShapeDurationModifier.java.i +data/src/org/anddev/andengine/engine/handler/timer/TimerHandler.java.i +data/src/org/anddev/andengine/entity/modifier/EntityModifierList.java.i +data/src/org/anddev/andengine/util/Base64.java.i +data/src/org/anddev/andengine/util/SimplePreferences.java.i +data/src/org/anddev/andengine/util/sort/InsertionSorter.java.i +data/src/org/anddev/andengine/engine/options/SplitScreenEngineOptions.java.i +data/src/org/anddev/andengine/util/path/IPathFinder.java.i +data/src/org/anddev/andengine/audio/sound/SoundFactory.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseCubicIn.java.i +data/ext/img/index.html.i +data/src/org/anddev/andengine/opengl/texture/source/TextureSourceDecorator.java.i +data/src/org/anddev/andengine/opengl/texture/region/TextureRegion.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ShapeModifier.java.i +data/src/org/anddev/andengine/entity/primitive/RectangularShape.java.i +data/src/org/anddev/andengine/physics/DynamicPhysicsBody.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseDoubleValueSpanModifier.java.i +data/src/org/anddev/andengine/opengl/IRenderHandler.java.i +data/.classpath.i +data/src/org/anddev/andengine/sensor/accelerometer/AccelerometerListener.java.i +data/src/org/anddev/andengine/engine/FixedStepEngine.java.i +data/build_hudson.xml.i +data/src/org/anddev/andengine/entity/modifier/MoveXModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseChangeModifier.java.i +data/src/org/anddev/andengine/entity/sprite/IModifierListener.java.i +data/src/org/anddev/andengine/engine/handler/timer/ITimerCallback.java.i +data/src/org/anddev/andengine/engine/EngineHook.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseExponentialInOut.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseExponentialOut.java.i +data/src/org/anddev/andengine/collision/LineCollisionChecker.java.i +data/src/org/anddev/andengine/opengl/texture/Texture.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/CircleFillTextureSourceDecorator.java.i +data/src/org/anddev/andengine/util/modifier/BaseDurationModifier.java.i +data/src/org/anddev/andengine/engine/options/FixedFPSEngineOptions.java.i +data/src/org/anddev/andengine/engine/LimitedFPSEngine.java.i +data/src/org/anddev/andengine/physics/IPhysicsSpace.java.i +data/src/org/anddev/andengine/engine/handler/collision/CollisionHandler.java.i +data/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolUpdateHandler.java.i +data/ant/exportJarToLavaLampLiveWallpaper.xml.i +data/src/org/anddev/andengine/entity/modifier/TripleValueSpanShapeModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseBounceIn.java.i +data/src/org/anddev/andengine/input/touch/detector/SurfaceScrollDetector.java.i +data/ext/img/source.png.i +data/src/org/anddev/andengine/ui/activity/LayoutGameActivity.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/AnimatedSpriteMenuItem.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseElasticOut.java.i +data/src/org/anddev/andengine/entity/shape/modifier/RotationAtModifier.java.i +data/src/org/anddev/andengine/input/touch/TouchEvent.java.i +data/src/org/anddev/andengine/entity/particle/modifier/RotateModifier.java.i +data/src/org/anddev/andengine/input/touch/controller/SingleTouchControler.java.i +data/src/org/anddev/andengine/audio/IAudioEntity.java.i +data/src/org/anddev/andengine/opengl/util/FastFloatBuffer.java.i +data/ant/exportJarToHeliTaxiShared.xml.i +data/src/org/anddev/andengine/engine/SmoothEngine.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuintOut.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseBounceOut.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileProperty.java.i +data/src/org/anddev/andengine/opengl/texture/region/TiledTextureRegion.java.i +data/src/org/anddev/andengine/entity/background/BaseBackground.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObject.java.i +data/src/org/anddev/andengine/sensor/SensorDelay.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/BaseShapeTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/particle/modifier/RotateInitialize.java.i +data/src/org/anddev/andengine/entity/scene/menu/animator/SlideMenuAnimator.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseCircularOut.java.i +data/src/org/anddev/andengine/audio/sound/SoundManager.java.i +data/src/org/anddev/andengine/entity/particle/modifier/RotationModifier.java.i +data/src/org/anddev/andengine/input/touch/detector/ClickDetector.java.i +data/src/org/anddev/andengine/entity/particle/modifier/ColorModifier.java.i +data/src/org/anddev/andengine/audio/music/MusicManager.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseElasticIn.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/TextureBuffer.java.i +data/src/org/anddev/andengine/opengl/texture/builder/ITextureBuilder.java.i +data/default.properties.i +data/src/org/anddev/andengine/audio/music/MusicFactory.java.i +data/src/org/anddev/andengine/physics/StaticPhysicsBody.java.i +data/src/org/anddev/andengine/opengl/text/Font.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuadInOut.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuadOut.java.i +data/src/org/anddev/andengine/entity/sprite/BaseSprite.java.i +data/src/org/anddev/andengine/opengl/texture/TextureFactory.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RoundedRectangleTextureSourceDecoratorShape.java.i +data/src/org/anddev/andengine/util/SocketUtils.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperties.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/OutlineTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXLoader.java.i +data/src/org/anddev/andengine/input/touch/IOnAreaTouchListener.java.i +data/src/org/anddev/andengine/util/ColorUtils.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/decorator/ScaleMenuItemDecorator.java.i +data/src/org/anddev/andengine/entity/particle/modifier/GravityModifier.java.i +data/src/org/anddev/andengine/input/touch/detector/HoldDetector.java.i +data/src/org/anddev/andengine/opengl/IDrawable.java.i +data/src/org/anddev/andengine/entity/UpdateHandlerList.java.i +data/src/org/anddev/andengine/entity/shape/modifier/AlphaModifier.java.i +data/src/org/anddev/andengine/util/modifier/BaseTripleValueSpanModifier.java.i +data/src/org/anddev/andengine/util/modifier/ParallelModifier.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseDoubleValueInitializer.java.i +data/src/org/anddev/andengine/entity/scene/transition/FadeTransitionScene.java.i +data/src/org/anddev/andengine/util/modifier/IModifier.java.i +data/uml/andengine_classdiagram.ucls.i +data/src/org/anddev/andengine/util/pool/GenericPool.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/BasePairFromToModifier.java.i +data/src/org/anddev/andengine/opengl/texture/factory/TextureRegionFactory.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseElasticIn.java.i +data/src/org/anddev/andengine/entity/group/TransformationGroup.java.i +data/src/org/anddev/andengine/entity/util/FPSLogger.java.i +data/ant/exportJarToHighRise.xml.i +data/src/org/anddev/andengine/util/Library.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/BaseTextureSourceDecorator.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseBounceOut.java.i +data/src/org/anddev/andengine/util/path/astar/AStarPathFinder.java.i +data/src/org/anddev/andengine/util/pool/PoolUpdateHandler.java.i +data/src/org/anddev/andengine/engine/options/resolutionpolicy/RelativeResolutionPolicy.java.i +data/ext/img/badge.png.i +data/src/org/anddev/andengine/entity/particle/emitter/BaseRectangleParticleEmitter.java.i +data/src/org/anddev/andengine/entity/primitives/Rectangle.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayerProperty.java.i +data/src/org/anddev/andengine/entity/modifier/ScaleModifier.java.i +data/src/org/anddev/andengine/entity/scene/menu/animator/DirectMenuAnimator.java.i +data/src/org/anddev/andengine/engine/camera/hud/controls/AnalogOnScreenControl.java.i +data/src/org/anddev/andengine/engine/handler/collision/ICollisionCallback.java.i +data/src/org/anddev/andengine/input/touch/detector/SurfaceGestureDetector.java.i +data/src/org/anddev/andengine/entity/particle/emitter/BaseParticleEmitter.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/IEaseFunction.java.i +data/ext/img/favicon.png.i +data/src/org/anddev/andengine/opengl/texture/TiledTexture.java.i +data/src/org/anddev/andengine/util/cache/RectangleVertexBufferCache.java.i +data/src/org/anddev/andengine/opengl/texture/region/TextureRegionLibrary.java.i +data/src/org/anddev/andengine/opengl/texture/factory/TextureFactory.java.i +data/ant/exportJarToHeliTaxiLiveWallpaper.xml.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/RadialGradientFillTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ParallelShapeModifier.java.i +data/src/org/anddev/andengine/util/path/astar/NullHeuristic.java.i +data/src/org/anddev/andengine/entity/particle/emitter/BaseCircleParticleEmitter.java.i +data/src/org/anddev/andengine/entity/scene/background/EntityBackground.java.i +data/src/org/anddev/andengine/entity/modifier/RotationAtModifier.java.i +data/src/org/anddev/andengine/util/MultiKey.java.i +data/src/org/anddev/andengine/util/DataUtils.java.i +data/src/org/anddev/andengine/util/path/Direction.java.i +data/src/org/anddev/andengine/entity/scene/transition/BaseTransitionScene.java.i +data/src/org/anddev/andengine/opengl/view/GLWrapper.java.i +data/src/org/anddev/andengine/entity/sprite/SpriteRenderer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuadInOut.java.i +data/src/org/anddev/andengine/entity/background/FixedColorBackground.java.i +data/src/org/anddev/andengine/entity/scene/background/modifier/ParallelBackgroundModifier.java.i +data/src/org/anddev/andengine/entity/IEntity.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseBounceInOut.java.i +data/AndroidManifest.xml.i +data/src/org/anddev/andengine/entity/modifier/FadeOutModifier.java.i +data/lib/libProgressMonitor.jar.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseBackIn.java.i +data/src/org/anddev/andengine/entity/scene/popup/PopupScene.java.i +data/src/org/anddev/andengine/entity/shape/GLShape.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseCircularIn.java.i +data/src/org/anddev/andengine/entity/modifier/ParallelEntityModifier.java.i +data/hudson_build.xml.i +data/src/org/anddev/andengine/entity/shape/modifier/ColorModifier.java.i +data/src/org/anddev/andengine/engine/UpdateHandlerList.java.i +data/src/org/anddev/andengine/entity/SplashScene.java.i +data/src/org/anddev/andengine/entity/ISceneTouchListener.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseModifier.java.i +data/src/org/anddev/andengine/entity/primitive/Line.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseTripleValueInitializer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/RotateByModifier.java.i +data/src/org/anddev/andengine/sensor/orientation/OrientationData.java.i +data/exportJarToHeliTaxiLiveWallpaper.xml.i +data/src/org/anddev/andengine/entity/scene/background/modifier/ColorModifier.java.i +data/src/org/anddev/andengine/entity/menu/MenuScene.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/ColorTextMenuItem.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuintIn.java.i +data/src/org/anddev/andengine/engine/camera/CameraFactory.java.i +data/src/org/anddev/andengine/util/Callback.java.i +data/src/org/anddev/andengine/entity/shape/modifier/PathModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ScaleAtModifier.java.i +data/src/org/anddev/andengine/util/ActivityUtils.java.i +data/src/org/anddev/andengine/entity/shape/RectangleRenderer.java.i +data/src/org/anddev/andengine/engine/options/resolutionpolicy/BaseResolutionPolicy.java.i +data/ext/img/splash.png.i +data/src/org/anddev/andengine/entity/layer/DynamicCapacityLayer.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/RotateModifier.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/TextMenuItem.java.i +data/src/org/anddev/andengine/entity/shape/modifier/IShapeModifier.java.i +data/src/org/anddev/andengine/entity/IDynamicEntity.java.i +data/src/org/anddev/andengine/entity/modifier/ScaleAtModifier.java.i +data/src/org/anddev/andengine/util/BetaUtils.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseTripleValueSpanModifier.java.i +data/src/org/anddev/andengine/engine/options/FixedStepEngineOptions.java.i +data/src/org/anddev/andengine/entity/particle/modifier/AccelerationModifier.java.i +data/src/org/anddev/andengine/util/progress/IProgressListener.java.i +data/src/org/anddev/andengine/engine/handler/physics/PhysicsHandler.java.i +data/src/org/anddev/andengine/entity/modifier/AlphaModifier.java.i +data/src/org/anddev/andengine/sensor/location/LocationSensorOptions.java.i +data/src/org/anddev/andengine/util/pool/RunnablePoolItem.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/BaseTextureRegionBuffer.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXParseException.java.i +data/src/org/anddev/andengine/opengl/texture/region/TextureRegionFactory.java.i +data/src/org/anddev/andengine/entity/modifier/IEntityModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseStrongIn.java.i +data/src/org/anddev/andengine/entity/shape/BaseRenderer.java.i +data/src/org/anddev/andengine/input/touch/controller/BaseTouchController.java.i +data/src/org/anddev/andengine/engine/handler/UpdateHandlerList.java.i +data/src/org/anddev/andengine/opengl/texture/source/FileTextureSource.java.i +data/src/org/anddev/andengine/entity/shape/RectangularShape.java.i +data/src/org/anddev/andengine/opengl/texture/FontManager.java.i +data/src/org/anddev/andengine/opengl/texture/TextureAtlas.java.i +data/src/org/anddev/andengine/opengl/texture/TextureManager.java.i +data/src/org/anddev/andengine/entity/util/ScreenCapture.java.i +data/src/org/anddev/andengine/opengl/GLHelper.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseSineIn.java.i +data/src/org/anddev/andengine/opengl/font/Letter.java.i +data/src/org/anddev/andengine/util/path/astar/ManhattanHeuristic.java.i +data/src/org/anddev/andengine/entity/shape/modifier/DoubleValueSpanShapeModifier.java.i +data/ant/exportJarToCampfireLiveWallpaper.xml.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseBackInOut.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/DelayModifier.java.i +data/src/org/anddev/andengine/engine/options/resolutionpolicy/IResolutionPolicy.java.i +data/src/org/anddev/andengine/entity/particle/initializer/AccelerationInitializer.java.i +data/src/org/anddev/andengine/util/ProbabilityGenerator.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BasePairInitializeModifier.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuartInOut.java.i +data/src/org/anddev/andengine/engine/camera/SmoothCamera.java.i +data/src/org/anddev/andengine/entity/shape/modifier/util/ShapeModifierUtils.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseBackOut.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXParseException.java.i +data/src/org/anddev/andengine/entity/sprite/AnimatedSprite.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXParser.java.i +data/src/org/anddev/andengine/entity/particle/modifier/RotateInitializer.java.i +data/ext/img/clapboard.png.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseCircularOut.java.i +data/src/org/anddev/andengine/util/modifier/ModifierList.java.i +data/src/org/anddev/andengine/entity/shape/modifier/FadeOutModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseSineInOut.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/CircleOutlineTextureSourceDecorator.java.i +data/exportJarToHeliTaxiShared.xml.i +data/src/org/anddev/andengine/entity/shape/modifier/TripleValueSpanShapeModifier.java.i +data/ext/img/logo2.png.i +data/src/org/anddev/andengine/entity/modifier/DoubleValueSpanShapeModifier.java.i +data/src/org/anddev/andengine/physics/PhysicsShape.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuadIn.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXLoadException.java.i +data/src/org/anddev/andengine/util/ViewUtils.java.i +data/src/org/anddev/andengine/opengl/texture/source/ColorKeyTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/layer/FixedCapacityLayer.java.i +data/src/org/anddev/andengine/entity/scene/menu/item/SpriteMenuItem.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuintIn.java.i +data/src/org/anddev/andengine/opengl/texture/AssetTexture.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseSineOut.java.i +data/src/org/anddev/andengine/util/StringUtils.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/CircleTextureSourceDecoratorShape.java.i +data/src/org/anddev/andengine/entity/util/IOnAreaTouchListener.java.i +data/src/org/anddev/andengine/entity/scene/background/SpriteBackground.java.i +data/src/org/anddev/andengine/entity/shape/modifier/LoopShapeModifier.java.i +data/src/org/anddev/andengine/opengl/vertex/RectangleVertexBuffer.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseElasticInOut.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseLinear.java.i +data/src/org/anddev/andengine/opengl/text/Size.java.i +data/src/org/anddev/andengine/opengl/texture/source/packing/BlackPawnTextureSourcePackingAlgorithm.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseElasticInOut.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ParallelModifier.java.i +data/src/org/anddev/andengine/entity/modifier/RotationByModifier.java.i +data/src/org/anddev/andengine/level/LevelLoader.java.i +data/src/org/anddev/andengine/entity/Scene.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseStrongOut.java.i +data/src/org/anddev/andengine/util/TimeUtils.java.i +data/src/org/anddev/andengine/entity/scene/menu/MenuScene.java.i +data/src/org/anddev/andengine/util/ArrayUtils.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/TiledTextureRegionBuffer.java.i +data/src/org/anddev/andengine/entity/menu/animator/BaseMenuAnimator.java.i +data/src/org/anddev/andengine/engine/camera/SmoothChaseCamera.java.i +data/src/org/anddev/andengine/entity/handler/collision/CollisionHandler.java.i +data/src/org/anddev/andengine/entity/particle/emitter/PointParticleEmitter.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuintInOut.java.i +data/src/org/anddev/andengine/ui/IGameInterface.java.i +data/src/org/anddev/andengine/util/AsyncCallable.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseStrongOut.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseExponentialIn.java.i +data/src/org/anddev/andengine/entity/shape/IShape.java.i +data/src/org/anddev/andengine/entity/scene/background/ColorBackground.java.i +data/src/org/anddev/andengine/input/touch/detector/BaseDetector.java.i +data/src/org/anddev/andengine/engine/IUpdateHandler.java.i +data/src/org/anddev/andengine/entity/menu/animator/SlideMenuAnimator.java.i +data/ext/img/source.svg.i +data/src/org/anddev/andengine/util/constants/MIMETypes.java.i +data/src/org/anddev/andengine/entity/modifier/LoopEntityModifier.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMapProperty.java.i +data/src/org/anddev/andengine/opengl/util/GLHelper.java.i +data/src/org/anddev/andengine/entity/layer/Layer.java.i +data/src/org/anddev/andengine/opengl/view/RenderSurfaceView.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseQuartInOut.java.i +data/src/org/anddev/andengine/opengl/texture/source/packing/ITextureSourcePackingAlgorithm.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseElasticOut.java.i +data/src/org/anddev/andengine/entity/scene/background/IBackground.java.i +data/src/org/anddev/andengine/entity/scene/menu/animator/IMenuAnimator.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/TextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/modifier/SingleValueChangeShapeModifier.java.i +data/src/org/anddev/andengine/entity/Entity.java.i +data/src/org/anddev/andengine/audio/BaseAudioEntity.java.i +data/ext/img/clapboard.svg.i +data/ant/exportJarToAndEngineExamples.xml.i +data/src/org/anddev/andengine/opengl/text/Letter.java.i +data/src/org/anddev/andengine/opengl/font/StrokeFont.java.i +data/src/org/anddev/andengine/entity/BaseDynamicEntity.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuartOut.java.i +data/src/org/anddev/andengine/opengl/texture/buffer/TextTextureBuffer.java.i +data/src/org/anddev/andengine/entity/DynamicEntity.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseExponentialIn.java.i +data/src/org/anddev/andengine/opengl/font/FontManager.java.i +data/src/org/anddev/andengine/opengl/IRenderable.java.i +data/src/org/anddev/andengine/entity/shape/modifier/SequenceShapeModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/SingleValueChangeShapeModifier.java.i +data/src/org/anddev/andengine/entity/primitive/Rectangle.java.i +data/src/org/anddev/andengine/game/BaseGameActivity.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/LinearGradientFillTextureSourceDecorator.java.i +data/src/org/anddev/andengine/entity/shape/modifier/SequenceModifier.java.i +data/src/org/anddev/andengine/util/constants/TimeConstants.java.i +data/src/org/anddev/andengine/entity/menu/MenuItem.java.i +data/src/org/anddev/andengine/opengl/texture/TextureBuffer.java.i +data/src/org/anddev/andengine/sensor/orientation/IOrientationListener.java.i +data/src/org/anddev/andengine/entity/modifier/DelayModifier.java.i +data/src/org/anddev/andengine/entity/IBaseEntity.java.i +data/src/org/anddev/andengine/physics/BasePhysicsBody.java.i +data/src/org/anddev/andengine/entity/scene/CameraScene.java.i +data/src/org/anddev/andengine/entity/primitives/RectangularShape.java.i +data/src/org/anddev/andengine/entity/shape/modifier/DelayModifier.java.i +data/src/org/anddev/andengine/entity/IOnSceneTouchListener.java.i +data/src/org/anddev/andengine/ui/activity/BaseSplashActivity.java.i +data/src/org/anddev/andengine/entity/util/FrameCounter.java.i +data/src/org/anddev/andengine/engine/ISceneTouchListener.java.i +data/src/org/anddev/andengine/util/SAXUtils.java.i +data/src/org/anddev/andengine/util/ParameterCallable.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseSineInOut.java.i +data/src/org/anddev/andengine/opengl/buffer/BaseBuffer.java.i +data/src/org/anddev/andengine/entity/shape/util/ShapeUtils.java.i +data/src/org/anddev/andengine/entity/particle/modifier/IParticleModifier.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseCubicIn.java.i +data/src/org/anddev/andengine/engine/SplitScreenEngine.java.i +data/src/org/anddev/andengine/opengl/buffer/BufferObject.java.i +data/src/org/anddev/andengine/opengl/texture/BuildableTexture.java.i +data/src/org/anddev/andengine/opengl/BaseBuffer.java.i +data/src/org/anddev/andengine/entity/util/IOnSceneTouchListener.java.i +data/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RectangleTextureSourceDecoratorShape.java.i +data/src/org/anddev/andengine/entity/modifier/EntityModifier.java.i +data/src/org/anddev/andengine/entity/shape/IShapeModifier.java.i +data/src/org/anddev/andengine/engine/EngineOptions.java.i +data/src/org/anddev/andengine/util/modifier/BaseModifier.java.i +data/src/org/anddev/andengine/entity/menu/IOnMenuItemClickListener.java.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXParser.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseSingleValueInitializer.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseInitializer.java.i +data/ext/img/logo_icon.svg.i +data/src/org/anddev/andengine/engine/options/EngineOptions.java.i +data/ext/img/android.svg.i +data/src/org/anddev/andengine/entity/CameraScene.java.i +data/src/org/anddev/andengine/entity/SceneWithChild.java.i +data/src/org/anddev/andengine/physics/collision/Intersector.java.i +data/ext/img/favicon.svg.i +data/src/org/anddev/andengine/entity/modifier/FadeInModifier.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/ScaleModifier.java.i +data/src/org/anddev/andengine/engine/Engine.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseFromToModifier.java.i +data/src/org/anddev/andengine/entity/sprite/modifier/RotateByModifier.java.i +data/src/org/anddev/andengine/util/pool/RunnablePoolUpdateHandler.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseSingleValueSpanModifier.java.i +data/src/org/anddev/andengine/entity/scene/Scene.java.i +data/src/org/anddev/andengine/opengl/texture/ITextureStateListener.java.i +data/src/org/anddev/andengine/entity/primitives/Line.java.i +data/src/org/anddev/andengine/entity/scene/background/modifier/SequenceBackgroundModifier.java.i +data/src/org/anddev/andengine/entity/particle/modifier/BaseSingleValueSpanModifier.java.i +data/src/org/anddev/andengine/util/IEntityMatcher.java.i +data/src/org/anddev/andengine/entity/particle/emitter/RectangleParticleEmitter.java.i +data/src/org/anddev/andengine/physics/collision/CollisionChecker.java.i +data/src/org/anddev/andengine/opengl/view/GLSurfaceView.java.i +data/src/org/anddev/andengine/entity/modifier/DurationShapeModifier.java.i +data/src/org/anddev/andengine/entity/sprite/IModificationListener.java.i +data/src/org/anddev/andengine/util/modifier/ease/EaseQuintInOut.java.i +data/src/org/anddev/andengine/opengl/view/ComponentSizeChooser.java.i +data/src/org/anddev/andengine/util/pool/PoolItem.java.i +data/src/org/anddev/andengine/entity/shape/modifier/ease/EaseExponentialInOut.java.i +data/src/org/anddev/andengine/entity/particle/modifier/ColorInitializer.java.i +data/src/org/anddev/andengine/opengl/texture/region/buffer/TiledTextureRegionBuffer.java.i +data/src/org/anddev/andengine/util/pool/MultiPool.java.i +data/src/org/anddev/andengine/opengl/font/FontLibrary.java.i +data/src/org/anddev/andengine/audio/sound/Sound.java.i +data/src/org/anddev/andengine/util/Callable.java.i +data/src/org/anddev/andengine/opengl/texture/source/EmptyBitmapTextureSource.java.i +data/src/org/anddev/andengine/engine/options/RenderHints.java.i +data/src/org/anddev/andengine/util/constants/Constants.java.i +data/src/org/anddev/andengine/entity/shape/modifier/IShapeModifierListener.java.i +data/src/org/anddev/andengine/engine/options/resolutionpolicy/RatioResolutionPolicy.java.i +data/src/org/anddev/andengine/input/touch/detector/ScrollDetector.java.i +data/src/org/anddev/andengine/util/pool/EntityRemoveRunnablePoolItem.java.i +data/src/org/anddev/andengine/util/sort/Sorter.java.i +data/uml/andengine_classdiagram.png.i +data/src/org/anddev/andengine/entity/particle/Particle.java.i +data/ext/img/logo3.png.i +data/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperty.java.i +data/src/org/anddev/andengine/entity/particle/emitter/CircleOutlineParticleEmitter.java.i +data/src/org/anddev/andengine/entity/shape/modifier/RotationModifier.java.i +data/src/org/anddev/andengine/ui/dialog/StringInputDialogBuilder.java.i +data/src/org/anddev/andengine/opengl/texture/TextureOptions.java.i +data/src/org/anddev/andengine/entity/layer/ZIndexSorter.java.i +data/src/org/anddev/andengine/entity/menu/IMenuAnimator.java.i +data/.hgignore.i +data/src/org/anddev/andengine/audio/sound/SoundLibrary.java.i +data/src/org/anddev/andengine/entity/particle/IParticleInitializer.java.i +data/src/org/anddev/andengine/util/Debug.java.i +data/push_google_code.bat.i +data/src/org/anddev/andengine/entity/particle/modifier/IParticleInitializer.java.i +data/src/org/anddev/andengine/entity/shape/modifier/BaseFromToModifier.java.i diff --git a/AndEngine/.hg/store/undo b/AndEngine/.hg/store/undo new file mode 100644 index 0000000..ca88939 Binary files /dev/null and b/AndEngine/.hg/store/undo differ diff --git a/AndEngine/.hg/undo.branch b/AndEngine/.hg/undo.branch new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/AndEngine/.hg/undo.branch @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/AndEngine/.hg/undo.desc b/AndEngine/.hg/undo.desc new file mode 100644 index 0000000..6616a99 --- /dev/null +++ b/AndEngine/.hg/undo.desc @@ -0,0 +1,3 @@ +0 +pull +https://andengine.googlecode.com/hg/ diff --git a/AndEngine/.hg/undo.dirstate b/AndEngine/.hg/undo.dirstate new file mode 100644 index 0000000..e69de29 diff --git a/AndEngine/.hgignore b/AndEngine/.hgignore new file mode 100644 index 0000000..57ac22e --- /dev/null +++ b/AndEngine/.hgignore @@ -0,0 +1,5 @@ +syntax: glob +bin/** +doc/** +.DS_Store +Thumbs.db diff --git a/AndEngine/.project b/AndEngine/.project new file mode 100644 index 0000000..71aabc2 --- /dev/null +++ b/AndEngine/.project @@ -0,0 +1,33 @@ + + + AndEngine + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/AndEngine/AndroidManifest.xml b/AndEngine/AndroidManifest.xml new file mode 100644 index 0000000..cf91295 --- /dev/null +++ b/AndEngine/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/AndEngine/default.properties b/AndEngine/default.properties new file mode 100644 index 0000000..7334714 --- /dev/null +++ b/AndEngine/default.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Indicates whether an apk should be generated for each density. +split.density=false +# Project target. +target=android-4 +android.library=true diff --git a/AndEngine/exportJarToAll.xml b/AndEngine/exportJarToAll.xml new file mode 100644 index 0000000..c3e2cda --- /dev/null +++ b/AndEngine/exportJarToAll.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${targetfile} + + + + + + + + + + diff --git a/AndEngine/ext/img/android.svg b/AndEngine/ext/img/android.svg new file mode 100644 index 0000000..a4d446b --- /dev/null +++ b/AndEngine/ext/img/android.svg @@ -0,0 +1,32 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AndEngine/ext/img/badge.png b/AndEngine/ext/img/badge.png new file mode 100644 index 0000000..70ce156 Binary files /dev/null and b/AndEngine/ext/img/badge.png differ diff --git a/AndEngine/ext/img/badge.svg b/AndEngine/ext/img/badge.svg new file mode 100644 index 0000000..51ab148 --- /dev/null +++ b/AndEngine/ext/img/badge.svg @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + andengine + + + + + + + + + + + + + diff --git a/AndEngine/ext/img/clapboard.png b/AndEngine/ext/img/clapboard.png new file mode 100644 index 0000000..3f55c7e Binary files /dev/null and b/AndEngine/ext/img/clapboard.png differ diff --git a/AndEngine/ext/img/clapboard.svg b/AndEngine/ext/img/clapboard.svg new file mode 100644 index 0000000..e5d0225 --- /dev/null +++ b/AndEngine/ext/img/clapboard.svg @@ -0,0 +1,547 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + clapper + 04-25-2007 + + + David Niezbitowski + + + + + David Niezabitowski + + + Inkscape .45.1 + + + clapper + movie + filmmaking + director + film + tv + movies + entertainment + slate + scene + marker + + + Scene Slate + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SCENE + TAKE + ROLL + TITLE + PRODUCER + DIRECTOR + + diff --git a/AndEngine/ext/img/favicon.png b/AndEngine/ext/img/favicon.png new file mode 100644 index 0000000..74fa83b Binary files /dev/null and b/AndEngine/ext/img/favicon.png differ diff --git a/AndEngine/ext/img/favicon.svg b/AndEngine/ext/img/favicon.svg new file mode 100644 index 0000000..c6a4713 --- /dev/null +++ b/AndEngine/ext/img/favicon.svg @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/AndEngine/ext/img/icon.svg b/AndEngine/ext/img/icon.svg new file mode 100644 index 0000000..cf58fcd --- /dev/null +++ b/AndEngine/ext/img/icon.svg @@ -0,0 +1,404 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AndEngine/ext/img/logo.png b/AndEngine/ext/img/logo.png new file mode 100644 index 0000000..df06990 Binary files /dev/null and b/AndEngine/ext/img/logo.png differ diff --git a/AndEngine/ext/img/logo.svg b/AndEngine/ext/img/logo.svg new file mode 100644 index 0000000..ea58b3c --- /dev/null +++ b/AndEngine/ext/img/logo.svg @@ -0,0 +1,2318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + andengine + + + + + + + + + + andengine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FUN + + + + + + + FAST + + + + + + + FREE + + + + + diff --git a/AndEngine/ext/img/logo_icon.svg b/AndEngine/ext/img/logo_icon.svg new file mode 100644 index 0000000..9eba283 --- /dev/null +++ b/AndEngine/ext/img/logo_icon.svg @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + ... coming 2010 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AndEngine/ext/img/source.png b/AndEngine/ext/img/source.png new file mode 100644 index 0000000..663ef73 Binary files /dev/null and b/AndEngine/ext/img/source.png differ diff --git a/AndEngine/ext/img/source.svg b/AndEngine/ext/img/source.svg new file mode 100644 index 0000000..ab2d37c --- /dev/null +++ b/AndEngine/ext/img/source.svg @@ -0,0 +1,2730 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Jakub Steiner + + + http://jimmac.musichall.cz/ + + + package + archive + tarball + tar + bzip + gzip + zip + arj + tar + jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + andengine + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AndEngine/ext/img/splash.png b/AndEngine/ext/img/splash.png new file mode 100644 index 0000000..2570a24 Binary files /dev/null and b/AndEngine/ext/img/splash.png differ diff --git a/AndEngine/ext/img/splash.svg b/AndEngine/ext/img/splash.svg new file mode 100644 index 0000000..19d37d5 --- /dev/null +++ b/AndEngine/ext/img/splash.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + andengine + + + + + + + + + + + + diff --git a/AndEngine/jni/Android.mk b/AndEngine/jni/Android.mk new file mode 100644 index 0000000..4a36649 --- /dev/null +++ b/AndEngine/jni/Android.mk @@ -0,0 +1,101 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := andenginephysicsbox2dextension +LOCAL_ARM_MODE := arm +LOCAL_SRC_FILES := \ +Box2D/Body.cpp \ +Box2D/CircleShape.cpp \ +Box2D/Contact.cpp \ +Box2D/Fixture.cpp \ +Box2D/Joint.cpp \ +Box2D/PolygonShape.cpp \ +Box2D/Shape.cpp \ +Box2D/World.cpp \ +Box2D/Box2D.h \ +Box2D/DistanceJoint.cpp \ +Box2D/FrictionJoint.cpp \ +Box2D/GearJoint.cpp \ +Box2D/LineJoint.cpp \ +Box2D/MouseJoint.cpp \ +Box2D/PrismaticJoint.cpp \ +Box2D/PulleyJoint.cpp \ +Box2D/RevoluteJoint.cpp \ +Box2D/Collision/b2BroadPhase.cpp \ +Box2D/Collision/b2BroadPhase.h \ +Box2D/Collision/b2CollideCircle.cpp \ +Box2D/Collision/b2CollidePolygon.cpp \ +Box2D/Collision/b2Collision.cpp \ +Box2D/Collision/b2Collision.h \ +Box2D/Collision/b2Distance.cpp \ +Box2D/Collision/b2Distance.h \ +Box2D/Collision/b2DynamicTree.cpp \ +Box2D/Collision/b2DynamicTree.h \ +Box2D/Collision/b2TimeOfImpact.cpp \ +Box2D/Collision/b2TimeOfImpact.h \ +Box2D/Collision/Shapes/b2CircleShape.cpp \ +Box2D/Collision/Shapes/b2CircleShape.h \ +Box2D/Collision/Shapes/b2PolygonShape.cpp \ +Box2D/Collision/Shapes/b2PolygonShape.h \ +Box2D/Collision/Shapes/b2Shape.h \ +Box2D/Common/b2BlockAllocator.cpp \ +Box2D/Common/b2BlockAllocator.h \ +Box2D/Common/b2Math.cpp \ +Box2D/Common/b2Math.h \ +Box2D/Common/b2Settings.cpp \ +Box2D/Common/b2Settings.h \ +Box2D/Common/b2StackAllocator.cpp \ +Box2D/Common/b2StackAllocator.h \ +Box2D/Dynamics/b2Body.cpp \ +Box2D/Dynamics/b2Body.h \ +Box2D/Dynamics/b2ContactManager.cpp \ +Box2D/Dynamics/b2ContactManager.h \ +Box2D/Dynamics/b2Fixture.cpp \ +Box2D/Dynamics/b2Fixture.h \ +Box2D/Dynamics/b2Island.cpp \ +Box2D/Dynamics/b2Island.h \ +Box2D/Dynamics/b2TimeStep.h \ +Box2D/Dynamics/b2World.cpp \ +Box2D/Dynamics/b2World.h \ +Box2D/Dynamics/b2WorldCallbacks.cpp \ +Box2D/Dynamics/b2WorldCallbacks.h \ \ +Box2D/Dynamics/Contacts/b2CircleContact.cpp \ +Box2D/Dynamics/Contacts/b2CircleContact.h \ +Box2D/Dynamics/Contacts/b2Contact.cpp \ +Box2D/Dynamics/Contacts/b2Contact.h \ +Box2D/Dynamics/Contacts/b2ContactSolver.cpp \ +Box2D/Dynamics/Contacts/b2ContactSolver.h \ +Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp \ +Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h \ +Box2D/Dynamics/Contacts/b2PolygonContact.cpp \ +Box2D/Dynamics/Contacts/b2PolygonContact.h \ +Box2D/Dynamics/Contacts/b2TOISolver.cpp \ +Box2D/Dynamics/Contacts/b2TOISolver.h \ +Box2D/Dynamics/Joints/b2DistanceJoint.cpp \ +Box2D/Dynamics/Joints/b2DistanceJoint.h \ +Box2D/Dynamics/Joints/b2FrictionJoint.cpp \ +Box2D/Dynamics/Joints/b2FrictionJoint.h \ +Box2D/Dynamics/Joints/b2GearJoint.cpp \ +Box2D/Dynamics/Joints/b2GearJoint.h \ +Box2D/Dynamics/Joints/b2Joint.cpp \ +Box2D/Dynamics/Joints/b2Joint.h \ +Box2D/Dynamics/Joints/b2LineJoint.cpp \ +Box2D/Dynamics/Joints/b2LineJoint.h \ +Box2D/Dynamics/Joints/b2MouseJoint.cpp \ +Box2D/Dynamics/Joints/b2MouseJoint.h \ +Box2D/Dynamics/Joints/b2PrismaticJoint.cpp \ +Box2D/Dynamics/Joints/b2PrismaticJoint.h \ +Box2D/Dynamics/Joints/b2PulleyJoint.cpp \ +Box2D/Dynamics/Joints/b2PulleyJoint.h \ +Box2D/Dynamics/Joints/b2RevoluteJoint.cpp \ +Box2D/Dynamics/Joints/b2RevoluteJoint.h \ +Box2D/Dynamics/Joints/b2WeldJoint.cpp \ +Box2D/Dynamics/Joints/b2WeldJoint.h + + +LOCAL_CFLAGS := -DFIXED_POINT -ffast-math -O3 -Wall -I$(LOCAL_PATH) -D_ARM_ASSEM_ -DANDROID +LOCAL_CPPFLAGS := -DFIXED_POINT -I$LOCAL_PATH/libvorbis/ -D_ARM_ASSEM_ +LOCAL_LDLIBS := -llog + +include $(BUILD_SHARED_LIBRARY) diff --git a/AndEngine/jni/Box2D/Android.mk b/AndEngine/jni/Box2D/Android.mk new file mode 100644 index 0000000..7f7452c --- /dev/null +++ b/AndEngine/jni/Box2D/Android.mk @@ -0,0 +1,53 @@ +GDX_SRC_FILES += Box2D/Body.cpp \ +Box2D/CircleShape.cpp \ +Box2D/Contact.cpp \ +Box2D/Fixture.cpp \ +Box2D/Joint.cpp \ +Box2D/PolygonShape.cpp \ +Box2D/Shape.cpp \ +Box2D/World.cpp \ +Box2D/DistanceJoint.cpp \ +Box2D/FrictionJoint.cpp \ +Box2D/GearJoint.cpp \ +Box2D/LineJoint.cpp \ +Box2D/MouseJoint.cpp \ +Box2D/PrismaticJoint.cpp \ +Box2D/PulleyJoint.cpp \ +Box2D/RevoluteJoint.cpp \ +Box2D/Collision/b2BroadPhase.cpp \ +Box2D/Collision/b2CollideCircle.cpp \ +Box2D/Collision/b2CollidePolygon.cpp \ +Box2D/Collision/b2Collision.cpp \ +Box2D/Collision/b2Distance.cpp \ +Box2D/Collision/b2DynamicTree.cpp \ +Box2D/Collision/b2TimeOfImpact.cpp \ +Box2D/Collision/Shapes/b2CircleShape.cpp \ +Box2D/Collision/Shapes/b2PolygonShape.cpp \ +Box2D/Common/b2BlockAllocator.cpp \ +Box2D/Common/b2Math.cpp \ +Box2D/Common/b2Settings.cpp \ +Box2D/Common/b2StackAllocator.cpp \ +Box2D/Dynamics/b2Body.cpp \ +Box2D/Dynamics/b2ContactManager.cpp \ +Box2D/Dynamics/b2Fixture.cpp \ +Box2D/Dynamics/b2Island.cpp \ +Box2D/Dynamics/b2World.cpp \ +Box2D/Dynamics/b2WorldCallbacks.cpp \ +Box2D/Dynamics/Contacts/b2CircleContact.cpp \ +Box2D/Dynamics/Contacts/b2Contact.cpp \ +Box2D/Dynamics/Contacts/b2ContactSolver.cpp \ +Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp \ +Box2D/Dynamics/Contacts/b2PolygonContact.cpp \ +Box2D/Dynamics/Contacts/b2TOISolver.cpp \ +Box2D/Dynamics/Joints/b2DistanceJoint.cpp \ +Box2D/Dynamics/Joints/b2FrictionJoint.cpp \ +Box2D/Dynamics/Joints/b2GearJoint.cpp \ +Box2D/Dynamics/Joints/b2Joint.cpp \ +Box2D/Dynamics/Joints/b2LineJoint.cpp \ +Box2D/Dynamics/Joints/b2MouseJoint.cpp \ +Box2D/Dynamics/Joints/b2PrismaticJoint.cpp \ +Box2D/Dynamics/Joints/b2PulleyJoint.cpp \ +Box2D/Dynamics/Joints/b2RevoluteJoint.cpp \ +Box2D/Dynamics/Joints/b2WeldJoint.cpp + +LOCAL_C_INCLUDES += $(LOCAL_PATH) $(LOCAL_PATH)/.. diff --git a/AndEngine/jni/Box2D/Body.cpp b/AndEngine/jni/Box2D/Body.cpp new file mode 100644 index 0000000..59b11c8 --- /dev/null +++ b/AndEngine/jni/Box2D/Body.cpp @@ -0,0 +1,637 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "Body.h" +#include + +#ifdef ANDROID +#include +#endif + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniCreateFixture + * Signature: (JJFFFZSSS)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniCreateFixture__JJFFFZSSS +(JNIEnv *, jobject, jlong addr, jlong shapeAddr, jfloat friction, jfloat restitution, jfloat density, jboolean isSensor, jshort categoryBits, jshort maskBits, jshort groupIndex) +{ + b2Body* body = (b2Body*)addr; + b2Shape* shape = (b2Shape*)shapeAddr; + b2FixtureDef fixtureDef; + +#ifdef ANDROID + //__android_log_print( ANDROID_LOG_INFO, "Box2DTest", "body: %d, shape: %d", body, shape ); +#endif + + fixtureDef.shape = shape; + fixtureDef.friction = friction; + fixtureDef.restitution = restitution; + fixtureDef.density = density; + fixtureDef.isSensor = isSensor; + fixtureDef.filter.maskBits = maskBits; + fixtureDef.filter.categoryBits = categoryBits; + fixtureDef.filter.groupIndex = groupIndex; + + return (jlong)body->CreateFixture( &fixtureDef ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniCreateFixture + * Signature: (JJF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniCreateFixture__JJF +(JNIEnv *, jobject, jlong addr, jlong shapeAddr, jfloat density) +{ + b2Body* body = (b2Body*)addr; + b2Shape* shape = (b2Shape*)shapeAddr; + return (jlong)body->CreateFixture( shape, density ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniDestroyFixture + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniDestroyFixture + (JNIEnv *, jobject, jlong addr, jlong fixtureAddr) +{ + b2Body* body = (b2Body*)addr; + b2Fixture* fixture = (b2Fixture*)fixtureAddr; + body->DestroyFixture(fixture); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetTransform + * Signature: (FFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetTransform + (JNIEnv *, jobject, jlong addr, jfloat positionX, jfloat positionY, jfloat angle) +{ + b2Body* body = (b2Body*)addr; + body->SetTransform(b2Vec2(positionX, positionY), angle); +} + +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetTransform + (JNIEnv *env, jobject, jlong addr, jfloatArray vals) +{ + b2Body* body = (b2Body*)addr; + float* valOut = (float*)env->GetPrimitiveArrayCritical(vals, 0); + b2Transform t = body->GetTransform(); + + valOut[0] = t.position.x; + valOut[1] = t.position.y; + valOut[2] = t.R.col1.x; + valOut[3] = t.R.col1.y; + valOut[4] = t.R.col2.x; + valOut[5] = t.R.col2.y; + env->ReleasePrimitiveArrayCritical(vals, valOut, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetPosition + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetPosition + (JNIEnv *env, jobject, jlong addr, jfloatArray position) +{ + b2Body* body = (b2Body*)addr; + float* positionOut = (float*)env->GetPrimitiveArrayCritical(position, 0); + b2Vec2 p = body->GetPosition(); + positionOut[0] = p.x; + positionOut[1] = p.y; + env->ReleasePrimitiveArrayCritical(position, positionOut, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetAngle + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetAngle + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetAngle(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetWorldCenter + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetWorldCenter + (JNIEnv *env, jobject, jlong addr, jfloatArray worldCenter) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(worldCenter, 0); + b2Vec2 w = body->GetWorldCenter(); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(worldCenter, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLocalCenter + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLocalCenter + (JNIEnv *env, jobject, jlong addr, jfloatArray localCenter) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(localCenter, 0); + b2Vec2 w = body->GetLocalCenter(); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(localCenter, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetLinearVelocity + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetLinearVelocity + (JNIEnv *, jobject, jlong addr, jfloat linearVelocityX, jfloat linearVelocityY) +{ + b2Body* body = (b2Body*)addr; + body->SetLinearVelocity(b2Vec2(linearVelocityX, linearVelocityY) ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearVelocity + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearVelocity + (JNIEnv *env, jobject, jlong addr, jfloatArray linVel) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(linVel,0); + b2Vec2 l = body->GetLinearVelocity(); + out[0] = l.x; + out[1] = l.y; + env->ReleasePrimitiveArrayCritical(linVel, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetAngularVelocity + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetAngularVelocity + (JNIEnv *, jobject, jlong addr, jfloat angularVelocity) +{ + b2Body* body = (b2Body*)addr; + body->SetAngularVelocity(angularVelocity); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetAngularVelocity + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetAngularVelocity + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetAngularVelocity(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyForce + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyForce + (JNIEnv *, jobject, jlong addr, jfloat forceX, jfloat forceY, jfloat pointX, jfloat pointY ) +{ + b2Body* body = (b2Body*)addr; + body->ApplyForce( b2Vec2( forceX, forceY ), b2Vec2( pointX, pointY ) ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyTorque + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyTorque + (JNIEnv *, jobject, jlong addr, jfloat torque) +{ + b2Body* body = (b2Body*)addr; + body->ApplyTorque(torque); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyLinearImpulse + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyLinearImpulse + (JNIEnv *, jobject, jlong addr, jfloat impulseX, jfloat impulseY, jfloat pointX, jfloat pointY) +{ + b2Body* body = (b2Body*)addr; + body->ApplyLinearImpulse( b2Vec2( impulseX, impulseY ), b2Vec2( pointX, pointY ) ); + +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyAngularImpulse + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyAngularImpulse + (JNIEnv *, jobject, jlong addr, jfloat angularImpulse) +{ + b2Body* body = (b2Body*)addr; + body->ApplyAngularImpulse(angularImpulse); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetMass + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetMass + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetMass(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetInertia + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetInertia + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetInertia(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetMassData + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetMassData + (JNIEnv *env, jobject, jlong addr, jfloatArray massData) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(massData, 0); + b2MassData m; + body->GetMassData(&m); + out[0] = m.mass; + out[1] = m.center.x; + out[2] = m.center.y; + out[3] = m.I; + env->ReleasePrimitiveArrayCritical(massData, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetMassData + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetMassData + (JNIEnv *, jobject, jlong addr, jfloat mass, jfloat centerX, jfloat centerY, jfloat I) +{ + b2Body* body = (b2Body*)addr; + b2MassData m; + m.mass = mass; + m.center.x = centerX; + m.center.y = centerY; + m.I = I; + body->SetMassData(&m); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniResetMassData + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniResetMassData + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + body->ResetMassData(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetWorldPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetWorldPoint + (JNIEnv *env, jobject, jlong addr, jfloat localPointX, jfloat localPointY, jfloatArray worldPoint) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(worldPoint, 0); + b2Vec2 w = body->GetWorldPoint( b2Vec2( localPointX, localPointY ) ); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(worldPoint, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetWorldVector + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetWorldVector +(JNIEnv *env, jobject, jlong addr, jfloat localVectorX, jfloat localVectorY, jfloatArray worldVector) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(worldVector, 0); + b2Vec2 w = body->GetWorldVector( b2Vec2( localVectorX, localVectorY ) ); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(worldVector, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLocalPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLocalPoint + (JNIEnv *env, jobject, jlong addr, jfloat worldPointX, jfloat worldPointY, jfloatArray localPoint) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(localPoint, 0); + b2Vec2 w = body->GetLocalPoint( b2Vec2( worldPointX, worldPointY ) ); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(localPoint, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLocalVector + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLocalVector + (JNIEnv *env, jobject, jlong addr, jfloat worldVectorX, jfloat worldVectorY, jfloatArray localVector) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(localVector, 0); + b2Vec2 w = body->GetLocalVector( b2Vec2( worldVectorX, worldVectorY ) ); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(localVector, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearVelocityFromWorldPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearVelocityFromWorldPoint + (JNIEnv *env, jobject, jlong addr, jfloat worldVectorX, jfloat worldVectorY, jfloatArray linVel) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(linVel, 0); + b2Vec2 w = body->GetLinearVelocityFromWorldPoint( b2Vec2( worldVectorX, worldVectorY ) ); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(linVel, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearVelocityFromLocalPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearVelocityFromLocalPoint + (JNIEnv *env, jobject, jlong addr, jfloat localPointX, jfloat localPointY, jfloatArray linVel) +{ + b2Body* body = (b2Body*)addr; + float* out = (float*)env->GetPrimitiveArrayCritical(linVel, 0); + b2Vec2 w = body->GetLinearVelocityFromLocalPoint( b2Vec2( localPointX, localPointY ) ); + out[0] = w.x; + out[1] = w.y; + env->ReleasePrimitiveArrayCritical(linVel, out, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearDamping + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearDamping + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetLinearDamping(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetLinearDamping + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetLinearDamping + (JNIEnv *, jobject, jlong addr, jfloat linearDamping) +{ + b2Body* body = (b2Body*)addr; + body->SetLinearDamping(linearDamping); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetAngularDamping + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetAngularDamping + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetAngularDamping(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetAngularDamping + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetAngularDamping + (JNIEnv *, jobject, jlong addr, jfloat angularDamping) +{ + b2Body* body = (b2Body*)addr; + body->SetAngularDamping(angularDamping); +} + +inline b2BodyType getBodyType( int type ) +{ + switch( type ) + { + case 0: return b2_staticBody; + case 1: return b2_kinematicBody; + case 2: return b2_dynamicBody; + default: + return b2_staticBody; + } +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetType + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetType + (JNIEnv *, jobject, jlong addr, jint type) +{ + b2Body* body = (b2Body*)addr; + body->SetType(getBodyType(type)); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetType + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->GetType(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetBullet + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetBullet + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2Body* body = (b2Body*)addr; + body->SetBullet(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsBullet + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsBullet + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->IsBullet(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetSleepingAllowed + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetSleepingAllowed + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2Body* body = (b2Body*)addr; + body->SetSleepingAllowed(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsSleepingAllowed + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsSleepingAllowed + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->IsSleepingAllowed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetAwake + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetAwake + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2Body* body = (b2Body*)addr; + body->SetAwake(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsAwake + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsAwake + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->IsAwake(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetActive + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetActive + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2Body* body = (b2Body*)addr; + body->SetActive(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsActive + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsActive + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->IsActive(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetFixedRotation + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetFixedRotation + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2Body* body = (b2Body*)addr; + body->SetFixedRotation(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsFixedRotation + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsFixedRotation + (JNIEnv *, jobject, jlong addr) +{ + b2Body* body = (b2Body*)addr; + return body->IsFixedRotation(); +} diff --git a/AndEngine/jni/Box2D/Body.h b/AndEngine/jni/Box2D/Body.h new file mode 100644 index 0000000..3222d61 --- /dev/null +++ b/AndEngine/jni/Box2D/Body.h @@ -0,0 +1,365 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_Body */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_Body +#define _Included_com_badlogic_gdx_physics_box2d_Body +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniCreateFixture + * Signature: (JJFFFZSSS)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniCreateFixture__JJFFFZSSS + (JNIEnv *, jobject, jlong, jlong, jfloat, jfloat, jfloat, jboolean, jshort, jshort, jshort); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniCreateFixture + * Signature: (JJF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniCreateFixture__JJF + (JNIEnv *, jobject, jlong, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniDestroyFixture + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniDestroyFixture + (JNIEnv *, jobject, jlong, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetTransform + * Signature: (JFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetTransform + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetTransform + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetTransform + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetPosition + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetPosition + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetAngle + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetAngle + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetWorldCenter + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetWorldCenter + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLocalCenter + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLocalCenter + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetLinearVelocity + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetLinearVelocity + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearVelocity + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearVelocity + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetAngularVelocity + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetAngularVelocity + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetAngularVelocity + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetAngularVelocity + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyForce + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyForce + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyTorque + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyTorque + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyLinearImpulse + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyLinearImpulse + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniApplyAngularImpulse + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniApplyAngularImpulse + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetMass + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetMass + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetInertia + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetInertia + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetMassData + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetMassData + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetMassData + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetMassData + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniResetMassData + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniResetMassData + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetWorldPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetWorldPoint + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetWorldVector + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetWorldVector + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLocalPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLocalPoint + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLocalVector + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLocalVector + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearVelocityFromWorldPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearVelocityFromWorldPoint + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearVelocityFromLocalPoint + * Signature: (JFF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearVelocityFromLocalPoint + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetLinearDamping + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetLinearDamping + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetLinearDamping + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetLinearDamping + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetAngularDamping + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetAngularDamping + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetAngularDamping + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetAngularDamping + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetType + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetType + (JNIEnv *, jobject, jlong, jint); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniGetType + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetBullet + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetBullet + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsBullet + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsBullet + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetSleepingAllowed + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetSleepingAllowed + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsSleepingAllowed + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsSleepingAllowed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetAwake + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetAwake + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsAwake + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsAwake + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetActive + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetActive + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsActive + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsActive + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniSetFixedRotation + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniSetFixedRotation + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Body + * Method: jniIsFixedRotation + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Body_jniIsFixedRotation + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/Box2D.h b/AndEngine/jni/Box2D/Box2D.h new file mode 100644 index 0000000..0d4bed5 --- /dev/null +++ b/AndEngine/jni/Box2D/Box2D.h @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BOX2D_H +#define BOX2D_H + +/** +\mainpage Box2D API Documentation + +\section intro_sec Getting Started + +For documentation please see http://box2d.org/documentation.html + +For discussion please visit http://box2d.org/forum +*/ + +// These include files constitute the main Box2D API + +#include "Box2D/Common/b2Settings.h" + +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" + +#include "Box2D/Collision/b2BroadPhase.h" +#include "Box2D/Collision/b2Distance.h" +#include "Box2D/Collision/b2DynamicTree.h" +#include "Box2D/Collision/b2TimeOfImpact.h" + +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2WorldCallbacks.h" +#include "Box2D/Dynamics/b2TimeStep.h" +#include "Box2D/Dynamics/b2World.h" + +#include "Box2D/Dynamics/Contacts/b2Contact.h" + +#include "Box2D/Dynamics/Joints/b2DistanceJoint.h" +#include "Box2D/Dynamics/Joints/b2FrictionJoint.h" +#include "Box2D/Dynamics/Joints/b2GearJoint.h" +#include "Box2D/Dynamics/Joints/b2LineJoint.h" +#include "Box2D/Dynamics/Joints/b2MouseJoint.h" +#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" +#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" +#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" +#include "Box2D/Dynamics/Joints/b2WeldJoint.h" + +#endif diff --git a/AndEngine/jni/Box2D/CircleShape.cpp b/AndEngine/jni/Box2D/CircleShape.cpp new file mode 100644 index 0000000..cb5fb99 --- /dev/null +++ b/AndEngine/jni/Box2D/CircleShape.cpp @@ -0,0 +1,56 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "CircleShape.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_CircleShape + * Method: newCircleShape + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_CircleShape_newCircleShape + (JNIEnv *, jobject) +{ + return (jlong)(new b2CircleShape( )); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_CircleShape + * Method: jniGetPosition + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_CircleShape_jniGetPosition + (JNIEnv *env, jobject, jlong addr, jfloatArray positionOut) +{ + b2CircleShape* circle = (b2CircleShape*)addr; + float* position = (float*)env->GetPrimitiveArrayCritical(positionOut, 0); + position[0] = circle->m_p.x; + position[1] = circle->m_p.y; + env->ReleasePrimitiveArrayCritical(positionOut, position, 0 ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_CircleShape + * Method: jniSetPosition + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_CircleShape_jniSetPosition + (JNIEnv *, jobject, jlong addr, jfloat positionX, jfloat positionY) +{ + b2CircleShape* circle = (b2CircleShape*)addr; + circle->m_p.x = positionX; + circle->m_p.y = positionY; +} diff --git a/AndEngine/jni/Box2D/CircleShape.h b/AndEngine/jni/Box2D/CircleShape.h new file mode 100644 index 0000000..a4b4fc6 --- /dev/null +++ b/AndEngine/jni/Box2D/CircleShape.h @@ -0,0 +1,52 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_CircleShape */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_CircleShape +#define _Included_com_badlogic_gdx_physics_box2d_CircleShape +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_CircleShape + * Method: newCircleShape + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_CircleShape_newCircleShape + (JNIEnv *, jobject); + +/* + * Class: com_badlogic_gdx_physics_box2d_CircleShape + * Method: jniGetPosition + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_CircleShape_jniGetPosition + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_CircleShape + * Method: jniSetPosition + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_CircleShape_jniSetPosition + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/Collision/Shapes/b2CircleShape.cpp b/AndEngine/jni/Box2D/Collision/Shapes/b2CircleShape.cpp new file mode 100644 index 0000000..018aa0d --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/Shapes/b2CircleShape.cpp @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include + +b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const +{ + void* mem = allocator->Allocate(sizeof(b2CircleShape)); + b2CircleShape* clone = new (mem) b2CircleShape; + *clone = *this; + return clone; +} + +bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const +{ + b2Vec2 center = transform.position + b2Mul(transform.R, m_p); + b2Vec2 d = p - center; + return b2Dot(d, d) <= m_radius * m_radius; +} + +// Collision Detection in Interactive 3D Environments by Gino van den Bergen +// From Section 3.1.2 +// x = s + a * r +// norm(x) = radius +bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const +{ + b2Vec2 position = transform.position + b2Mul(transform.R, m_p); + b2Vec2 s = input.p1 - position; + float32 b = b2Dot(s, s) - m_radius * m_radius; + + // Solve quadratic equation. + b2Vec2 r = input.p2 - input.p1; + float32 c = b2Dot(s, r); + float32 rr = b2Dot(r, r); + float32 sigma = c * c - rr * b; + + // Check for negative discriminant and short segment. + if (sigma < 0.0f || rr < b2_epsilon) + { + return false; + } + + // Find the point of intersection of the line with the circle. + float32 a = -(c + b2Sqrt(sigma)); + + // Is the intersection point on the segment? + if (0.0f <= a && a <= input.maxFraction * rr) + { + a /= rr; + output->fraction = a; + output->normal = s + a * r; + output->normal.Normalize(); + return true; + } + + return false; +} + +void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform) const +{ + b2Vec2 p = transform.position + b2Mul(transform.R, m_p); + aabb->lowerBound.Set(p.x - m_radius, p.y - m_radius); + aabb->upperBound.Set(p.x + m_radius, p.y + m_radius); +} + +void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const +{ + massData->mass = density * b2_pi * m_radius * m_radius; + massData->center = m_p; + + // inertia about the local origin + massData->I = massData->mass * (0.5f * m_radius * m_radius + b2Dot(m_p, m_p)); +} diff --git a/AndEngine/jni/Box2D/Collision/Shapes/b2CircleShape.h b/AndEngine/jni/Box2D/Collision/Shapes/b2CircleShape.h new file mode 100644 index 0000000..84d809e --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/Shapes/b2CircleShape.h @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_CIRCLE_SHAPE_H +#define B2_CIRCLE_SHAPE_H + +#include "Box2D/Collision/Shapes/b2Shape.h" + +/// A circle shape. +class b2CircleShape : public b2Shape +{ +public: + b2CircleShape(); + + /// Implement b2Shape. + b2Shape* Clone(b2BlockAllocator* allocator) const; + + /// Implement b2Shape. + bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; + + /// Implement b2Shape. + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const; + + /// @see b2Shape::ComputeAABB + void ComputeAABB(b2AABB* aabb, const b2Transform& transform) const; + + /// @see b2Shape::ComputeMass + void ComputeMass(b2MassData* massData, float32 density) const; + + /// Get the supporting vertex index in the given direction. + int32 GetSupport(const b2Vec2& d) const; + + /// Get the supporting vertex in the given direction. + const b2Vec2& GetSupportVertex(const b2Vec2& d) const; + + /// Get the vertex count. + int32 GetVertexCount() const { return 1; } + + /// Get a vertex by index. Used by b2Distance. + const b2Vec2& GetVertex(int32 index) const; + + /// Position + b2Vec2 m_p; +}; + +inline b2CircleShape::b2CircleShape() +{ + m_type = e_circle; + m_radius = 0.0f; + m_p.SetZero(); +} + +inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const +{ + B2_NOT_USED(d); + return 0; +} + +inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const +{ + B2_NOT_USED(d); + return m_p; +} + +inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const +{ + B2_NOT_USED(index); + b2Assert(index == 0); + return m_p; +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/Shapes/b2PolygonShape.cpp b/AndEngine/jni/Box2D/Collision/Shapes/b2PolygonShape.cpp new file mode 100644 index 0000000..9db0fa8 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/Shapes/b2PolygonShape.cpp @@ -0,0 +1,434 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/Shapes/b2PolygonShape.h" +#include + +b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const +{ + void* mem = allocator->Allocate(sizeof(b2PolygonShape)); + b2PolygonShape* clone = new (mem) b2PolygonShape; + *clone = *this; + return clone; +} + +void b2PolygonShape::SetAsBox(float32 hx, float32 hy) +{ + m_vertexCount = 4; + m_vertices[0].Set(-hx, -hy); + m_vertices[1].Set( hx, -hy); + m_vertices[2].Set( hx, hy); + m_vertices[3].Set(-hx, hy); + m_normals[0].Set(0.0f, -1.0f); + m_normals[1].Set(1.0f, 0.0f); + m_normals[2].Set(0.0f, 1.0f); + m_normals[3].Set(-1.0f, 0.0f); + m_centroid.SetZero(); +} + +void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle) +{ + m_vertexCount = 4; + m_vertices[0].Set(-hx, -hy); + m_vertices[1].Set( hx, -hy); + m_vertices[2].Set( hx, hy); + m_vertices[3].Set(-hx, hy); + m_normals[0].Set(0.0f, -1.0f); + m_normals[1].Set(1.0f, 0.0f); + m_normals[2].Set(0.0f, 1.0f); + m_normals[3].Set(-1.0f, 0.0f); + m_centroid = center; + + b2Transform xf; + xf.position = center; + xf.R.Set(angle); + + // Transform vertices and normals. + for (int32 i = 0; i < m_vertexCount; ++i) + { + m_vertices[i] = b2Mul(xf, m_vertices[i]); + m_normals[i] = b2Mul(xf.R, m_normals[i]); + } +} + +void b2PolygonShape::SetAsEdge(const b2Vec2& v1, const b2Vec2& v2) +{ + m_vertexCount = 2; + m_vertices[0] = v1; + m_vertices[1] = v2; + m_centroid = 0.5f * (v1 + v2); + m_normals[0] = b2Cross(v2 - v1, 1.0f); + m_normals[0].Normalize(); + m_normals[1] = -m_normals[0]; +} + +static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count) +{ + b2Assert(count >= 2); + + b2Vec2 c; c.Set(0.0f, 0.0f); + float32 area = 0.0f; + + if (count == 2) + { + c = 0.5f * (vs[0] + vs[1]); + return c; + } + + // pRef is the reference point for forming triangles. + // It's location doesn't change the result (except for rounding error). + b2Vec2 pRef(0.0f, 0.0f); +#if 0 + // This code would put the reference point inside the polygon. + for (int32 i = 0; i < count; ++i) + { + pRef += vs[i]; + } + pRef *= 1.0f / count; +#endif + + const float32 inv3 = 1.0f / 3.0f; + + for (int32 i = 0; i < count; ++i) + { + // Triangle vertices. + b2Vec2 p1 = pRef; + b2Vec2 p2 = vs[i]; + b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0]; + + b2Vec2 e1 = p2 - p1; + b2Vec2 e2 = p3 - p1; + + float32 D = b2Cross(e1, e2); + + float32 triangleArea = 0.5f * D; + area += triangleArea; + + // Area weighted centroid + c += triangleArea * inv3 * (p1 + p2 + p3); + } + + // Centroid + b2Assert(area > b2_epsilon); + c *= 1.0f / area; + return c; +} + +void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) +{ + b2Assert(2 <= count && count <= b2_maxPolygonVertices); + m_vertexCount = count; + + // Copy vertices. + for (int32 i = 0; i < m_vertexCount; ++i) + { + m_vertices[i] = vertices[i]; + } + + // Compute normals. Ensure the edges have non-zero length. + for (int32 i = 0; i < m_vertexCount; ++i) + { + int32 i1 = i; + int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0; + b2Vec2 edge = m_vertices[i2] - m_vertices[i1]; + b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon); + m_normals[i] = b2Cross(edge, 1.0f); + m_normals[i].Normalize(); + } + +#ifdef _DEBUG + // Ensure the polygon is convex and the interior + // is to the left of each edge. + for (int32 i = 0; i < m_vertexCount; ++i) + { + int32 i1 = i; + int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0; + b2Vec2 edge = m_vertices[i2] - m_vertices[i1]; + + for (int32 j = 0; j < m_vertexCount; ++j) + { + // Don't check vertices on the current edge. + if (j == i1 || j == i2) + { + continue; + } + + b2Vec2 r = m_vertices[j] - m_vertices[i1]; + + // Your polygon is non-convex (it has an indentation) or + // has colinear edges. + float32 s = b2Cross(edge, r); + b2Assert(s > 0.0f); + } + } +#endif + + // Compute the polygon centroid. + m_centroid = ComputeCentroid(m_vertices, m_vertexCount); +} + +bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const +{ + b2Vec2 pLocal = b2MulT(xf.R, p - xf.position); + + for (int32 i = 0; i < m_vertexCount; ++i) + { + float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]); + if (dot > 0.0f) + { + return false; + } + } + + return true; +} + +bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& xf) const +{ + // Put the ray into the polygon's frame of reference. + b2Vec2 p1 = b2MulT(xf.R, input.p1 - xf.position); + b2Vec2 p2 = b2MulT(xf.R, input.p2 - xf.position); + b2Vec2 d = p2 - p1; + + if (m_vertexCount == 2) + { + b2Vec2 v1 = m_vertices[0]; + b2Vec2 v2 = m_vertices[1]; + b2Vec2 normal = m_normals[0]; + + // q = p1 + t * d + // dot(normal, q - v1) = 0 + // dot(normal, p1 - v1) + t * dot(normal, d) = 0 + float32 numerator = b2Dot(normal, v1 - p1); + float32 denominator = b2Dot(normal, d); + + if (denominator == 0.0f) + { + return false; + } + + float32 t = numerator / denominator; + if (t < 0.0f || 1.0f < t) + { + return false; + } + + b2Vec2 q = p1 + t * d; + + // q = v1 + s * r + // s = dot(q - v1, r) / dot(r, r) + b2Vec2 r = v2 - v1; + float32 rr = b2Dot(r, r); + if (rr == 0.0f) + { + return false; + } + + float32 s = b2Dot(q - v1, r) / rr; + if (s < 0.0f || 1.0f < s) + { + return false; + } + + output->fraction = t; + if (numerator > 0.0f) + { + output->normal = -normal; + } + else + { + output->normal = normal; + } + return true; + } + else + { + float32 lower = 0.0f, upper = input.maxFraction; + + int32 index = -1; + + for (int32 i = 0; i < m_vertexCount; ++i) + { + // p = p1 + a * d + // dot(normal, p - v) = 0 + // dot(normal, p1 - v) + a * dot(normal, d) = 0 + float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1); + float32 denominator = b2Dot(m_normals[i], d); + + if (denominator == 0.0f) + { + if (numerator < 0.0f) + { + return false; + } + } + else + { + // Note: we want this predicate without division: + // lower < numerator / denominator, where denominator < 0 + // Since denominator < 0, we have to flip the inequality: + // lower < numerator / denominator <==> denominator * lower > numerator. + if (denominator < 0.0f && numerator < lower * denominator) + { + // Increase lower. + // The segment enters this half-space. + lower = numerator / denominator; + index = i; + } + else if (denominator > 0.0f && numerator < upper * denominator) + { + // Decrease upper. + // The segment exits this half-space. + upper = numerator / denominator; + } + } + + // The use of epsilon here causes the assert on lower to trip + // in some cases. Apparently the use of epsilon was to make edge + // shapes work, but now those are handled separately. + //if (upper < lower - b2_epsilon) + if (upper < lower) + { + return false; + } + } + + b2Assert(0.0f <= lower && lower <= input.maxFraction); + + if (index >= 0) + { + output->fraction = lower; + output->normal = b2Mul(xf.R, m_normals[index]); + return true; + } + } + + return false; +} + +void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf) const +{ + b2Vec2 lower = b2Mul(xf, m_vertices[0]); + b2Vec2 upper = lower; + + for (int32 i = 1; i < m_vertexCount; ++i) + { + b2Vec2 v = b2Mul(xf, m_vertices[i]); + lower = b2Min(lower, v); + upper = b2Max(upper, v); + } + + b2Vec2 r(m_radius, m_radius); + aabb->lowerBound = lower - r; + aabb->upperBound = upper + r; +} + +void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const +{ + // Polygon mass, centroid, and inertia. + // Let rho be the polygon density in mass per unit area. + // Then: + // mass = rho * int(dA) + // centroid.x = (1/mass) * rho * int(x * dA) + // centroid.y = (1/mass) * rho * int(y * dA) + // I = rho * int((x*x + y*y) * dA) + // + // We can compute these integrals by summing all the integrals + // for each triangle of the polygon. To evaluate the integral + // for a single triangle, we make a change of variables to + // the (u,v) coordinates of the triangle: + // x = x0 + e1x * u + e2x * v + // y = y0 + e1y * u + e2y * v + // where 0 <= u && 0 <= v && u + v <= 1. + // + // We integrate u from [0,1-v] and then v from [0,1]. + // We also need to use the Jacobian of the transformation: + // D = cross(e1, e2) + // + // Simplification: triangle centroid = (1/3) * (p1 + p2 + p3) + // + // The rest of the derivation is handled by computer algebra. + + b2Assert(m_vertexCount >= 2); + + // A line segment has zero mass. + if (m_vertexCount == 2) + { + massData->center = 0.5f * (m_vertices[0] + m_vertices[1]); + massData->mass = 0.0f; + massData->I = 0.0f; + return; + } + + b2Vec2 center; center.Set(0.0f, 0.0f); + float32 area = 0.0f; + float32 I = 0.0f; + + // pRef is the reference point for forming triangles. + // It's location doesn't change the result (except for rounding error). + b2Vec2 pRef(0.0f, 0.0f); +#if 0 + // This code would put the reference point inside the polygon. + for (int32 i = 0; i < m_vertexCount; ++i) + { + pRef += m_vertices[i]; + } + pRef *= 1.0f / count; +#endif + + const float32 k_inv3 = 1.0f / 3.0f; + + for (int32 i = 0; i < m_vertexCount; ++i) + { + // Triangle vertices. + b2Vec2 p1 = pRef; + b2Vec2 p2 = m_vertices[i]; + b2Vec2 p3 = i + 1 < m_vertexCount ? m_vertices[i+1] : m_vertices[0]; + + b2Vec2 e1 = p2 - p1; + b2Vec2 e2 = p3 - p1; + + float32 D = b2Cross(e1, e2); + + float32 triangleArea = 0.5f * D; + area += triangleArea; + + // Area weighted centroid + center += triangleArea * k_inv3 * (p1 + p2 + p3); + + float32 px = p1.x, py = p1.y; + float32 ex1 = e1.x, ey1 = e1.y; + float32 ex2 = e2.x, ey2 = e2.y; + + float32 intx2 = k_inv3 * (0.25f * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5f*px*px; + float32 inty2 = k_inv3 * (0.25f * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5f*py*py; + + I += D * (intx2 + inty2); + } + + // Total mass + massData->mass = density * area; + + // Center of mass + b2Assert(area > b2_epsilon); + center *= 1.0f / area; + massData->center = center; + + // Inertia tensor relative to the local origin. + massData->I = density * I; +} diff --git a/AndEngine/jni/Box2D/Collision/Shapes/b2PolygonShape.h b/AndEngine/jni/Box2D/Collision/Shapes/b2PolygonShape.h new file mode 100644 index 0000000..4c67cb8 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/Shapes/b2PolygonShape.h @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_POLYGON_SHAPE_H +#define B2_POLYGON_SHAPE_H + +#include "Box2D/Collision/Shapes/b2Shape.h" + +/// A convex polygon. It is assumed that the interior of the polygon is to +/// the left of each edge. +class b2PolygonShape : public b2Shape +{ +public: + b2PolygonShape(); + + /// Implement b2Shape. + b2Shape* Clone(b2BlockAllocator* allocator) const; + + /// Copy vertices. This assumes the vertices define a convex polygon. + /// It is assumed that the exterior is the the right of each edge. + void Set(const b2Vec2* vertices, int32 vertexCount); + + /// Build vertices to represent an axis-aligned box. + /// @param hx the half-width. + /// @param hy the half-height. + void SetAsBox(float32 hx, float32 hy); + + /// Build vertices to represent an oriented box. + /// @param hx the half-width. + /// @param hy the half-height. + /// @param center the center of the box in local coordinates. + /// @param angle the rotation of the box in local coordinates. + void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle); + + /// Set this as a single edge. + void SetAsEdge(const b2Vec2& v1, const b2Vec2& v2); + + /// @see b2Shape::TestPoint + bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; + + /// Implement b2Shape. + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const; + + /// @see b2Shape::ComputeAABB + void ComputeAABB(b2AABB* aabb, const b2Transform& transform) const; + + /// @see b2Shape::ComputeMass + void ComputeMass(b2MassData* massData, float32 density) const; + + /// Get the supporting vertex index in the given direction. + int32 GetSupport(const b2Vec2& d) const; + + /// Get the supporting vertex in the given direction. + const b2Vec2& GetSupportVertex(const b2Vec2& d) const; + + /// Get the vertex count. + int32 GetVertexCount() const { return m_vertexCount; } + + /// Get a vertex by index. + const b2Vec2& GetVertex(int32 index) const; + + b2Vec2 m_centroid; + b2Vec2 m_vertices[b2_maxPolygonVertices]; + b2Vec2 m_normals[b2_maxPolygonVertices]; + int32 m_vertexCount; +}; + +inline b2PolygonShape::b2PolygonShape() +{ + m_type = e_polygon; + m_radius = b2_polygonRadius; + m_vertexCount = 0; + m_centroid.SetZero(); +} + +inline int32 b2PolygonShape::GetSupport(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float32 bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_vertexCount; ++i) + { + float32 value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return bestIndex; +} + +inline const b2Vec2& b2PolygonShape::GetSupportVertex(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float32 bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_vertexCount; ++i) + { + float32 value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return m_vertices[bestIndex]; +} + +inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const +{ + b2Assert(0 <= index && index < m_vertexCount); + return m_vertices[index]; +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/Shapes/b2Shape.h b/AndEngine/jni/Box2D/Collision/Shapes/b2Shape.h new file mode 100644 index 0000000..d121790 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/Shapes/b2Shape.h @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_SHAPE_H +#define B2_SHAPE_H + +#include "Box2D/Common/b2BlockAllocator.h" +#include "Box2D/Common/b2Math.h" +#include "Box2D/Collision/b2Collision.h" + +/// This holds the mass data computed for a shape. +struct b2MassData +{ + /// The mass of the shape, usually in kilograms. + float32 mass; + + /// The position of the shape's centroid relative to the shape's origin. + b2Vec2 center; + + /// The rotational inertia of the shape about the local origin. + float32 I; +}; + +/// A shape is used for collision detection. You can create a shape however you like. +/// Shapes used for simulation in b2World are created automatically when a b2Fixture +/// is created. +class b2Shape +{ +public: + + enum Type + { + e_unknown= -1, + e_circle = 0, + e_polygon = 1, + e_typeCount = 2, + }; + + b2Shape() { m_type = e_unknown; } + virtual ~b2Shape() {} + + /// Clone the concrete shape using the provided allocator. + virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0; + + /// Get the type of this shape. You can use this to down cast to the concrete shape. + /// @return the shape type. + Type GetType() const; + + /// Test a point for containment in this shape. This only works for convex shapes. + /// @param xf the shape world transform. + /// @param p a point in world coordinates. + virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0; + + /// Cast a ray against this shape. + /// @param output the ray-cast results. + /// @param input the ray-cast input parameters. + /// @param transform the transform to be applied to the shape. + virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const = 0; + + /// Given a transform, compute the associated axis aligned bounding box for this shape. + /// @param aabb returns the axis aligned box. + /// @param xf the world transform of the shape. + virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf) const = 0; + + /// Compute the mass properties of this shape using its dimensions and density. + /// The inertia tensor is computed about the local origin. + /// @param massData returns the mass data for this shape. + /// @param density the density in kilograms per meter squared. + virtual void ComputeMass(b2MassData* massData, float32 density) const = 0; + + Type m_type; + float32 m_radius; +}; + +inline b2Shape::Type b2Shape::GetType() const +{ + return m_type; +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/b2BroadPhase.cpp b/AndEngine/jni/Box2D/Collision/b2BroadPhase.cpp new file mode 100644 index 0000000..4030958 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2BroadPhase.cpp @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2BroadPhase.h" +#include + +b2BroadPhase::b2BroadPhase() +{ + m_proxyCount = 0; + + m_pairCapacity = 16; + m_pairCount = 0; + m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); + + m_moveCapacity = 16; + m_moveCount = 0; + m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32)); +} + +b2BroadPhase::~b2BroadPhase() +{ + b2Free(m_moveBuffer); + b2Free(m_pairBuffer); +} + +int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData) +{ + int32 proxyId = m_tree.CreateProxy(aabb, userData); + ++m_proxyCount; + BufferMove(proxyId); + return proxyId; +} + +void b2BroadPhase::DestroyProxy(int32 proxyId) +{ + UnBufferMove(proxyId); + --m_proxyCount; + m_tree.DestroyProxy(proxyId); +} + +void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement) +{ + bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement); + if (buffer) + { + BufferMove(proxyId); + } +} + +void b2BroadPhase::BufferMove(int32 proxyId) +{ + if (m_moveCount == m_moveCapacity) + { + int32* oldBuffer = m_moveBuffer; + m_moveCapacity *= 2; + m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32)); + memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32)); + b2Free(oldBuffer); + } + + m_moveBuffer[m_moveCount] = proxyId; + ++m_moveCount; +} + +void b2BroadPhase::UnBufferMove(int32 proxyId) +{ + for (int32 i = 0; i < m_moveCount; ++i) + { + if (m_moveBuffer[i] == proxyId) + { + m_moveBuffer[i] = e_nullProxy; + return; + } + } +} + +// This is called from b2DynamicTree::Query when we are gathering pairs. +bool b2BroadPhase::QueryCallback(int32 proxyId) +{ + // A proxy cannot form a pair with itself. + if (proxyId == m_queryProxyId) + { + return true; + } + + // Grow the pair buffer as needed. + if (m_pairCount == m_pairCapacity) + { + b2Pair* oldBuffer = m_pairBuffer; + m_pairCapacity *= 2; + m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); + memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair)); + b2Free(oldBuffer); + } + + m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId); + m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId); + ++m_pairCount; + + return true; +} diff --git a/AndEngine/jni/Box2D/Collision/b2BroadPhase.h b/AndEngine/jni/Box2D/Collision/b2BroadPhase.h new file mode 100644 index 0000000..a236815 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2BroadPhase.h @@ -0,0 +1,264 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_BROAD_PHASE_H +#define B2_BROAD_PHASE_H + +#include "Box2D/Common/b2Settings.h" +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/b2DynamicTree.h" +#include +//#include + +struct b2Pair +{ + int32 proxyIdA; + int32 proxyIdB; + int32 next; +}; + +/// The broad-phase is used for computing pairs and performing volume queries and ray casts. +/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs. +/// It is up to the client to consume the new pairs and to track subsequent overlap. +class b2BroadPhase +{ +public: + + enum + { + e_nullProxy = -1, + }; + + b2BroadPhase(); + ~b2BroadPhase(); + + /// Create a proxy with an initial AABB. Pairs are not reported until + /// UpdatePairs is called. + int32 CreateProxy(const b2AABB& aabb, void* userData); + + /// Destroy a proxy. It is up to the client to remove any pairs. + void DestroyProxy(int32 proxyId); + + /// Call MoveProxy as many times as you like, then when you are done + /// call UpdatePairs to finalized the proxy pairs (for your time step). + void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement); + + /// Get the fat AABB for a proxy. + const b2AABB& GetFatAABB(int32 proxyId) const; + + /// Get user data from a proxy. Returns NULL if the id is invalid. + void* GetUserData(int32 proxyId) const; + + /// Test overlap of fat AABBs. + bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const; + + /// Get the number of proxies. + int32 GetProxyCount() const; + + /// Update the pairs. This results in pair callbacks. This can only add pairs. + template + void UpdatePairs(T* callback); + + /// Query an AABB for overlapping proxies. The callback class + /// is called for each proxy that overlaps the supplied AABB. + template + void Query(T* callback, const b2AABB& aabb) const; + + /// Ray-cast against the proxies in the tree. This relies on the callback + /// to perform a exact ray-cast in the case were the proxy contains a shape. + /// The callback also performs the any collision filtering. This has performance + /// roughly equal to k * log(n), where k is the number of collisions and n is the + /// number of proxies in the tree. + /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). + /// @param callback a callback class that is called for each proxy that is hit by the ray. + template + void RayCast(T* callback, const b2RayCastInput& input) const; + + /// Compute the height of the embedded tree. + int32 ComputeHeight() const; + +private: + + friend class b2DynamicTree; + + void BufferMove(int32 proxyId); + void UnBufferMove(int32 proxyId); + + bool QueryCallback(int32 proxyId); + + b2DynamicTree m_tree; + + int32 m_proxyCount; + + int32* m_moveBuffer; + int32 m_moveCapacity; + int32 m_moveCount; + + b2Pair* m_pairBuffer; + int32 m_pairCapacity; + int32 m_pairCount; + + int32 m_queryProxyId; +}; + +/// This is used to sort pairs. +inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2) +{ + if (pair1.proxyIdA < pair2.proxyIdA) + { + return true; + } + + if (pair1.proxyIdA == pair2.proxyIdA) + { + return pair1.proxyIdB < pair2.proxyIdB; + } + + return false; +} + +inline void* b2BroadPhase::GetUserData(int32 proxyId) const +{ + return m_tree.GetUserData(proxyId); +} + +inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const +{ + const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA); + const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB); + return b2TestOverlap(aabbA, aabbB); +} + +inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const +{ + return m_tree.GetFatAABB(proxyId); +} + +inline int32 b2BroadPhase::GetProxyCount() const +{ + return m_proxyCount; +} + +inline int32 b2BroadPhase::ComputeHeight() const +{ + return m_tree.ComputeHeight(); +} + +//The return value of this function should represent whether elem1 is considered less than, +//equal to, or greater than elem2 by returning, respectively, a negative value, zero or a positive value. +inline int b2PairCompareQSort(const void * elem1, const void * elem2) +{ + b2Pair* pair1 = (b2Pair*) elem1; + b2Pair* pair2 = (b2Pair*) elem2; + + if (pair1->proxyIdA < pair2->proxyIdA) + { + return -1; + } + + if (pair1->proxyIdA == pair2->proxyIdA) + { + if( pair1->proxyIdB < pair2->proxyIdB ) { + return -1; + } + else if(pair1->proxyIdB > pair2->proxyIdB) { + return 1; + } + else { + return 0; + } + } + else { + return 1; + } + +} + +template +void b2BroadPhase::UpdatePairs(T* callback) +{ + // Reset pair buffer + m_pairCount = 0; + + // Perform tree queries for all moving proxies. + for (int32 i = 0; i < m_moveCount; ++i) + { + m_queryProxyId = m_moveBuffer[i]; + if (m_queryProxyId == e_nullProxy) + { + continue; + } + + // We have to query the tree with the fat AABB so that + // we don't fail to create a pair that may touch later. + const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId); + + // Query tree, create pairs and add them pair buffer. + m_tree.Query(this, fatAABB); + } + + // Reset move buffer + m_moveCount = 0; + + // Sort the pair buffer to expose duplicates. + //std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan); + + // FIX from http://www.box2d.org/forum/viewtopic.php?f=7&t=4756&start=0 to get rid of stl dependency + qsort(m_pairBuffer, sizeof(m_pairBuffer) / sizeof(struct b2Pair) , sizeof(struct b2Pair), b2PairCompareQSort); + + // Send the pairs back to the client. + int32 i = 0; + while (i < m_pairCount) + { + b2Pair* primaryPair = m_pairBuffer + i; + void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA); + void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB); + + callback->AddPair(userDataA, userDataB); + ++i; + + // Skip any duplicate pairs. + while (i < m_pairCount) + { + b2Pair* pair = m_pairBuffer + i; + if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB) + { + break; + } + ++i; + } + } + + // Try to keep the tree balanced. + m_tree.Rebalance(4); +} + + +template +inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const +{ + m_tree.Query(callback, aabb); +} + +template +inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const +{ + m_tree.RayCast(callback, input); +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/b2CollideCircle.cpp b/AndEngine/jni/Box2D/Collision/b2CollideCircle.cpp new file mode 100644 index 0000000..deabbbf --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2CollideCircle.cpp @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" + +void b2CollideCircles( + b2Manifold* manifold, + const b2CircleShape* circleA, const b2Transform& xfA, + const b2CircleShape* circleB, const b2Transform& xfB) +{ + manifold->pointCount = 0; + + b2Vec2 pA = b2Mul(xfA, circleA->m_p); + b2Vec2 pB = b2Mul(xfB, circleB->m_p); + + b2Vec2 d = pB - pA; + float32 distSqr = b2Dot(d, d); + float32 rA = circleA->m_radius, rB = circleB->m_radius; + float32 radius = rA + rB; + if (distSqr > radius * radius) + { + return; + } + + manifold->type = b2Manifold::e_circles; + manifold->localPoint = circleA->m_p; + manifold->localNormal.SetZero(); + manifold->pointCount = 1; + + manifold->points[0].localPoint = circleB->m_p; + manifold->points[0].id.key = 0; +} + +void b2CollidePolygonAndCircle( + b2Manifold* manifold, + const b2PolygonShape* polygonA, const b2Transform& xfA, + const b2CircleShape* circleB, const b2Transform& xfB) +{ + manifold->pointCount = 0; + + // Compute circle position in the frame of the polygon. + b2Vec2 c = b2Mul(xfB, circleB->m_p); + b2Vec2 cLocal = b2MulT(xfA, c); + + // Find the min separating edge. + int32 normalIndex = 0; + float32 separation = -b2_maxFloat; + float32 radius = polygonA->m_radius + circleB->m_radius; + int32 vertexCount = polygonA->m_vertexCount; + const b2Vec2* vertices = polygonA->m_vertices; + const b2Vec2* normals = polygonA->m_normals; + + for (int32 i = 0; i < vertexCount; ++i) + { + float32 s = b2Dot(normals[i], cLocal - vertices[i]); + + if (s > radius) + { + // Early out. + return; + } + + if (s > separation) + { + separation = s; + normalIndex = i; + } + } + + // Vertices that subtend the incident face. + int32 vertIndex1 = normalIndex; + int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0; + b2Vec2 v1 = vertices[vertIndex1]; + b2Vec2 v2 = vertices[vertIndex2]; + + // If the center is inside the polygon ... + if (separation < b2_epsilon) + { + manifold->pointCount = 1; + manifold->type = b2Manifold::e_faceA; + manifold->localNormal = normals[normalIndex]; + manifold->localPoint = 0.5f * (v1 + v2); + manifold->points[0].localPoint = circleB->m_p; + manifold->points[0].id.key = 0; + return; + } + + // Compute barycentric coordinates + float32 u1 = b2Dot(cLocal - v1, v2 - v1); + float32 u2 = b2Dot(cLocal - v2, v1 - v2); + if (u1 <= 0.0f) + { + if (b2DistanceSquared(cLocal, v1) > radius * radius) + { + return; + } + + manifold->pointCount = 1; + manifold->type = b2Manifold::e_faceA; + manifold->localNormal = cLocal - v1; + manifold->localNormal.Normalize(); + manifold->localPoint = v1; + manifold->points[0].localPoint = circleB->m_p; + manifold->points[0].id.key = 0; + } + else if (u2 <= 0.0f) + { + if (b2DistanceSquared(cLocal, v2) > radius * radius) + { + return; + } + + manifold->pointCount = 1; + manifold->type = b2Manifold::e_faceA; + manifold->localNormal = cLocal - v2; + manifold->localNormal.Normalize(); + manifold->localPoint = v2; + manifold->points[0].localPoint = circleB->m_p; + manifold->points[0].id.key = 0; + } + else + { + b2Vec2 faceCenter = 0.5f * (v1 + v2); + float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]); + if (separation > radius) + { + return; + } + + manifold->pointCount = 1; + manifold->type = b2Manifold::e_faceA; + manifold->localNormal = normals[vertIndex1]; + manifold->localPoint = faceCenter; + manifold->points[0].localPoint = circleB->m_p; + manifold->points[0].id.key = 0; + } +} diff --git a/AndEngine/jni/Box2D/Collision/b2CollidePolygon.cpp b/AndEngine/jni/Box2D/Collision/b2CollidePolygon.cpp new file mode 100644 index 0000000..2ac8779 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2CollidePolygon.cpp @@ -0,0 +1,306 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" + +// Find the separation between poly1 and poly2 for a give edge normal on poly1. +static float32 b2EdgeSeparation(const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1, + const b2PolygonShape* poly2, const b2Transform& xf2) +{ + int32 count1 = poly1->m_vertexCount; + const b2Vec2* vertices1 = poly1->m_vertices; + const b2Vec2* normals1 = poly1->m_normals; + + int32 count2 = poly2->m_vertexCount; + const b2Vec2* vertices2 = poly2->m_vertices; + + b2Assert(0 <= edge1 && edge1 < count1); + + // Convert normal from poly1's frame into poly2's frame. + b2Vec2 normal1World = b2Mul(xf1.R, normals1[edge1]); + b2Vec2 normal1 = b2MulT(xf2.R, normal1World); + + // Find support vertex on poly2 for -normal. + int32 index = 0; + float32 minDot = b2_maxFloat; + + for (int32 i = 0; i < count2; ++i) + { + float32 dot = b2Dot(vertices2[i], normal1); + if (dot < minDot) + { + minDot = dot; + index = i; + } + } + + b2Vec2 v1 = b2Mul(xf1, vertices1[edge1]); + b2Vec2 v2 = b2Mul(xf2, vertices2[index]); + float32 separation = b2Dot(v2 - v1, normal1World); + return separation; +} + +// Find the max separation between poly1 and poly2 using edge normals from poly1. +static float32 b2FindMaxSeparation(int32* edgeIndex, + const b2PolygonShape* poly1, const b2Transform& xf1, + const b2PolygonShape* poly2, const b2Transform& xf2) +{ + int32 count1 = poly1->m_vertexCount; + const b2Vec2* normals1 = poly1->m_normals; + + // Vector pointing from the centroid of poly1 to the centroid of poly2. + b2Vec2 d = b2Mul(xf2, poly2->m_centroid) - b2Mul(xf1, poly1->m_centroid); + b2Vec2 dLocal1 = b2MulT(xf1.R, d); + + // Find edge normal on poly1 that has the largest projection onto d. + int32 edge = 0; + float32 maxDot = -b2_maxFloat; + for (int32 i = 0; i < count1; ++i) + { + float32 dot = b2Dot(normals1[i], dLocal1); + if (dot > maxDot) + { + maxDot = dot; + edge = i; + } + } + + // Get the separation for the edge normal. + float32 s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2); + + // Check the separation for the previous edge normal. + int32 prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1; + float32 sPrev = b2EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2); + + // Check the separation for the next edge normal. + int32 nextEdge = edge + 1 < count1 ? edge + 1 : 0; + float32 sNext = b2EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2); + + // Find the best edge and the search direction. + int32 bestEdge; + float32 bestSeparation; + int32 increment; + if (sPrev > s && sPrev > sNext) + { + increment = -1; + bestEdge = prevEdge; + bestSeparation = sPrev; + } + else if (sNext > s) + { + increment = 1; + bestEdge = nextEdge; + bestSeparation = sNext; + } + else + { + *edgeIndex = edge; + return s; + } + + // Perform a local search for the best edge normal. + for ( ; ; ) + { + if (increment == -1) + edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; + else + edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0; + + s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2); + + if (s > bestSeparation) + { + bestEdge = edge; + bestSeparation = s; + } + else + { + break; + } + } + + *edgeIndex = bestEdge; + return bestSeparation; +} + +static void b2FindIncidentEdge(b2ClipVertex c[2], + const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1, + const b2PolygonShape* poly2, const b2Transform& xf2) +{ + int32 count1 = poly1->m_vertexCount; + const b2Vec2* normals1 = poly1->m_normals; + + int32 count2 = poly2->m_vertexCount; + const b2Vec2* vertices2 = poly2->m_vertices; + const b2Vec2* normals2 = poly2->m_normals; + + b2Assert(0 <= edge1 && edge1 < count1); + + // Get the normal of the reference edge in poly2's frame. + b2Vec2 normal1 = b2MulT(xf2.R, b2Mul(xf1.R, normals1[edge1])); + + // Find the incident edge on poly2. + int32 index = 0; + float32 minDot = b2_maxFloat; + for (int32 i = 0; i < count2; ++i) + { + float32 dot = b2Dot(normal1, normals2[i]); + if (dot < minDot) + { + minDot = dot; + index = i; + } + } + + // Build the clip vertices for the incident edge. + int32 i1 = index; + int32 i2 = i1 + 1 < count2 ? i1 + 1 : 0; + + c[0].v = b2Mul(xf2, vertices2[i1]); + c[0].id.features.referenceEdge = (uint8)edge1; + c[0].id.features.incidentEdge = (uint8)i1; + c[0].id.features.incidentVertex = 0; + + c[1].v = b2Mul(xf2, vertices2[i2]); + c[1].id.features.referenceEdge = (uint8)edge1; + c[1].id.features.incidentEdge = (uint8)i2; + c[1].id.features.incidentVertex = 1; +} + +// Find edge normal of max separation on A - return if separating axis is found +// Find edge normal of max separation on B - return if separation axis is found +// Choose reference edge as min(minA, minB) +// Find incident edge +// Clip + +// The normal points from 1 to 2 +void b2CollidePolygons(b2Manifold* manifold, + const b2PolygonShape* polyA, const b2Transform& xfA, + const b2PolygonShape* polyB, const b2Transform& xfB) +{ + manifold->pointCount = 0; + float32 totalRadius = polyA->m_radius + polyB->m_radius; + + int32 edgeA = 0; + float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB); + if (separationA > totalRadius) + return; + + int32 edgeB = 0; + float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA); + if (separationB > totalRadius) + return; + + const b2PolygonShape* poly1; // reference polygon + const b2PolygonShape* poly2; // incident polygon + b2Transform xf1, xf2; + int32 edge1; // reference edge + uint8 flip; + const float32 k_relativeTol = 0.98f; + const float32 k_absoluteTol = 0.001f; + + if (separationB > k_relativeTol * separationA + k_absoluteTol) + { + poly1 = polyB; + poly2 = polyA; + xf1 = xfB; + xf2 = xfA; + edge1 = edgeB; + manifold->type = b2Manifold::e_faceB; + flip = 1; + } + else + { + poly1 = polyA; + poly2 = polyB; + xf1 = xfA; + xf2 = xfB; + edge1 = edgeA; + manifold->type = b2Manifold::e_faceA; + flip = 0; + } + + b2ClipVertex incidentEdge[2]; + b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); + + int32 count1 = poly1->m_vertexCount; + const b2Vec2* vertices1 = poly1->m_vertices; + + b2Vec2 v11 = vertices1[edge1]; + b2Vec2 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0]; + + b2Vec2 localTangent = v12 - v11; + localTangent.Normalize(); + + b2Vec2 localNormal = b2Cross(localTangent, 1.0f); + b2Vec2 planePoint = 0.5f * (v11 + v12); + + b2Vec2 tangent = b2Mul(xf1.R, localTangent); + b2Vec2 normal = b2Cross(tangent, 1.0f); + + v11 = b2Mul(xf1, v11); + v12 = b2Mul(xf1, v12); + + // Face offset. + float32 frontOffset = b2Dot(normal, v11); + + // Side offsets, extended by polytope skin thickness. + float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius; + float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius; + + // Clip incident edge against extruded edge1 side edges. + b2ClipVertex clipPoints1[2]; + b2ClipVertex clipPoints2[2]; + int np; + + // Clip to box side 1 + np = b2ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1); + + if (np < 2) + return; + + // Clip to negative box side 1 + np = b2ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); + + if (np < 2) + { + return; + } + + // Now clipPoints2 contains the clipped points. + manifold->localNormal = localNormal; + manifold->localPoint = planePoint; + + int32 pointCount = 0; + for (int32 i = 0; i < b2_maxManifoldPoints; ++i) + { + float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset; + + if (separation <= totalRadius) + { + b2ManifoldPoint* cp = manifold->points + pointCount; + cp->localPoint = b2MulT(xf2, clipPoints2[i].v); + cp->id = clipPoints2[i].id; + cp->id.features.flip = flip; + ++pointCount; + } + } + + manifold->pointCount = pointCount; +} diff --git a/AndEngine/jni/Box2D/Collision/b2Collision.cpp b/AndEngine/jni/Box2D/Collision/b2Collision.cpp new file mode 100644 index 0000000..6af5afe --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2Collision.cpp @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/b2Distance.h" + +void b2WorldManifold::Initialize(const b2Manifold* manifold, + const b2Transform& xfA, float32 radiusA, + const b2Transform& xfB, float32 radiusB) +{ + if (manifold->pointCount == 0) + { + return; + } + + switch (manifold->type) + { + case b2Manifold::e_circles: + { + normal.Set(1.0f, 0.0f); + b2Vec2 pointA = b2Mul(xfA, manifold->localPoint); + b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint); + if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon) + { + normal = pointB - pointA; + normal.Normalize(); + } + + b2Vec2 cA = pointA + radiusA * normal; + b2Vec2 cB = pointB - radiusB * normal; + points[0] = 0.5f * (cA + cB); + } + break; + + case b2Manifold::e_faceA: + { + normal = b2Mul(xfA.R, manifold->localNormal); + b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint); + + for (int32 i = 0; i < manifold->pointCount; ++i) + { + b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint); + b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal; + b2Vec2 cB = clipPoint - radiusB * normal; + points[i] = 0.5f * (cA + cB); + } + } + break; + + case b2Manifold::e_faceB: + { + normal = b2Mul(xfB.R, manifold->localNormal); + b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint); + + for (int32 i = 0; i < manifold->pointCount; ++i) + { + b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint); + b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal; + b2Vec2 cA = clipPoint - radiusA * normal; + points[i] = 0.5f * (cA + cB); + } + + // Ensure normal points from A to B. + normal = -normal; + } + break; + } +} + +void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], + const b2Manifold* manifold1, const b2Manifold* manifold2) +{ + for (int32 i = 0; i < b2_maxManifoldPoints; ++i) + { + state1[i] = b2_nullState; + state2[i] = b2_nullState; + } + + // Detect persists and removes. + for (int32 i = 0; i < manifold1->pointCount; ++i) + { + b2ContactID id = manifold1->points[i].id; + + state1[i] = b2_removeState; + + for (int32 j = 0; j < manifold2->pointCount; ++j) + { + if (manifold2->points[j].id.key == id.key) + { + state1[i] = b2_persistState; + break; + } + } + } + + // Detect persists and adds. + for (int32 i = 0; i < manifold2->pointCount; ++i) + { + b2ContactID id = manifold2->points[i].id; + + state2[i] = b2_addState; + + for (int32 j = 0; j < manifold1->pointCount; ++j) + { + if (manifold1->points[j].id.key == id.key) + { + state2[i] = b2_persistState; + break; + } + } + } +} + +// From Real-time Collision Detection, p179. +bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const +{ + float32 tmin = -b2_maxFloat; + float32 tmax = b2_maxFloat; + + b2Vec2 p = input.p1; + b2Vec2 d = input.p2 - input.p1; + b2Vec2 absD = b2Abs(d); + + b2Vec2 normal; + + for (int32 i = 0; i < 2; ++i) + { + if (absD(i) < b2_epsilon) + { + // Parallel. + if (p(i) < lowerBound(i) || upperBound(i) < p(i)) + { + return false; + } + } + else + { + float32 inv_d = 1.0f / d(i); + float32 t1 = (lowerBound(i) - p(i)) * inv_d; + float32 t2 = (upperBound(i) - p(i)) * inv_d; + + // Sign of the normal vector. + float32 s = -1.0f; + + if (t1 > t2) + { + b2Swap(t1, t2); + s = 1.0f; + } + + // Push the min up + if (t1 > tmin) + { + normal.SetZero(); + normal(i) = s; + tmin = t1; + } + + // Pull the max down + tmax = b2Min(tmax, t2); + + if (tmin > tmax) + { + return false; + } + } + } + + // Does the ray start inside the box? + // Does the ray intersect beyond the max fraction? + if (tmin < 0.0f || input.maxFraction < tmin) + { + return false; + } + + // Intersection. + output->fraction = tmin; + output->normal = normal; + return true; +} + +// Sutherland-Hodgman clipping. +int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], + const b2Vec2& normal, float32 offset) +{ + // Start with no output points + int32 numOut = 0; + + // Calculate the distance of end points to the line + float32 distance0 = b2Dot(normal, vIn[0].v) - offset; + float32 distance1 = b2Dot(normal, vIn[1].v) - offset; + + // If the points are behind the plane + if (distance0 <= 0.0f) vOut[numOut++] = vIn[0]; + if (distance1 <= 0.0f) vOut[numOut++] = vIn[1]; + + // If the points are on different sides of the plane + if (distance0 * distance1 < 0.0f) + { + // Find intersection point of edge and plane + float32 interp = distance0 / (distance0 - distance1); + vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v); + if (distance0 > 0.0f) + { + vOut[numOut].id = vIn[0].id; + } + else + { + vOut[numOut].id = vIn[1].id; + } + ++numOut; + } + + return numOut; +} + +bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB, + const b2Transform& xfA, const b2Transform& xfB) +{ + b2DistanceInput input; + input.proxyA.Set(shapeA); + input.proxyB.Set(shapeB); + input.transformA = xfA; + input.transformB = xfB; + input.useRadii = true; + + b2SimplexCache cache; + cache.count = 0; + + b2DistanceOutput output; + + b2Distance(&output, &cache, &input); + + return output.distance < 10.0f * b2_epsilon; +} diff --git a/AndEngine/jni/Box2D/Collision/b2Collision.h b/AndEngine/jni/Box2D/Collision/b2Collision.h new file mode 100644 index 0000000..567530b --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2Collision.h @@ -0,0 +1,240 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_COLLISION_H +#define B2_COLLISION_H + +#include "Box2D/Common/b2Math.h" +#include + +/// @file +/// Structures and functions used for computing contact points, distance +/// queries, and TOI queries. + +class b2Shape; +class b2CircleShape; +class b2PolygonShape; + +const uint8 b2_nullFeature = UCHAR_MAX; + +/// Contact ids to facilitate warm starting. +union b2ContactID +{ + /// The features that intersect to form the contact point + struct Features + { + uint8 referenceEdge; ///< The edge that defines the outward contact normal. + uint8 incidentEdge; ///< The edge most anti-parallel to the reference edge. + uint8 incidentVertex; ///< The vertex (0 or 1) on the incident edge that was clipped. + uint8 flip; ///< A value of 1 indicates that the reference edge is on shape2. + } features; + uint32 key; ///< Used to quickly compare contact ids. +}; + +/// A manifold point is a contact point belonging to a contact +/// manifold. It holds details related to the geometry and dynamics +/// of the contact points. +/// The local point usage depends on the manifold type: +/// -e_circles: the local center of circleB +/// -e_faceA: the local center of cirlceB or the clip point of polygonB +/// -e_faceB: the clip point of polygonA +/// This structure is stored across time steps, so we keep it small. +/// Note: the impulses are used for internal caching and may not +/// provide reliable contact forces, especially for high speed collisions. +struct b2ManifoldPoint +{ + b2Vec2 localPoint; ///< usage depends on manifold type + float32 normalImpulse; ///< the non-penetration impulse + float32 tangentImpulse; ///< the friction impulse + b2ContactID id; ///< uniquely identifies a contact point between two shapes +}; + +/// A manifold for two touching convex shapes. +/// Box2D supports multiple types of contact: +/// - clip point versus plane with radius +/// - point versus point with radius (circles) +/// The local point usage depends on the manifold type: +/// -e_circles: the local center of circleA +/// -e_faceA: the center of faceA +/// -e_faceB: the center of faceB +/// Similarly the local normal usage: +/// -e_circles: not used +/// -e_faceA: the normal on polygonA +/// -e_faceB: the normal on polygonB +/// We store contacts in this way so that position correction can +/// account for movement, which is critical for continuous physics. +/// All contact scenarios must be expressed in one of these types. +/// This structure is stored across time steps, so we keep it small. +struct b2Manifold +{ + enum Type + { + e_circles, + e_faceA, + e_faceB + }; + + b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact + b2Vec2 localNormal; ///< not use for Type::e_points + b2Vec2 localPoint; ///< usage depends on manifold type + Type type; + int32 pointCount; ///< the number of manifold points +}; + +/// This is used to compute the current state of a contact manifold. +struct b2WorldManifold +{ + /// Evaluate the manifold with supplied transforms. This assumes + /// modest motion from the original state. This does not change the + /// point count, impulses, etc. The radii must come from the shapes + /// that generated the manifold. + void Initialize(const b2Manifold* manifold, + const b2Transform& xfA, float32 radiusA, + const b2Transform& xfB, float32 radiusB); + + b2Vec2 normal; ///< world vector pointing from A to B + b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection) +}; + +/// This is used for determining the state of contact points. +enum b2PointState +{ + b2_nullState, ///< point does not exist + b2_addState, ///< point was added in the update + b2_persistState, ///< point persisted across the update + b2_removeState ///< point was removed in the update +}; + +/// Compute the point states given two manifolds. The states pertain to the transition from manifold1 +/// to manifold2. So state1 is either persist or remove while state2 is either add or persist. +void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], + const b2Manifold* manifold1, const b2Manifold* manifold2); + +/// Used for computing contact manifolds. +struct b2ClipVertex +{ + b2Vec2 v; + b2ContactID id; +}; + +/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). +struct b2RayCastInput +{ + b2Vec2 p1, p2; + float32 maxFraction; +}; + +/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 +/// come from b2RayCastInput. +struct b2RayCastOutput +{ + b2Vec2 normal; + float32 fraction; +}; + +/// An axis aligned bounding box. +struct b2AABB +{ + /// Verify that the bounds are sorted. + bool IsValid() const; + + /// Get the center of the AABB. + b2Vec2 GetCenter() const + { + return 0.5f * (lowerBound + upperBound); + } + + /// Get the extents of the AABB (half-widths). + b2Vec2 GetExtents() const + { + return 0.5f * (upperBound - lowerBound); + } + + /// Combine two AABBs into this one. + void Combine(const b2AABB& aabb1, const b2AABB& aabb2) + { + lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound); + upperBound = b2Max(aabb1.upperBound, aabb2.upperBound); + } + + /// Does this aabb contain the provided AABB. + bool Contains(const b2AABB& aabb) const + { + bool result = true; + result = result && lowerBound.x <= aabb.lowerBound.x; + result = result && lowerBound.y <= aabb.lowerBound.y; + result = result && aabb.upperBound.x <= upperBound.x; + result = result && aabb.upperBound.y <= upperBound.y; + return result; + } + + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; + + b2Vec2 lowerBound; ///< the lower vertex + b2Vec2 upperBound; ///< the upper vertex +}; + +/// Compute the collision manifold between two circles. +void b2CollideCircles(b2Manifold* manifold, + const b2CircleShape* circle1, const b2Transform& xf1, + const b2CircleShape* circle2, const b2Transform& xf2); + +/// Compute the collision manifold between a polygon and a circle. +void b2CollidePolygonAndCircle(b2Manifold* manifold, + const b2PolygonShape* polygon, const b2Transform& xf1, + const b2CircleShape* circle, const b2Transform& xf2); + +/// Compute the collision manifold between two polygons. +void b2CollidePolygons(b2Manifold* manifold, + const b2PolygonShape* polygon1, const b2Transform& xf1, + const b2PolygonShape* polygon2, const b2Transform& xf2); + +/// Clipping for contact manifolds. +int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], + const b2Vec2& normal, float32 offset); + +/// Determine if two generic shapes overlap. +bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB, + const b2Transform& xfA, const b2Transform& xfB); + +// ---------------- Inline Functions ------------------------------------------ + +inline bool b2AABB::IsValid() const +{ + b2Vec2 d = upperBound - lowerBound; + bool valid = d.x >= 0.0f && d.y >= 0.0f; + valid = valid && lowerBound.IsValid() && upperBound.IsValid(); + return valid; +} + +inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b) +{ + b2Vec2 d1, d2; + d1 = b.lowerBound - a.upperBound; + d2 = a.lowerBound - b.upperBound; + + if (d1.x > 0.0f || d1.y > 0.0f) + return false; + + if (d2.x > 0.0f || d2.y > 0.0f) + return false; + + return true; +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/b2Distance.cpp b/AndEngine/jni/Box2D/Collision/b2Distance.cpp new file mode 100644 index 0000000..9160eb7 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2Distance.cpp @@ -0,0 +1,571 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2Distance.h" +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" + +// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates. +int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; + +void b2DistanceProxy::Set(const b2Shape* shape) +{ + switch (shape->GetType()) + { + case b2Shape::e_circle: + { + const b2CircleShape* circle = (b2CircleShape*)shape; + m_vertices = &circle->m_p; + m_count = 1; + m_radius = circle->m_radius; + } + break; + + case b2Shape::e_polygon: + { + const b2PolygonShape* polygon = (b2PolygonShape*)shape; + m_vertices = polygon->m_vertices; + m_count = polygon->m_vertexCount; + m_radius = polygon->m_radius; + } + break; + + default: + b2Assert(false); + } +} + + +struct b2SimplexVertex +{ + b2Vec2 wA; // support point in proxyA + b2Vec2 wB; // support point in proxyB + b2Vec2 w; // wB - wA + float32 a; // barycentric coordinate for closest point + int32 indexA; // wA index + int32 indexB; // wB index +}; + +struct b2Simplex +{ + void ReadCache( const b2SimplexCache* cache, + const b2DistanceProxy* proxyA, const b2Transform& transformA, + const b2DistanceProxy* proxyB, const b2Transform& transformB) + { + b2Assert(cache->count <= 3); + + // Copy data from cache. + m_count = cache->count; + b2SimplexVertex* vertices = &m_v1; + for (int32 i = 0; i < m_count; ++i) + { + b2SimplexVertex* v = vertices + i; + v->indexA = cache->indexA[i]; + v->indexB = cache->indexB[i]; + b2Vec2 wALocal = proxyA->GetVertex(v->indexA); + b2Vec2 wBLocal = proxyB->GetVertex(v->indexB); + v->wA = b2Mul(transformA, wALocal); + v->wB = b2Mul(transformB, wBLocal); + v->w = v->wB - v->wA; + v->a = 0.0f; + } + + // Compute the new simplex metric, if it is substantially different than + // old metric then flush the simplex. + if (m_count > 1) + { + float32 metric1 = cache->metric; + float32 metric2 = GetMetric(); + if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon) + { + // Reset the simplex. + m_count = 0; + } + } + + // If the cache is empty or invalid ... + if (m_count == 0) + { + b2SimplexVertex* v = vertices + 0; + v->indexA = 0; + v->indexB = 0; + b2Vec2 wALocal = proxyA->GetVertex(0); + b2Vec2 wBLocal = proxyB->GetVertex(0); + v->wA = b2Mul(transformA, wALocal); + v->wB = b2Mul(transformB, wBLocal); + v->w = v->wB - v->wA; + m_count = 1; + } + } + + void WriteCache(b2SimplexCache* cache) const + { + cache->metric = GetMetric(); + cache->count = uint16(m_count); + const b2SimplexVertex* vertices = &m_v1; + for (int32 i = 0; i < m_count; ++i) + { + cache->indexA[i] = uint8(vertices[i].indexA); + cache->indexB[i] = uint8(vertices[i].indexB); + } + } + + b2Vec2 GetSearchDirection() const + { + switch (m_count) + { + case 1: + return -m_v1.w; + + case 2: + { + b2Vec2 e12 = m_v2.w - m_v1.w; + float32 sgn = b2Cross(e12, -m_v1.w); + if (sgn > 0.0f) + { + // Origin is left of e12. + return b2Cross(1.0f, e12); + } + else + { + // Origin is right of e12. + return b2Cross(e12, 1.0f); + } + } + + default: + b2Assert(false); + return b2Vec2_zero; + } + } + + b2Vec2 GetClosestPoint() const + { + switch (m_count) + { + case 0: + b2Assert(false); + return b2Vec2_zero; + + case 1: + return m_v1.w; + + case 2: + return m_v1.a * m_v1.w + m_v2.a * m_v2.w; + + case 3: + return b2Vec2_zero; + + default: + b2Assert(false); + return b2Vec2_zero; + } + } + + void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const + { + switch (m_count) + { + case 0: + b2Assert(false); + break; + + case 1: + *pA = m_v1.wA; + *pB = m_v1.wB; + break; + + case 2: + *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA; + *pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB; + break; + + case 3: + *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA; + *pB = *pA; + break; + + default: + b2Assert(false); + break; + } + } + + float32 GetMetric() const + { + switch (m_count) + { + case 0: + b2Assert(false); + return 0.0; + + case 1: + return 0.0f; + + case 2: + return b2Distance(m_v1.w, m_v2.w); + + case 3: + return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w); + + default: + b2Assert(false); + return 0.0f; + } + } + + void Solve2(); + void Solve3(); + + b2SimplexVertex m_v1, m_v2, m_v3; + int32 m_count; +}; + + +// Solve a line segment using barycentric coordinates. +// +// p = a1 * w1 + a2 * w2 +// a1 + a2 = 1 +// +// The vector from the origin to the closest point on the line is +// perpendicular to the line. +// e12 = w2 - w1 +// dot(p, e) = 0 +// a1 * dot(w1, e) + a2 * dot(w2, e) = 0 +// +// 2-by-2 linear system +// [1 1 ][a1] = [1] +// [w1.e12 w2.e12][a2] = [0] +// +// Define +// d12_1 = dot(w2, e12) +// d12_2 = -dot(w1, e12) +// d12 = d12_1 + d12_2 +// +// Solution +// a1 = d12_1 / d12 +// a2 = d12_2 / d12 +void b2Simplex::Solve2() +{ + b2Vec2 w1 = m_v1.w; + b2Vec2 w2 = m_v2.w; + b2Vec2 e12 = w2 - w1; + + // w1 region + float32 d12_2 = -b2Dot(w1, e12); + if (d12_2 <= 0.0f) + { + // a2 <= 0, so we clamp it to 0 + m_v1.a = 1.0f; + m_count = 1; + return; + } + + // w2 region + float32 d12_1 = b2Dot(w2, e12); + if (d12_1 <= 0.0f) + { + // a1 <= 0, so we clamp it to 0 + m_v2.a = 1.0f; + m_count = 1; + m_v1 = m_v2; + return; + } + + // Must be in e12 region. + float32 inv_d12 = 1.0f / (d12_1 + d12_2); + m_v1.a = d12_1 * inv_d12; + m_v2.a = d12_2 * inv_d12; + m_count = 2; +} + +// Possible regions: +// - points[2] +// - edge points[0]-points[2] +// - edge points[1]-points[2] +// - inside the triangle +void b2Simplex::Solve3() +{ + b2Vec2 w1 = m_v1.w; + b2Vec2 w2 = m_v2.w; + b2Vec2 w3 = m_v3.w; + + // Edge12 + // [1 1 ][a1] = [1] + // [w1.e12 w2.e12][a2] = [0] + // a3 = 0 + b2Vec2 e12 = w2 - w1; + float32 w1e12 = b2Dot(w1, e12); + float32 w2e12 = b2Dot(w2, e12); + float32 d12_1 = w2e12; + float32 d12_2 = -w1e12; + + // Edge13 + // [1 1 ][a1] = [1] + // [w1.e13 w3.e13][a3] = [0] + // a2 = 0 + b2Vec2 e13 = w3 - w1; + float32 w1e13 = b2Dot(w1, e13); + float32 w3e13 = b2Dot(w3, e13); + float32 d13_1 = w3e13; + float32 d13_2 = -w1e13; + + // Edge23 + // [1 1 ][a2] = [1] + // [w2.e23 w3.e23][a3] = [0] + // a1 = 0 + b2Vec2 e23 = w3 - w2; + float32 w2e23 = b2Dot(w2, e23); + float32 w3e23 = b2Dot(w3, e23); + float32 d23_1 = w3e23; + float32 d23_2 = -w2e23; + + // Triangle123 + float32 n123 = b2Cross(e12, e13); + + float32 d123_1 = n123 * b2Cross(w2, w3); + float32 d123_2 = n123 * b2Cross(w3, w1); + float32 d123_3 = n123 * b2Cross(w1, w2); + + // w1 region + if (d12_2 <= 0.0f && d13_2 <= 0.0f) + { + m_v1.a = 1.0f; + m_count = 1; + return; + } + + // e12 + if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f) + { + float32 inv_d12 = 1.0f / (d12_1 + d12_2); + m_v1.a = d12_1 * inv_d12; + m_v2.a = d12_2 * inv_d12; + m_count = 2; + return; + } + + // e13 + if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f) + { + float32 inv_d13 = 1.0f / (d13_1 + d13_2); + m_v1.a = d13_1 * inv_d13; + m_v3.a = d13_2 * inv_d13; + m_count = 2; + m_v2 = m_v3; + return; + } + + // w2 region + if (d12_1 <= 0.0f && d23_2 <= 0.0f) + { + m_v2.a = 1.0f; + m_count = 1; + m_v1 = m_v2; + return; + } + + // w3 region + if (d13_1 <= 0.0f && d23_1 <= 0.0f) + { + m_v3.a = 1.0f; + m_count = 1; + m_v1 = m_v3; + return; + } + + // e23 + if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f) + { + float32 inv_d23 = 1.0f / (d23_1 + d23_2); + m_v2.a = d23_1 * inv_d23; + m_v3.a = d23_2 * inv_d23; + m_count = 2; + m_v1 = m_v3; + return; + } + + // Must be in triangle123 + float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3); + m_v1.a = d123_1 * inv_d123; + m_v2.a = d123_2 * inv_d123; + m_v3.a = d123_3 * inv_d123; + m_count = 3; +} + +void b2Distance(b2DistanceOutput* output, + b2SimplexCache* cache, + const b2DistanceInput* input) +{ + ++b2_gjkCalls; + + const b2DistanceProxy* proxyA = &input->proxyA; + const b2DistanceProxy* proxyB = &input->proxyB; + + b2Transform transformA = input->transformA; + b2Transform transformB = input->transformB; + + // Initialize the simplex. + b2Simplex simplex; + simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); + + // Get simplex vertices as an array. + b2SimplexVertex* vertices = &simplex.m_v1; + const int32 k_maxIters = 20; + + // These store the vertices of the last simplex so that we + // can check for duplicates and prevent cycling. + int32 saveA[3], saveB[3]; + int32 saveCount = 0; + + b2Vec2 closestPoint = simplex.GetClosestPoint(); + float32 distanceSqr1 = closestPoint.LengthSquared(); + float32 distanceSqr2 = distanceSqr1; + + // Main iteration loop. + int32 iter = 0; + while (iter < k_maxIters) + { + // Copy simplex so we can identify duplicates. + saveCount = simplex.m_count; + for (int32 i = 0; i < saveCount; ++i) + { + saveA[i] = vertices[i].indexA; + saveB[i] = vertices[i].indexB; + } + + switch (simplex.m_count) + { + case 1: + break; + + case 2: + simplex.Solve2(); + break; + + case 3: + simplex.Solve3(); + break; + + default: + b2Assert(false); + } + + // If we have 3 points, then the origin is in the corresponding triangle. + if (simplex.m_count == 3) + { + break; + } + + // Compute closest point. + b2Vec2 p = simplex.GetClosestPoint(); + distanceSqr2 = p.LengthSquared(); + + // Ensure progress + if (distanceSqr2 >= distanceSqr1) + { + //break; + } + distanceSqr1 = distanceSqr2; + + // Get search direction. + b2Vec2 d = simplex.GetSearchDirection(); + + // Ensure the search direction is numerically fit. + if (d.LengthSquared() < b2_epsilon * b2_epsilon) + { + // The origin is probably contained by a line segment + // or triangle. Thus the shapes are overlapped. + + // We can't return zero here even though there may be overlap. + // In case the simplex is a point, segment, or triangle it is difficult + // to determine if the origin is contained in the CSO or very close to it. + break; + } + + // Compute a tentative new simplex vertex using support points. + b2SimplexVertex* vertex = vertices + simplex.m_count; + vertex->indexA = proxyA->GetSupport(b2MulT(transformA.R, -d)); + vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA)); + b2Vec2 wBLocal; + vertex->indexB = proxyB->GetSupport(b2MulT(transformB.R, d)); + vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB)); + vertex->w = vertex->wB - vertex->wA; + + // Iteration count is equated to the number of support point calls. + ++iter; + ++b2_gjkIters; + + // Check for duplicate support points. This is the main termination criteria. + bool duplicate = false; + for (int32 i = 0; i < saveCount; ++i) + { + if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i]) + { + duplicate = true; + break; + } + } + + // If we found a duplicate support point we must exit to avoid cycling. + if (duplicate) + { + break; + } + + // New vertex is ok and needed. + ++simplex.m_count; + } + + b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter); + + // Prepare output. + simplex.GetWitnessPoints(&output->pointA, &output->pointB); + output->distance = b2Distance(output->pointA, output->pointB); + output->iterations = iter; + + // Cache the simplex. + simplex.WriteCache(cache); + + // Apply radii if requested. + if (input->useRadii) + { + float32 rA = proxyA->m_radius; + float32 rB = proxyB->m_radius; + + if (output->distance > rA + rB && output->distance > b2_epsilon) + { + // Shapes are still no overlapped. + // Move the witness points to the outer surface. + output->distance -= rA + rB; + b2Vec2 normal = output->pointB - output->pointA; + normal.Normalize(); + output->pointA += rA * normal; + output->pointB -= rB * normal; + } + else + { + // Shapes are overlapped when radii are considered. + // Move the witness points to the middle. + b2Vec2 p = 0.5f * (output->pointA + output->pointB); + output->pointA = p; + output->pointB = p; + output->distance = 0.0f; + } + } +} diff --git a/AndEngine/jni/Box2D/Collision/b2Distance.h b/AndEngine/jni/Box2D/Collision/b2Distance.h new file mode 100644 index 0000000..83fda23 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2Distance.h @@ -0,0 +1,141 @@ + +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_DISTANCE_H +#define B2_DISTANCE_H + +#include "Box2D/Common/b2Math.h" +#include + +class b2Shape; + +/// A distance proxy is used by the GJK algorithm. +/// It encapsulates any shape. +struct b2DistanceProxy +{ + b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {} + + /// Initialize the proxy using the given shape. The shape + /// must remain in scope while the proxy is in use. + void Set(const b2Shape* shape); + + /// Get the supporting vertex index in the given direction. + int32 GetSupport(const b2Vec2& d) const; + + /// Get the supporting vertex in the given direction. + const b2Vec2& GetSupportVertex(const b2Vec2& d) const; + + /// Get the vertex count. + int32 GetVertexCount() const; + + /// Get a vertex by index. Used by b2Distance. + const b2Vec2& GetVertex(int32 index) const; + + const b2Vec2* m_vertices; + int32 m_count; + float32 m_radius; +}; + +/// Used to warm start b2Distance. +/// Set count to zero on first call. +struct b2SimplexCache +{ + float32 metric; ///< length or area + uint16 count; + uint8 indexA[3]; ///< vertices on shape A + uint8 indexB[3]; ///< vertices on shape B +}; + +/// Input for b2Distance. +/// You have to option to use the shape radii +/// in the computation. Even +struct b2DistanceInput +{ + b2DistanceProxy proxyA; + b2DistanceProxy proxyB; + b2Transform transformA; + b2Transform transformB; + bool useRadii; +}; + +/// Output for b2Distance. +struct b2DistanceOutput +{ + b2Vec2 pointA; ///< closest point on shapeA + b2Vec2 pointB; ///< closest point on shapeB + float32 distance; + int32 iterations; ///< number of GJK iterations used +}; + +/// Compute the closest points between two shapes. Supports any combination of: +/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output. +/// On the first call set b2SimplexCache.count to zero. +void b2Distance(b2DistanceOutput* output, + b2SimplexCache* cache, + const b2DistanceInput* input); + + +////////////////////////////////////////////////////////////////////////// + +inline int32 b2DistanceProxy::GetVertexCount() const +{ + return m_count; +} + +inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const +{ + b2Assert(0 <= index && index < m_count); + return m_vertices[index]; +} + +inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float32 bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_count; ++i) + { + float32 value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return bestIndex; +} + +inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float32 bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_count; ++i) + { + float32 value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return m_vertices[bestIndex]; +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/b2DynamicTree.cpp b/AndEngine/jni/Box2D/Collision/b2DynamicTree.cpp new file mode 100644 index 0000000..f0e23b6 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2DynamicTree.cpp @@ -0,0 +1,365 @@ +/* +* Copyright (c) 2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2DynamicTree.h" +#include +#include + +b2DynamicTree::b2DynamicTree() +{ + m_root = b2_nullNode; + + m_nodeCapacity = 16; + m_nodeCount = 0; + m_nodes = (b2DynamicTreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2DynamicTreeNode)); + memset(m_nodes, 0, m_nodeCapacity * sizeof(b2DynamicTreeNode)); + + // Build a linked list for the free list. + for (int32 i = 0; i < m_nodeCapacity - 1; ++i) + { + m_nodes[i].next = i + 1; + } + m_nodes[m_nodeCapacity-1].next = b2_nullNode; + m_freeList = 0; + + m_path = 0; + + m_insertionCount = 0; +} + +b2DynamicTree::~b2DynamicTree() +{ + // This frees the entire tree in one shot. + b2Free(m_nodes); +} + +// Allocate a node from the pool. Grow the pool if necessary. +int32 b2DynamicTree::AllocateNode() +{ + // Expand the node pool as needed. + if (m_freeList == b2_nullNode) + { + b2Assert(m_nodeCount == m_nodeCapacity); + + // The free list is empty. Rebuild a bigger pool. + b2DynamicTreeNode* oldNodes = m_nodes; + m_nodeCapacity *= 2; + m_nodes = (b2DynamicTreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2DynamicTreeNode)); + memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2DynamicTreeNode)); + b2Free(oldNodes); + + // Build a linked list for the free list. The parent + // pointer becomes the "next" pointer. + for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i) + { + m_nodes[i].next = i + 1; + } + m_nodes[m_nodeCapacity-1].next = b2_nullNode; + m_freeList = m_nodeCount; + } + + // Peel a node off the free list. + int32 nodeId = m_freeList; + m_freeList = m_nodes[nodeId].next; + m_nodes[nodeId].parent = b2_nullNode; + m_nodes[nodeId].child1 = b2_nullNode; + m_nodes[nodeId].child2 = b2_nullNode; + ++m_nodeCount; + return nodeId; +} + +// Return a node to the pool. +void b2DynamicTree::FreeNode(int32 nodeId) +{ + b2Assert(0 <= nodeId && nodeId < m_nodeCapacity); + b2Assert(0 < m_nodeCount); + m_nodes[nodeId].next = m_freeList; + m_freeList = nodeId; + --m_nodeCount; +} + +// Create a proxy in the tree as a leaf node. We return the index +// of the node instead of a pointer so that we can grow +// the node pool. +int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData) +{ + int32 proxyId = AllocateNode(); + + // Fatten the aabb. + b2Vec2 r(b2_aabbExtension, b2_aabbExtension); + m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r; + m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r; + m_nodes[proxyId].userData = userData; + + InsertLeaf(proxyId); + + // Rebalance if necessary. + int32 iterationCount = m_nodeCount >> 4; + int32 tryCount = 0; + int32 height = ComputeHeight(); + while (height > 64 && tryCount < 10) + { + Rebalance(iterationCount); + height = ComputeHeight(); + ++tryCount; + } + + return proxyId; +} + +void b2DynamicTree::DestroyProxy(int32 proxyId) +{ + b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); + b2Assert(m_nodes[proxyId].IsLeaf()); + + RemoveLeaf(proxyId); + FreeNode(proxyId); +} + +bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement) +{ + b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); + + b2Assert(m_nodes[proxyId].IsLeaf()); + + if (m_nodes[proxyId].aabb.Contains(aabb)) + { + return false; + } + + RemoveLeaf(proxyId); + + // Extend AABB. + b2AABB b = aabb; + b2Vec2 r(b2_aabbExtension, b2_aabbExtension); + b.lowerBound = b.lowerBound - r; + b.upperBound = b.upperBound + r; + + // Predict AABB displacement. + b2Vec2 d = b2_aabbMultiplier * displacement; + + if (d.x < 0.0f) + { + b.lowerBound.x += d.x; + } + else + { + b.upperBound.x += d.x; + } + + if (d.y < 0.0f) + { + b.lowerBound.y += d.y; + } + else + { + b.upperBound.y += d.y; + } + + m_nodes[proxyId].aabb = b; + + InsertLeaf(proxyId); + return true; +} + +void b2DynamicTree::InsertLeaf(int32 leaf) +{ + ++m_insertionCount; + + if (m_root == b2_nullNode) + { + m_root = leaf; + m_nodes[m_root].parent = b2_nullNode; + return; + } + + // Find the best sibling for this node. + b2Vec2 center = m_nodes[leaf].aabb.GetCenter(); + int32 sibling = m_root; + if (m_nodes[sibling].IsLeaf() == false) + { + do + { + int32 child1 = m_nodes[sibling].child1; + int32 child2 = m_nodes[sibling].child2; + + b2Vec2 delta1 = b2Abs(m_nodes[child1].aabb.GetCenter() - center); + b2Vec2 delta2 = b2Abs(m_nodes[child2].aabb.GetCenter() - center); + + float32 norm1 = delta1.x + delta1.y; + float32 norm2 = delta2.x + delta2.y; + + if (norm1 < norm2) + { + sibling = child1; + } + else + { + sibling = child2; + } + + } + while(m_nodes[sibling].IsLeaf() == false); + } + + // Create a parent for the siblings. + int32 node1 = m_nodes[sibling].parent; + int32 node2 = AllocateNode(); + m_nodes[node2].parent = node1; + m_nodes[node2].userData = NULL; + m_nodes[node2].aabb.Combine(m_nodes[leaf].aabb, m_nodes[sibling].aabb); + + if (node1 != b2_nullNode) + { + if (m_nodes[m_nodes[sibling].parent].child1 == sibling) + { + m_nodes[node1].child1 = node2; + } + else + { + m_nodes[node1].child2 = node2; + } + + m_nodes[node2].child1 = sibling; + m_nodes[node2].child2 = leaf; + m_nodes[sibling].parent = node2; + m_nodes[leaf].parent = node2; + + do + { + if (m_nodes[node1].aabb.Contains(m_nodes[node2].aabb)) + { + break; + } + + m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb); + node2 = node1; + node1 = m_nodes[node1].parent; + } + while(node1 != b2_nullNode); + } + else + { + m_nodes[node2].child1 = sibling; + m_nodes[node2].child2 = leaf; + m_nodes[sibling].parent = node2; + m_nodes[leaf].parent = node2; + m_root = node2; + } +} + +void b2DynamicTree::RemoveLeaf(int32 leaf) +{ + if (leaf == m_root) + { + m_root = b2_nullNode; + return; + } + + int32 node2 = m_nodes[leaf].parent; + int32 node1 = m_nodes[node2].parent; + int32 sibling; + if (m_nodes[node2].child1 == leaf) + { + sibling = m_nodes[node2].child2; + } + else + { + sibling = m_nodes[node2].child1; + } + + if (node1 != b2_nullNode) + { + // Destroy node2 and connect node1 to sibling. + if (m_nodes[node1].child1 == node2) + { + m_nodes[node1].child1 = sibling; + } + else + { + m_nodes[node1].child2 = sibling; + } + m_nodes[sibling].parent = node1; + FreeNode(node2); + + // Adjust ancestor bounds. + while (node1 != b2_nullNode) + { + b2AABB oldAABB = m_nodes[node1].aabb; + m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb); + + if (oldAABB.Contains(m_nodes[node1].aabb)) + { + break; + } + + node1 = m_nodes[node1].parent; + } + } + else + { + m_root = sibling; + m_nodes[sibling].parent = b2_nullNode; + FreeNode(node2); + } +} + +void b2DynamicTree::Rebalance(int32 iterations) +{ + if (m_root == b2_nullNode) + { + return; + } + + for (int32 i = 0; i < iterations; ++i) + { + int32 node = m_root; + + uint32 bit = 0; + while (m_nodes[node].IsLeaf() == false) + { + int32* children = &m_nodes[node].child1; + node = children[(m_path >> bit) & 1]; + bit = (bit + 1) & (8* sizeof(uint32) - 1); + } + ++m_path; + + RemoveLeaf(node); + InsertLeaf(node); + } +} + +// Compute the height of a sub-tree. +int32 b2DynamicTree::ComputeHeight(int32 nodeId) const +{ + if (nodeId == b2_nullNode) + { + return 0; + } + + b2Assert(0 <= nodeId && nodeId < m_nodeCapacity); + b2DynamicTreeNode* node = m_nodes + nodeId; + int32 height1 = ComputeHeight(node->child1); + int32 height2 = ComputeHeight(node->child2); + return 1 + b2Max(height1, height2); +} + +int32 b2DynamicTree::ComputeHeight() const +{ + return ComputeHeight(m_root); +} diff --git a/AndEngine/jni/Box2D/Collision/b2DynamicTree.h b/AndEngine/jni/Box2D/Collision/b2DynamicTree.h new file mode 100644 index 0000000..1e3eee1 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2DynamicTree.h @@ -0,0 +1,286 @@ +/* +* Copyright (c) 2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_DYNAMIC_TREE_H +#define B2_DYNAMIC_TREE_H + +#include "Box2D/Collision/b2Collision.h" + +/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt. + +#define b2_nullNode (-1) + +/// A node in the dynamic tree. The client does not interact with this directly. +struct b2DynamicTreeNode +{ + bool IsLeaf() const + { + return child1 == b2_nullNode; + } + + /// This is the fattened AABB. + b2AABB aabb; + + //int32 userData; + void* userData; + + union + { + int32 parent; + int32 next; + }; + + int32 child1; + int32 child2; +}; + +/// A dynamic tree arranges data in a binary tree to accelerate +/// queries such as volume queries and ray casts. Leafs are proxies +/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor +/// so that the proxy AABB is bigger than the client object. This allows the client +/// object to move by small amounts without triggering a tree update. +/// +/// Nodes are pooled and relocatable, so we use node indices rather than pointers. +class b2DynamicTree +{ +public: + + /// Constructing the tree initializes the node pool. + b2DynamicTree(); + + /// Destroy the tree, freeing the node pool. + ~b2DynamicTree(); + + /// Create a proxy. Provide a tight fitting AABB and a userData pointer. + int32 CreateProxy(const b2AABB& aabb, void* userData); + + /// Destroy a proxy. This asserts if the id is invalid. + void DestroyProxy(int32 proxyId); + + /// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB, + /// then the proxy is removed from the tree and re-inserted. Otherwise + /// the function returns immediately. + /// @return true if the proxy was re-inserted. + bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement); + + /// Perform some iterations to re-balance the tree. + void Rebalance(int32 iterations); + + /// Get proxy user data. + /// @return the proxy user data or 0 if the id is invalid. + void* GetUserData(int32 proxyId) const; + + /// Get the fat AABB for a proxy. + const b2AABB& GetFatAABB(int32 proxyId) const; + + /// Compute the height of the tree. + int32 ComputeHeight() const; + + /// Query an AABB for overlapping proxies. The callback class + /// is called for each proxy that overlaps the supplied AABB. + template + void Query(T* callback, const b2AABB& aabb) const; + + /// Ray-cast against the proxies in the tree. This relies on the callback + /// to perform a exact ray-cast in the case were the proxy contains a shape. + /// The callback also performs the any collision filtering. This has performance + /// roughly equal to k * log(n), where k is the number of collisions and n is the + /// number of proxies in the tree. + /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). + /// @param callback a callback class that is called for each proxy that is hit by the ray. + template + void RayCast(T* callback, const b2RayCastInput& input) const; + +private: + + int32 AllocateNode(); + void FreeNode(int32 node); + + void InsertLeaf(int32 node); + void RemoveLeaf(int32 node); + + int32 ComputeHeight(int32 nodeId) const; + + int32 m_root; + + b2DynamicTreeNode* m_nodes; + int32 m_nodeCount; + int32 m_nodeCapacity; + + int32 m_freeList; + + /// This is used incrementally traverse the tree for re-balancing. + uint32 m_path; + + int32 m_insertionCount; +}; + +inline void* b2DynamicTree::GetUserData(int32 proxyId) const +{ + b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); + return m_nodes[proxyId].userData; +} + +inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const +{ + b2Assert(0 <= proxyId && proxyId < m_nodeCapacity); + return m_nodes[proxyId].aabb; +} + +template +inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const +{ + const int32 k_stackSize = 128; + int32 stack[k_stackSize]; + + int32 count = 0; + stack[count++] = m_root; + + while (count > 0) + { + int32 nodeId = stack[--count]; + if (nodeId == b2_nullNode) + { + continue; + } + + const b2DynamicTreeNode* node = m_nodes + nodeId; + + if (b2TestOverlap(node->aabb, aabb)) + { + if (node->IsLeaf()) + { + bool proceed = callback->QueryCallback(nodeId); + if (proceed == false) + { + return; + } + } + else + { + if (count < k_stackSize) + { + stack[count++] = node->child1; + } + + if (count < k_stackSize) + { + stack[count++] = node->child2; + } + } + } + } +} + +template +inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const +{ + b2Vec2 p1 = input.p1; + b2Vec2 p2 = input.p2; + b2Vec2 r = p2 - p1; + b2Assert(r.LengthSquared() > 0.0f); + r.Normalize(); + + // v is perpendicular to the segment. + b2Vec2 v = b2Cross(1.0f, r); + b2Vec2 abs_v = b2Abs(v); + + // Separating axis for segment (Gino, p80). + // |dot(v, p1 - c)| > dot(|v|, h) + + float32 maxFraction = input.maxFraction; + + // Build a bounding box for the segment. + b2AABB segmentAABB; + { + b2Vec2 t = p1 + maxFraction * (p2 - p1); + segmentAABB.lowerBound = b2Min(p1, t); + segmentAABB.upperBound = b2Max(p1, t); + } + + const int32 k_stackSize = 128; + int32 stack[k_stackSize]; + + int32 count = 0; + stack[count++] = m_root; + + while (count > 0) + { + int32 nodeId = stack[--count]; + if (nodeId == b2_nullNode) + { + continue; + } + + const b2DynamicTreeNode* node = m_nodes + nodeId; + + if (b2TestOverlap(node->aabb, segmentAABB) == false) + { + continue; + } + + // Separating axis for segment (Gino, p80). + // |dot(v, p1 - c)| > dot(|v|, h) + b2Vec2 c = node->aabb.GetCenter(); + b2Vec2 h = node->aabb.GetExtents(); + float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h); + if (separation > 0.0f) + { + continue; + } + + if (node->IsLeaf()) + { + b2RayCastInput subInput; + subInput.p1 = input.p1; + subInput.p2 = input.p2; + subInput.maxFraction = maxFraction; + + float32 value = callback->RayCastCallback(subInput, nodeId); + + if (value == 0.0f) + { + // The client has terminated the ray cast. + return; + } + + if (value > 0.0f) + { + // Update segment bounding box. + maxFraction = value; + b2Vec2 t = p1 + maxFraction * (p2 - p1); + segmentAABB.lowerBound = b2Min(p1, t); + segmentAABB.upperBound = b2Max(p1, t); + } + } + else + { + if (count < k_stackSize) + { + stack[count++] = node->child1; + } + + if (count < k_stackSize) + { + stack[count++] = node->child2; + } + } + } +} + +#endif diff --git a/AndEngine/jni/Box2D/Collision/b2TimeOfImpact.cpp b/AndEngine/jni/Box2D/Collision/b2TimeOfImpact.cpp new file mode 100644 index 0000000..39158c4 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2TimeOfImpact.cpp @@ -0,0 +1,483 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/b2Distance.h" +#include "Box2D/Collision/b2TimeOfImpact.h" +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" + +#include + +int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; +int32 b2_toiRootIters, b2_toiMaxRootIters; + +int32 b2_toiMaxOptIters; + +struct b2SeparationFunction +{ + enum Type + { + e_points, + e_faceA, + e_faceB + }; + + // TODO_ERIN might not need to return the separation + + float32 Initialize(const b2SimplexCache* cache, + const b2DistanceProxy* proxyA, const b2Sweep& sweepA, + const b2DistanceProxy* proxyB, const b2Sweep& sweepB) + { + m_proxyA = proxyA; + m_proxyB = proxyB; + int32 count = cache->count; + b2Assert(0 < count && count < 3); + + m_sweepA = sweepA; + m_sweepB = sweepB; + + b2Transform xfA, xfB; + m_sweepA.GetTransform(&xfA, 0.0f); + m_sweepB.GetTransform(&xfB, 0.0f); + + if (count == 1) + { + m_type = e_points; + b2Vec2 localPointA = m_proxyA->GetVertex(cache->indexA[0]); + b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]); + b2Vec2 pointA = b2Mul(xfA, localPointA); + b2Vec2 pointB = b2Mul(xfB, localPointB); + m_axis = pointB - pointA; + float32 s = m_axis.Normalize(); + return s; + } + else if (cache->indexA[0] == cache->indexA[1]) + { + // Two points on B and one on A. + m_type = e_faceB; + b2Vec2 localPointB1 = proxyB->GetVertex(cache->indexB[0]); + b2Vec2 localPointB2 = proxyB->GetVertex(cache->indexB[1]); + + m_axis = b2Cross(localPointB2 - localPointB1, 1.0f); + m_axis.Normalize(); + b2Vec2 normal = b2Mul(xfB.R, m_axis); + + m_localPoint = 0.5f * (localPointB1 + localPointB2); + b2Vec2 pointB = b2Mul(xfB, m_localPoint); + + b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]); + b2Vec2 pointA = b2Mul(xfA, localPointA); + + float32 s = b2Dot(pointA - pointB, normal); + if (s < 0.0f) + { + m_axis = -m_axis; + s = -s; + } + return s; + } + else + { + // Two points on A and one or two points on B. + m_type = e_faceA; + b2Vec2 localPointA1 = m_proxyA->GetVertex(cache->indexA[0]); + b2Vec2 localPointA2 = m_proxyA->GetVertex(cache->indexA[1]); + + m_axis = b2Cross(localPointA2 - localPointA1, 1.0f); + m_axis.Normalize(); + b2Vec2 normal = b2Mul(xfA.R, m_axis); + + m_localPoint = 0.5f * (localPointA1 + localPointA2); + b2Vec2 pointA = b2Mul(xfA, m_localPoint); + + b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]); + b2Vec2 pointB = b2Mul(xfB, localPointB); + + float32 s = b2Dot(pointB - pointA, normal); + if (s < 0.0f) + { + m_axis = -m_axis; + s = -s; + } + return s; + } + } + + float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const + { + b2Transform xfA, xfB; + m_sweepA.GetTransform(&xfA, t); + m_sweepB.GetTransform(&xfB, t); + + switch (m_type) + { + case e_points: + { + b2Vec2 axisA = b2MulT(xfA.R, m_axis); + b2Vec2 axisB = b2MulT(xfB.R, -m_axis); + + *indexA = m_proxyA->GetSupport(axisA); + *indexB = m_proxyB->GetSupport(axisB); + + b2Vec2 localPointA = m_proxyA->GetVertex(*indexA); + b2Vec2 localPointB = m_proxyB->GetVertex(*indexB); + + b2Vec2 pointA = b2Mul(xfA, localPointA); + b2Vec2 pointB = b2Mul(xfB, localPointB); + + float32 separation = b2Dot(pointB - pointA, m_axis); + return separation; + } + + case e_faceA: + { + b2Vec2 normal = b2Mul(xfA.R, m_axis); + b2Vec2 pointA = b2Mul(xfA, m_localPoint); + + b2Vec2 axisB = b2MulT(xfB.R, -normal); + + *indexA = -1; + *indexB = m_proxyB->GetSupport(axisB); + + b2Vec2 localPointB = m_proxyB->GetVertex(*indexB); + b2Vec2 pointB = b2Mul(xfB, localPointB); + + float32 separation = b2Dot(pointB - pointA, normal); + return separation; + } + + case e_faceB: + { + b2Vec2 normal = b2Mul(xfB.R, m_axis); + b2Vec2 pointB = b2Mul(xfB, m_localPoint); + + b2Vec2 axisA = b2MulT(xfA.R, -normal); + + *indexB = -1; + *indexA = m_proxyA->GetSupport(axisA); + + b2Vec2 localPointA = m_proxyA->GetVertex(*indexA); + b2Vec2 pointA = b2Mul(xfA, localPointA); + + float32 separation = b2Dot(pointA - pointB, normal); + return separation; + } + + default: + b2Assert(false); + *indexA = -1; + *indexB = -1; + return 0.0f; + } + } + + float32 Evaluate(int32 indexA, int32 indexB, float32 t) const + { + b2Transform xfA, xfB; + m_sweepA.GetTransform(&xfA, t); + m_sweepB.GetTransform(&xfB, t); + + switch (m_type) + { + case e_points: + { + b2Vec2 axisA = b2MulT(xfA.R, m_axis); + b2Vec2 axisB = b2MulT(xfB.R, -m_axis); + + b2Vec2 localPointA = m_proxyA->GetVertex(indexA); + b2Vec2 localPointB = m_proxyB->GetVertex(indexB); + + b2Vec2 pointA = b2Mul(xfA, localPointA); + b2Vec2 pointB = b2Mul(xfB, localPointB); + float32 separation = b2Dot(pointB - pointA, m_axis); + + return separation; + } + + case e_faceA: + { + b2Vec2 normal = b2Mul(xfA.R, m_axis); + b2Vec2 pointA = b2Mul(xfA, m_localPoint); + + b2Vec2 axisB = b2MulT(xfB.R, -normal); + + b2Vec2 localPointB = m_proxyB->GetVertex(indexB); + b2Vec2 pointB = b2Mul(xfB, localPointB); + + float32 separation = b2Dot(pointB - pointA, normal); + return separation; + } + + case e_faceB: + { + b2Vec2 normal = b2Mul(xfB.R, m_axis); + b2Vec2 pointB = b2Mul(xfB, m_localPoint); + + b2Vec2 axisA = b2MulT(xfA.R, -normal); + + b2Vec2 localPointA = m_proxyA->GetVertex(indexA); + b2Vec2 pointA = b2Mul(xfA, localPointA); + + float32 separation = b2Dot(pointA - pointB, normal); + return separation; + } + + default: + b2Assert(false); + return 0.0f; + } + } + + const b2DistanceProxy* m_proxyA; + const b2DistanceProxy* m_proxyB; + b2Sweep m_sweepA, m_sweepB; + Type m_type; + b2Vec2 m_localPoint; + b2Vec2 m_axis; +}; + +// CCD via the local separating axis method. This seeks progression +// by computing the largest time at which separation is maintained. +void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input) +{ + ++b2_toiCalls; + + output->state = b2TOIOutput::e_unknown; + output->t = input->tMax; + + const b2DistanceProxy* proxyA = &input->proxyA; + const b2DistanceProxy* proxyB = &input->proxyB; + + b2Sweep sweepA = input->sweepA; + b2Sweep sweepB = input->sweepB; + + // Large rotations can make the root finder fail, so we normalize the + // sweep angles. + sweepA.Normalize(); + sweepB.Normalize(); + + float32 tMax = input->tMax; + + float32 totalRadius = proxyA->m_radius + proxyB->m_radius; + float32 target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop); + float32 tolerance = 0.25f * b2_linearSlop; + b2Assert(target > tolerance); + + float32 t1 = 0.0f; + const int32 k_maxIterations = 20; // TODO_ERIN b2Settings + int32 iter = 0; + + // Prepare input for distance query. + b2SimplexCache cache; + cache.count = 0; + b2DistanceInput distanceInput; + distanceInput.proxyA = input->proxyA; + distanceInput.proxyB = input->proxyB; + distanceInput.useRadii = false; + + // The outer loop progressively attempts to compute new separating axes. + // This loop terminates when an axis is repeated (no progress is made). + for(;;) + { + b2Transform xfA, xfB; + sweepA.GetTransform(&xfA, t1); + sweepB.GetTransform(&xfB, t1); + + // Get the distance between shapes. We can also use the results + // to get a separating axis. + distanceInput.transformA = xfA; + distanceInput.transformB = xfB; + b2DistanceOutput distanceOutput; + b2Distance(&distanceOutput, &cache, &distanceInput); + + // If the shapes are overlapped, we give up on continuous collision. + if (distanceOutput.distance <= 0.0f) + { + // Failure! + output->state = b2TOIOutput::e_overlapped; + output->t = 0.0f; + break; + } + + if (distanceOutput.distance < target + tolerance) + { + // Victory! + output->state = b2TOIOutput::e_touching; + output->t = t1; + break; + } + + // Initialize the separating axis. + b2SeparationFunction fcn; + fcn.Initialize(&cache, proxyA, sweepA, proxyB, sweepB); +#if 0 + // Dump the curve seen by the root finder + { + const int32 N = 100; + float32 dx = 1.0f / N; + float32 xs[N+1]; + float32 fs[N+1]; + + float32 x = 0.0f; + + for (int32 i = 0; i <= N; ++i) + { + sweepA.GetTransform(&xfA, x); + sweepB.GetTransform(&xfB, x); + float32 f = fcn.Evaluate(xfA, xfB) - target; + + printf("%g %g\n", x, f); + + xs[i] = x; + fs[i] = f; + + x += dx; + } + } +#endif + + // Compute the TOI on the separating axis. We do this by successively + // resolving the deepest point. This loop is bounded by the number of vertices. + bool done = false; + float32 t2 = tMax; + int32 pushBackIter = 0; + for (;;) + { + // Find the deepest point at t2. Store the witness point indices. + int32 indexA, indexB; + float32 s2 = fcn.FindMinSeparation(&indexA, &indexB, t2); + + // Is the final configuration separated? + if (s2 > target + tolerance) + { + // Victory! + output->state = b2TOIOutput::e_separated; + output->t = tMax; + done = true; + break; + } + + // Has the separation reached tolerance? + if (s2 > target - tolerance) + { + // Advance the sweeps + t1 = t2; + break; + } + + // Compute the initial separation of the witness points. + float32 s1 = fcn.Evaluate(indexA, indexB, t1); + + // Check for initial overlap. This might happen if the root finder + // runs out of iterations. + if (s1 < target - tolerance) + { + output->state = b2TOIOutput::e_failed; + output->t = t1; + done = true; + break; + } + + // Check for touching + if (s1 <= target + tolerance) + { + // Victory! t1 should hold the TOI (could be 0.0). + output->state = b2TOIOutput::e_touching; + output->t = t1; + done = true; + break; + } + + // Compute 1D root of: f(x) - target = 0 + int32 rootIterCount = 0; + float32 a1 = t1, a2 = t2; + for (;;) + { + // Use a mix of the secant rule and bisection. + float32 t; + if (rootIterCount & 1) + { + // Secant rule to improve convergence. + t = a1 + (target - s1) * (a2 - a1) / (s2 - s1); + } + else + { + // Bisection to guarantee progress. + t = 0.5f * (a1 + a2); + } + + float32 s = fcn.Evaluate(indexA, indexB, t); + + if (b2Abs(s - target) < tolerance) + { + // t2 holds a tentative value for t1 + t2 = t; + break; + } + + // Ensure we continue to bracket the root. + if (s > target) + { + a1 = t; + s1 = s; + } + else + { + a2 = t; + s2 = s; + } + + ++rootIterCount; + ++b2_toiRootIters; + + if (rootIterCount == 50) + { + break; + } + } + + b2_toiMaxRootIters = b2Max(b2_toiMaxRootIters, rootIterCount); + + ++pushBackIter; + + if (pushBackIter == b2_maxPolygonVertices) + { + break; + } + } + + ++iter; + ++b2_toiIters; + + if (done) + { + break; + } + + if (iter == k_maxIterations) + { + // Root finder got stuck. Semi-victory. + output->state = b2TOIOutput::e_failed; + output->t = t1; + break; + } + } + + b2_toiMaxIters = b2Max(b2_toiMaxIters, iter); +} diff --git a/AndEngine/jni/Box2D/Collision/b2TimeOfImpact.h b/AndEngine/jni/Box2D/Collision/b2TimeOfImpact.h new file mode 100644 index 0000000..475fa13 --- /dev/null +++ b/AndEngine/jni/Box2D/Collision/b2TimeOfImpact.h @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_TIME_OF_IMPACT_H +#define B2_TIME_OF_IMPACT_H + +#include "Box2D/Common/b2Math.h" +#include "Box2D/Collision/b2Distance.h" +#include + +/// Input parameters for b2TimeOfImpact +struct b2TOIInput +{ + b2DistanceProxy proxyA; + b2DistanceProxy proxyB; + b2Sweep sweepA; + b2Sweep sweepB; + float32 tMax; // defines sweep interval [0, tMax] +}; + +// Output parameters for b2TimeOfImpact. +struct b2TOIOutput +{ + enum State + { + e_unknown, + e_failed, + e_overlapped, + e_touching, + e_separated + }; + + State state; + float32 t; +}; + +/// Compute the upper bound on time before two shapes penetrate. Time is represented as +/// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate, +/// non-tunneling collision. If you change the time interval, you should call this function +/// again. +/// Note: use b2Distance to compute the contact point and normal at the time of impact. +void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input); + +#endif diff --git a/AndEngine/jni/Box2D/Common/b2BlockAllocator.cpp b/AndEngine/jni/Box2D/Common/b2BlockAllocator.cpp new file mode 100644 index 0000000..6acad2a --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2BlockAllocator.cpp @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Common/b2BlockAllocator.h" +#include +#include +#include +#include + +int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = +{ + 16, // 0 + 32, // 1 + 64, // 2 + 96, // 3 + 128, // 4 + 160, // 5 + 192, // 6 + 224, // 7 + 256, // 8 + 320, // 9 + 384, // 10 + 448, // 11 + 512, // 12 + 640, // 13 +}; +uint8 b2BlockAllocator::s_blockSizeLookup[b2_maxBlockSize + 1]; +bool b2BlockAllocator::s_blockSizeLookupInitialized; + +struct b2Chunk +{ + int32 blockSize; + b2Block* blocks; +}; + +struct b2Block +{ + b2Block* next; +}; + +b2BlockAllocator::b2BlockAllocator() +{ + b2Assert(b2_blockSizes < UCHAR_MAX); + + m_chunkSpace = b2_chunkArrayIncrement; + m_chunkCount = 0; + m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk)); + + memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk)); + memset(m_freeLists, 0, sizeof(m_freeLists)); + + if (s_blockSizeLookupInitialized == false) + { + int32 j = 0; + for (int32 i = 1; i <= b2_maxBlockSize; ++i) + { + b2Assert(j < b2_blockSizes); + if (i <= s_blockSizes[j]) + { + s_blockSizeLookup[i] = (uint8)j; + } + else + { + ++j; + s_blockSizeLookup[i] = (uint8)j; + } + } + + s_blockSizeLookupInitialized = true; + } +} + +b2BlockAllocator::~b2BlockAllocator() +{ + for (int32 i = 0; i < m_chunkCount; ++i) + { + b2Free(m_chunks[i].blocks); + } + + b2Free(m_chunks); +} + +void* b2BlockAllocator::Allocate(int32 size) +{ + if (size == 0) + return NULL; + + b2Assert(0 < size && size <= b2_maxBlockSize); + + int32 index = s_blockSizeLookup[size]; + b2Assert(0 <= index && index < b2_blockSizes); + + if (m_freeLists[index]) + { + b2Block* block = m_freeLists[index]; + m_freeLists[index] = block->next; + return block; + } + else + { + if (m_chunkCount == m_chunkSpace) + { + b2Chunk* oldChunks = m_chunks; + m_chunkSpace += b2_chunkArrayIncrement; + m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk)); + memcpy(m_chunks, oldChunks, m_chunkCount * sizeof(b2Chunk)); + memset(m_chunks + m_chunkCount, 0, b2_chunkArrayIncrement * sizeof(b2Chunk)); + b2Free(oldChunks); + } + + b2Chunk* chunk = m_chunks + m_chunkCount; + chunk->blocks = (b2Block*)b2Alloc(b2_chunkSize); +#if defined(_DEBUG) + memset(chunk->blocks, 0xcd, b2_chunkSize); +#endif + int32 blockSize = s_blockSizes[index]; + chunk->blockSize = blockSize; + int32 blockCount = b2_chunkSize / blockSize; + b2Assert(blockCount * blockSize <= b2_chunkSize); + for (int32 i = 0; i < blockCount - 1; ++i) + { + b2Block* block = (b2Block*)((int8*)chunk->blocks + blockSize * i); + b2Block* next = (b2Block*)((int8*)chunk->blocks + blockSize * (i + 1)); + block->next = next; + } + b2Block* last = (b2Block*)((int8*)chunk->blocks + blockSize * (blockCount - 1)); + last->next = NULL; + + m_freeLists[index] = chunk->blocks->next; + ++m_chunkCount; + + return chunk->blocks; + } +} + +void b2BlockAllocator::Free(void* p, int32 size) +{ + if (size == 0) + { + return; + } + + b2Assert(0 < size && size <= b2_maxBlockSize); + + int32 index = s_blockSizeLookup[size]; + b2Assert(0 <= index && index < b2_blockSizes); + +#ifdef _DEBUG + // Verify the memory address and size is valid. + int32 blockSize = s_blockSizes[index]; + bool found = false; + for (int32 i = 0; i < m_chunkCount; ++i) + { + b2Chunk* chunk = m_chunks + i; + if (chunk->blockSize != blockSize) + { + b2Assert( (int8*)p + blockSize <= (int8*)chunk->blocks || + (int8*)chunk->blocks + b2_chunkSize <= (int8*)p); + } + else + { + if ((int8*)chunk->blocks <= (int8*)p && (int8*)p + blockSize <= (int8*)chunk->blocks + b2_chunkSize) + { + found = true; + } + } + } + + b2Assert(found); + + memset(p, 0xfd, blockSize); +#endif + + b2Block* block = (b2Block*)p; + block->next = m_freeLists[index]; + m_freeLists[index] = block; +} + +void b2BlockAllocator::Clear() +{ + for (int32 i = 0; i < m_chunkCount; ++i) + { + b2Free(m_chunks[i].blocks); + } + + m_chunkCount = 0; + memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk)); + + memset(m_freeLists, 0, sizeof(m_freeLists)); +} diff --git a/AndEngine/jni/Box2D/Common/b2BlockAllocator.h b/AndEngine/jni/Box2D/Common/b2BlockAllocator.h new file mode 100644 index 0000000..2c3c5dc --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2BlockAllocator.h @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_BLOCK_ALLOCATOR_H +#define B2_BLOCK_ALLOCATOR_H + +#include "Box2D/Common/b2Settings.h" + +const int32 b2_chunkSize = 4096; +const int32 b2_maxBlockSize = 640; +const int32 b2_blockSizes = 14; +const int32 b2_chunkArrayIncrement = 128; + +struct b2Block; +struct b2Chunk; + +// This is a small object allocator used for allocating small +// objects that persist for more than one time step. +// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp +class b2BlockAllocator +{ +public: + b2BlockAllocator(); + ~b2BlockAllocator(); + + void* Allocate(int32 size); + void Free(void* p, int32 size); + + void Clear(); + +private: + + b2Chunk* m_chunks; + int32 m_chunkCount; + int32 m_chunkSpace; + + b2Block* m_freeLists[b2_blockSizes]; + + static int32 s_blockSizes[b2_blockSizes]; + static uint8 s_blockSizeLookup[b2_maxBlockSize + 1]; + static bool s_blockSizeLookupInitialized; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Common/b2Math.cpp b/AndEngine/jni/Box2D/Common/b2Math.cpp new file mode 100644 index 0000000..b1e5ec3 --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2Math.cpp @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Common/b2Math.h" + +const b2Vec2 b2Vec2_zero(0.0f, 0.0f); +const b2Mat22 b2Mat22_identity(1.0f, 0.0f, 0.0f, 1.0f); +const b2Transform b2Transform_identity(b2Vec2_zero, b2Mat22_identity); + +/// Solve A * x = b, where b is a column vector. This is more efficient +/// than computing the inverse in one-shot cases. +b2Vec3 b2Mat33::Solve33(const b2Vec3& b) const +{ + float32 det = b2Dot(col1, b2Cross(col2, col3)); + if (det != 0.0f) + { + det = 1.0f / det; + } + b2Vec3 x; + x.x = det * b2Dot(b, b2Cross(col2, col3)); + x.y = det * b2Dot(col1, b2Cross(b, col3)); + x.z = det * b2Dot(col1, b2Cross(col2, b)); + return x; +} + +/// Solve A * x = b, where b is a column vector. This is more efficient +/// than computing the inverse in one-shot cases. +b2Vec2 b2Mat33::Solve22(const b2Vec2& b) const +{ + float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y; + float32 det = a11 * a22 - a12 * a21; + if (det != 0.0f) + { + det = 1.0f / det; + } + b2Vec2 x; + x.x = det * (a22 * b.x - a12 * b.y); + x.y = det * (a11 * b.y - a21 * b.x); + return x; +} diff --git a/AndEngine/jni/Box2D/Common/b2Math.h b/AndEngine/jni/Box2D/Common/b2Math.h new file mode 100644 index 0000000..7983337 --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2Math.h @@ -0,0 +1,623 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_MATH_H +#define B2_MATH_H + +#include "Box2D/Common/b2Settings.h" + +#include +#include +#include +#include + +/// This function is used to ensure that a floating point number is +/// not a NaN or infinity. +inline bool b2IsValid(float32 x) +{ + if (x != x) + { + // NaN. + return false; + } + + return true; +} + +/// This is a approximate yet fast inverse square-root. +inline float32 b2InvSqrt(float32 x) +{ + union + { + float32 x; + int32 i; + } convert; + + convert.x = x; + float32 xhalf = 0.5f * x; + convert.i = 0x5f3759df - (convert.i >> 1); + x = convert.x; + x = x * (1.5f - xhalf * x * x); + return x; +} + +#define b2Sqrt(x) sqrtf(x) +#define b2Atan2(y, x) atan2f(y, x) + +inline float32 b2Abs(float32 a) +{ + return a > 0.0f ? a : -a; +} + +/// A 2D column vector. +struct b2Vec2 +{ + /// Default constructor does nothing (for performance). + b2Vec2() {} + + /// Construct using coordinates. + b2Vec2(float32 x, float32 y) : x(x), y(y) {} + + /// Set this vector to all zeros. + void SetZero() { x = 0.0f; y = 0.0f; } + + /// Set this vector to some specified coordinates. + void Set(float32 x_, float32 y_) { x = x_; y = y_; } + + /// Negate this vector. + b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; } + + /// Read from and indexed element. + float32 operator () (int32 i) const + { + return (&x)[i]; + } + + /// Write to an indexed element. + float32& operator () (int32 i) + { + return (&x)[i]; + } + + /// Add a vector to this vector. + void operator += (const b2Vec2& v) + { + x += v.x; y += v.y; + } + + /// Subtract a vector from this vector. + void operator -= (const b2Vec2& v) + { + x -= v.x; y -= v.y; + } + + /// Multiply this vector by a scalar. + void operator *= (float32 a) + { + x *= a; y *= a; + } + + /// Get the length of this vector (the norm). + float32 Length() const + { + return b2Sqrt(x * x + y * y); + } + + /// Get the length squared. For performance, use this instead of + /// b2Vec2::Length (if possible). + float32 LengthSquared() const + { + return x * x + y * y; + } + + /// Convert this vector into a unit vector. Returns the length. + float32 Normalize() + { + float32 length = Length(); + if (length < b2_epsilon) + { + return 0.0f; + } + float32 invLength = 1.0f / length; + x *= invLength; + y *= invLength; + + return length; + } + + /// Does this vector contain finite coordinates? + bool IsValid() const + { + return b2IsValid(x) && b2IsValid(y); + } + + float32 x, y; +}; + +/// A 2D column vector with 3 elements. +struct b2Vec3 +{ + /// Default constructor does nothing (for performance). + b2Vec3() {} + + /// Construct using coordinates. + b2Vec3(float32 x, float32 y, float32 z) : x(x), y(y), z(z) {} + + /// Set this vector to all zeros. + void SetZero() { x = 0.0f; y = 0.0f; z = 0.0f; } + + /// Set this vector to some specified coordinates. + void Set(float32 x_, float32 y_, float32 z_) { x = x_; y = y_; z = z_; } + + /// Negate this vector. + b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; } + + /// Add a vector to this vector. + void operator += (const b2Vec3& v) + { + x += v.x; y += v.y; z += v.z; + } + + /// Subtract a vector from this vector. + void operator -= (const b2Vec3& v) + { + x -= v.x; y -= v.y; z -= v.z; + } + + /// Multiply this vector by a scalar. + void operator *= (float32 s) + { + x *= s; y *= s; z *= s; + } + + float32 x, y, z; +}; + +/// A 2-by-2 matrix. Stored in column-major order. +struct b2Mat22 +{ + /// The default constructor does nothing (for performance). + b2Mat22() {} + + /// Construct this matrix using columns. + b2Mat22(const b2Vec2& c1, const b2Vec2& c2) + { + col1 = c1; + col2 = c2; + } + + /// Construct this matrix using scalars. + b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22) + { + col1.x = a11; col1.y = a21; + col2.x = a12; col2.y = a22; + } + + /// Construct this matrix using an angle. This matrix becomes + /// an orthonormal rotation matrix. + explicit b2Mat22(float32 angle) + { + // TODO_ERIN compute sin+cos together. + float32 c = cosf(angle), s = sinf(angle); + col1.x = c; col2.x = -s; + col1.y = s; col2.y = c; + } + + /// Initialize this matrix using columns. + void Set(const b2Vec2& c1, const b2Vec2& c2) + { + col1 = c1; + col2 = c2; + } + + /// Initialize this matrix using an angle. This matrix becomes + /// an orthonormal rotation matrix. + void Set(float32 angle) + { + float32 c = cosf(angle), s = sinf(angle); + col1.x = c; col2.x = -s; + col1.y = s; col2.y = c; + } + + /// Set this to the identity matrix. + void SetIdentity() + { + col1.x = 1.0f; col2.x = 0.0f; + col1.y = 0.0f; col2.y = 1.0f; + } + + /// Set this matrix to all zeros. + void SetZero() + { + col1.x = 0.0f; col2.x = 0.0f; + col1.y = 0.0f; col2.y = 0.0f; + } + + /// Extract the angle from this matrix (assumed to be + /// a rotation matrix). + float32 GetAngle() const + { + return b2Atan2(col1.y, col1.x); + } + + b2Mat22 GetInverse() const + { + float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y; + b2Mat22 B; + float32 det = a * d - b * c; + if (det != 0.0f) + { + det = 1.0f / det; + } + B.col1.x = det * d; B.col2.x = -det * b; + B.col1.y = -det * c; B.col2.y = det * a; + return B; + } + + /// Solve A * x = b, where b is a column vector. This is more efficient + /// than computing the inverse in one-shot cases. + b2Vec2 Solve(const b2Vec2& b) const + { + float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y; + float32 det = a11 * a22 - a12 * a21; + if (det != 0.0f) + { + det = 1.0f / det; + } + b2Vec2 x; + x.x = det * (a22 * b.x - a12 * b.y); + x.y = det * (a11 * b.y - a21 * b.x); + return x; + } + + b2Vec2 col1, col2; +}; + +/// A 3-by-3 matrix. Stored in column-major order. +struct b2Mat33 +{ + /// The default constructor does nothing (for performance). + b2Mat33() {} + + /// Construct this matrix using columns. + b2Mat33(const b2Vec3& c1, const b2Vec3& c2, const b2Vec3& c3) + { + col1 = c1; + col2 = c2; + col3 = c3; + } + + /// Set this matrix to all zeros. + void SetZero() + { + col1.SetZero(); + col2.SetZero(); + col3.SetZero(); + } + + /// Solve A * x = b, where b is a column vector. This is more efficient + /// than computing the inverse in one-shot cases. + b2Vec3 Solve33(const b2Vec3& b) const; + + /// Solve A * x = b, where b is a column vector. This is more efficient + /// than computing the inverse in one-shot cases. Solve only the upper + /// 2-by-2 matrix equation. + b2Vec2 Solve22(const b2Vec2& b) const; + + b2Vec3 col1, col2, col3; +}; + +/// A transform contains translation and rotation. It is used to represent +/// the position and orientation of rigid frames. +struct b2Transform +{ + /// The default constructor does nothing (for performance). + b2Transform() {} + + /// Initialize using a position vector and a rotation matrix. + b2Transform(const b2Vec2& position, const b2Mat22& R) : position(position), R(R) {} + + /// Set this to the identity transform. + void SetIdentity() + { + position.SetZero(); + R.SetIdentity(); + } + + /// Set this based on the position and angle. + void Set(const b2Vec2& p, float32 angle) + { + position = p; + R.Set(angle); + } + + /// Calculate the angle that the rotation matrix represents. + float32 GetAngle() const + { + return b2Atan2(R.col1.y, R.col1.x); + } + + b2Vec2 position; + b2Mat22 R; +}; + +/// This describes the motion of a body/shape for TOI computation. +/// Shapes are defined with respect to the body origin, which may +/// no coincide with the center of mass. However, to support dynamics +/// we must interpolate the center of mass position. +struct b2Sweep +{ + /// Get the interpolated transform at a specific time. + /// @param alpha is a factor in [0,1], where 0 indicates t0. + void GetTransform(b2Transform* xf, float32 alpha) const; + + /// Advance the sweep forward, yielding a new initial state. + /// @param t the new initial time. + void Advance(float32 t); + + /// Normalize the angles. + void Normalize(); + + b2Vec2 localCenter; ///< local center of mass position + b2Vec2 c0, c; ///< center world positions + float32 a0, a; ///< world angles +}; + + +extern const b2Vec2 b2Vec2_zero; +extern const b2Mat22 b2Mat22_identity; +extern const b2Transform b2Transform_identity; + +/// Perform the dot product on two vectors. +inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b) +{ + return a.x * b.x + a.y * b.y; +} + +/// Perform the cross product on two vectors. In 2D this produces a scalar. +inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b) +{ + return a.x * b.y - a.y * b.x; +} + +/// Perform the cross product on a vector and a scalar. In 2D this produces +/// a vector. +inline b2Vec2 b2Cross(const b2Vec2& a, float32 s) +{ + return b2Vec2(s * a.y, -s * a.x); +} + +/// Perform the cross product on a scalar and a vector. In 2D this produces +/// a vector. +inline b2Vec2 b2Cross(float32 s, const b2Vec2& a) +{ + return b2Vec2(-s * a.y, s * a.x); +} + +/// Multiply a matrix times a vector. If a rotation matrix is provided, +/// then this transforms the vector from one frame to another. +inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v) +{ + return b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); +} + +/// Multiply a matrix transpose times a vector. If a rotation matrix is provided, +/// then this transforms the vector from one frame to another (inverse transform). +inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v) +{ + return b2Vec2(b2Dot(v, A.col1), b2Dot(v, A.col2)); +} + +/// Add two vectors component-wise. +inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b) +{ + return b2Vec2(a.x + b.x, a.y + b.y); +} + +/// Subtract two vectors component-wise. +inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b) +{ + return b2Vec2(a.x - b.x, a.y - b.y); +} + +inline b2Vec2 operator * (float32 s, const b2Vec2& a) +{ + return b2Vec2(s * a.x, s * a.y); +} + +inline bool operator == (const b2Vec2& a, const b2Vec2& b) +{ + return a.x == b.x && a.y == b.y; +} + +inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b) +{ + b2Vec2 c = a - b; + return c.Length(); +} + +inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b) +{ + b2Vec2 c = a - b; + return b2Dot(c, c); +} + +inline b2Vec3 operator * (float32 s, const b2Vec3& a) +{ + return b2Vec3(s * a.x, s * a.y, s * a.z); +} + +/// Add two vectors component-wise. +inline b2Vec3 operator + (const b2Vec3& a, const b2Vec3& b) +{ + return b2Vec3(a.x + b.x, a.y + b.y, a.z + b.z); +} + +/// Subtract two vectors component-wise. +inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b) +{ + return b2Vec3(a.x - b.x, a.y - b.y, a.z - b.z); +} + +/// Perform the dot product on two vectors. +inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +/// Perform the cross product on two vectors. +inline b2Vec3 b2Cross(const b2Vec3& a, const b2Vec3& b) +{ + return b2Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} + +inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B) +{ + return b2Mat22(A.col1 + B.col1, A.col2 + B.col2); +} + +// A * B +inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B) +{ + return b2Mat22(b2Mul(A, B.col1), b2Mul(A, B.col2)); +} + +// A^T * B +inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B) +{ + b2Vec2 c1(b2Dot(A.col1, B.col1), b2Dot(A.col2, B.col1)); + b2Vec2 c2(b2Dot(A.col1, B.col2), b2Dot(A.col2, B.col2)); + return b2Mat22(c1, c2); +} + +/// Multiply a matrix times a vector. +inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v) +{ + return v.x * A.col1 + v.y * A.col2 + v.z * A.col3; +} + +inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v) +{ + float32 x = T.position.x + T.R.col1.x * v.x + T.R.col2.x * v.y; + float32 y = T.position.y + T.R.col1.y * v.x + T.R.col2.y * v.y; + + return b2Vec2(x, y); +} + +inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v) +{ + return b2MulT(T.R, v - T.position); +} + +inline b2Vec2 b2Abs(const b2Vec2& a) +{ + return b2Vec2(b2Abs(a.x), b2Abs(a.y)); +} + +inline b2Mat22 b2Abs(const b2Mat22& A) +{ + return b2Mat22(b2Abs(A.col1), b2Abs(A.col2)); +} + +template +inline T b2Min(T a, T b) +{ + return a < b ? a : b; +} + +inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b) +{ + return b2Vec2(b2Min(a.x, b.x), b2Min(a.y, b.y)); +} + +template +inline T b2Max(T a, T b) +{ + return a > b ? a : b; +} + +inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b) +{ + return b2Vec2(b2Max(a.x, b.x), b2Max(a.y, b.y)); +} + +template +inline T b2Clamp(T a, T low, T high) +{ + return b2Max(low, b2Min(a, high)); +} + +inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high) +{ + return b2Max(low, b2Min(a, high)); +} + +template inline void b2Swap(T& a, T& b) +{ + T tmp = a; + a = b; + b = tmp; +} + +/// "Next Largest Power of 2 +/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm +/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with +/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next +/// largest power of 2. For a 32-bit value:" +inline uint32 b2NextPowerOfTwo(uint32 x) +{ + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x + 1; +} + +inline bool b2IsPowerOfTwo(uint32 x) +{ + bool result = x > 0 && (x & (x - 1)) == 0; + return result; +} + +inline void b2Sweep::GetTransform(b2Transform* xf, float32 alpha) const +{ + xf->position = (1.0f - alpha) * c0 + alpha * c; + float32 angle = (1.0f - alpha) * a0 + alpha * a; + xf->R.Set(angle); + + // Shift to origin + xf->position -= b2Mul(xf->R, localCenter); +} + +inline void b2Sweep::Advance(float32 t) +{ + c0 = (1.0f - t) * c0 + t * c; + a0 = (1.0f - t) * a0 + t * a; +} + +/// Normalize an angle in radians to be between -pi and pi +inline void b2Sweep::Normalize() +{ + float32 twoPi = 2.0f * b2_pi; + float32 d = twoPi * floorf(a0 / twoPi); + a0 -= d; + a -= d; +} + +#endif diff --git a/AndEngine/jni/Box2D/Common/b2Settings.cpp b/AndEngine/jni/Box2D/Common/b2Settings.cpp new file mode 100644 index 0000000..b6ba2b8 --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2Settings.cpp @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Common/b2Settings.h" +#include + +b2Version b2_version = {2, 1, 2}; + +// Memory allocators. Modify these to use your own allocator. +void* b2Alloc(int32 size) +{ + return malloc(size); +} + +void b2Free(void* mem) +{ + free(mem); +} diff --git a/AndEngine/jni/Box2D/Common/b2Settings.h b/AndEngine/jni/Box2D/Common/b2Settings.h new file mode 100644 index 0000000..741b58f --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2Settings.h @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_SETTINGS_H +#define B2_SETTINGS_H + +#include +#include + +#define B2_NOT_USED(x) ((void)(x)) +#define b2Assert(A) assert(A) + +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef float float32; + +#define b2_maxFloat FLT_MAX +#define b2_epsilon FLT_EPSILON +#define b2_pi 3.14159265359f + +/// @file +/// Global tuning constants based on meters-kilograms-seconds (MKS) units. +/// + +// Collision + +/// The maximum number of contact points between two convex shapes. +#define b2_maxManifoldPoints 2 + +/// The maximum number of vertices on a convex polygon. +#define b2_maxPolygonVertices 8 + +/// This is used to fatten AABBs in the dynamic tree. This allows proxies +/// to move by a small amount without triggering a tree adjustment. +/// This is in meters. +#define b2_aabbExtension 0.1f + +/// This is used to fatten AABBs in the dynamic tree. This is used to predict +/// the future position based on the current displacement. +/// This is a dimensionless multiplier. +#define b2_aabbMultiplier 2.0f + +/// A small length used as a collision and constraint tolerance. Usually it is +/// chosen to be numerically significant, but visually insignificant. +#define b2_linearSlop 0.005f + +/// A small angle used as a collision and constraint tolerance. Usually it is +/// chosen to be numerically significant, but visually insignificant. +#define b2_angularSlop (2.0f / 180.0f * b2_pi) + +/// The radius of the polygon/edge shape skin. This should not be modified. Making +/// this smaller means polygons will have an insufficient buffer for continuous collision. +/// Making it larger may create artifacts for vertex collision. +#define b2_polygonRadius (2.0f * b2_linearSlop) + + +// Dynamics + +/// Maximum number of contacts to be handled to solve a TOI impact. +#define b2_maxTOIContacts 32 + +/// A velocity threshold for elastic collisions. Any collision with a relative linear +/// velocity below this threshold will be treated as inelastic. +#define b2_velocityThreshold 1.0f + +/// The maximum linear position correction used when solving constraints. This helps to +/// prevent overshoot. +#define b2_maxLinearCorrection 0.2f + +/// The maximum angular position correction used when solving constraints. This helps to +/// prevent overshoot. +#define b2_maxAngularCorrection (8.0f / 180.0f * b2_pi) + +/// The maximum linear velocity of a body. This limit is very large and is used +/// to prevent numerical problems. You shouldn't need to adjust this. +#define b2_maxTranslation 2.0f +#define b2_maxTranslationSquared (b2_maxTranslation * b2_maxTranslation) + +/// The maximum angular velocity of a body. This limit is very large and is used +/// to prevent numerical problems. You shouldn't need to adjust this. +#define b2_maxRotation (0.5f * b2_pi) +#define b2_maxRotationSquared (b2_maxRotation * b2_maxRotation) + +/// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so +/// that overlap is removed in one time step. However using values close to 1 often lead +/// to overshoot. +#define b2_contactBaumgarte 0.2f + +// Sleep + +/// The time that a body must be still before it will go to sleep. +#define b2_timeToSleep 0.5f + +/// A body cannot sleep if its linear velocity is above this tolerance. +#define b2_linearSleepTolerance 0.01f + +/// A body cannot sleep if its angular velocity is above this tolerance. +#define b2_angularSleepTolerance (2.0f / 180.0f * b2_pi) + +// Memory Allocation + +/// Implement this function to use your own memory allocator. +void* b2Alloc(int32 size); + +/// If you implement b2Alloc, you should also implement this function. +void b2Free(void* mem); + +/// Version numbering scheme. +/// See http://en.wikipedia.org/wiki/Software_versioning +struct b2Version +{ + int32 major; ///< significant changes + int32 minor; ///< incremental changes + int32 revision; ///< bug fixes +}; + +/// Current version. +extern b2Version b2_version; + +/// Friction mixing law. Feel free to customize this. +inline float32 b2MixFriction(float32 friction1, float32 friction2) +{ + return sqrtf(friction1 * friction2); +} + +/// Restitution mixing law. Feel free to customize this. +inline float32 b2MixRestitution(float32 restitution1, float32 restitution2) +{ + return restitution1 > restitution2 ? restitution1 : restitution2; +} + +#endif diff --git a/AndEngine/jni/Box2D/Common/b2StackAllocator.cpp b/AndEngine/jni/Box2D/Common/b2StackAllocator.cpp new file mode 100644 index 0000000..af207df --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2StackAllocator.cpp @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Common/b2StackAllocator.h" +#include "Box2D/Common/b2Math.h" + +b2StackAllocator::b2StackAllocator() +{ + m_index = 0; + m_allocation = 0; + m_maxAllocation = 0; + m_entryCount = 0; +} + +b2StackAllocator::~b2StackAllocator() +{ + b2Assert(m_index == 0); + b2Assert(m_entryCount == 0); +} + +void* b2StackAllocator::Allocate(int32 size) +{ + b2Assert(m_entryCount < b2_maxStackEntries); + + b2StackEntry* entry = m_entries + m_entryCount; + entry->size = size; + if (m_index + size > b2_stackSize) + { + entry->data = (char*)b2Alloc(size); + entry->usedMalloc = true; + } + else + { + entry->data = m_data + m_index; + entry->usedMalloc = false; + m_index += size; + } + + m_allocation += size; + m_maxAllocation = b2Max(m_maxAllocation, m_allocation); + ++m_entryCount; + + return entry->data; +} + +void b2StackAllocator::Free(void* p) +{ + b2Assert(m_entryCount > 0); + b2StackEntry* entry = m_entries + m_entryCount - 1; + b2Assert(p == entry->data); + if (entry->usedMalloc) + { + b2Free(p); + } + else + { + m_index -= entry->size; + } + m_allocation -= entry->size; + --m_entryCount; + + p = NULL; +} + +int32 b2StackAllocator::GetMaxAllocation() const +{ + return m_maxAllocation; +} diff --git a/AndEngine/jni/Box2D/Common/b2StackAllocator.h b/AndEngine/jni/Box2D/Common/b2StackAllocator.h new file mode 100644 index 0000000..a1a66fb --- /dev/null +++ b/AndEngine/jni/Box2D/Common/b2StackAllocator.h @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_STACK_ALLOCATOR_H +#define B2_STACK_ALLOCATOR_H + +#include "Box2D/Common/b2Settings.h" + +const int32 b2_stackSize = 100 * 1024; // 100k +const int32 b2_maxStackEntries = 32; + +struct b2StackEntry +{ + char* data; + int32 size; + bool usedMalloc; +}; + +// This is a stack allocator used for fast per step allocations. +// You must nest allocate/free pairs. The code will assert +// if you try to interleave multiple allocate/free pairs. +class b2StackAllocator +{ +public: + b2StackAllocator(); + ~b2StackAllocator(); + + void* Allocate(int32 size); + void Free(void* p); + + int32 GetMaxAllocation() const; + +private: + + char m_data[b2_stackSize]; + int32 m_index; + + int32 m_allocation; + int32 m_maxAllocation; + + b2StackEntry m_entries[b2_maxStackEntries]; + int32 m_entryCount; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Contact.cpp b/AndEngine/jni/Box2D/Contact.cpp new file mode 100644 index 0000000..1db0c98 --- /dev/null +++ b/AndEngine/jni/Box2D/Contact.cpp @@ -0,0 +1,105 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "Contact.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniGetWorldManifold + * Signature: (J)J + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniGetWorldManifold + (JNIEnv *env, jobject, jlong addr, jfloatArray mani) +{ + b2Contact* contact = (b2Contact*)addr; + b2WorldManifold manifold; + contact->GetWorldManifold(&manifold); + int numPoints = contact->GetManifold()->pointCount; + + float* tmp = (float*)env->GetPrimitiveArrayCritical( mani, 0 ); + tmp[0] = manifold.normal.x; + tmp[1] = manifold.normal.y; + + for( int i = 0; i < numPoints; i++ ) + { + tmp[2 + i*2] = manifold.points[i].x; + tmp[2 + i*2+1] = manifold.points[i].y; + } + + env->ReleasePrimitiveArrayCritical( mani, tmp, 0 ); + + return numPoints; +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniIsTouching + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniIsTouching + (JNIEnv *, jobject, jlong addr) +{ + b2Contact* contact = (b2Contact*)addr; + return contact->IsTouching(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniSetEnabled + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniSetEnabled + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2Contact* contact = (b2Contact*)addr; + contact->SetEnabled(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniIsEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniIsEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2Contact* contact = (b2Contact*)addr; + return contact->IsEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniGetFixtureA + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniGetFixtureA + (JNIEnv *, jobject, jlong addr) +{ + b2Contact* contact = (b2Contact*)addr; + return (jlong)contact->GetFixtureA(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniGetFixtureB + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniGetFixtureB + (JNIEnv *, jobject, jlong addr) +{ + b2Contact* contact = (b2Contact*)addr; + return (jlong)contact->GetFixtureB(); +} diff --git a/AndEngine/jni/Box2D/Contact.h b/AndEngine/jni/Box2D/Contact.h new file mode 100644 index 0000000..5017c93 --- /dev/null +++ b/AndEngine/jni/Box2D/Contact.h @@ -0,0 +1,76 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_Contact */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_Contact +#define _Included_com_badlogic_gdx_physics_box2d_Contact +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniGetWorldManifold + * Signature: (J[F)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniGetWorldManifold + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniIsTouching + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniIsTouching + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniSetEnabled + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniSetEnabled + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniIsEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniIsEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniGetFixtureA + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniGetFixtureA + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Contact + * Method: jniGetFixtureB + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Contact_jniGetFixtureB + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/DistanceJoint.cpp b/AndEngine/jni/Box2D/DistanceJoint.cpp new file mode 100644 index 0000000..25917d6 --- /dev/null +++ b/AndEngine/jni/Box2D/DistanceJoint.cpp @@ -0,0 +1,89 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "DistanceJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniSetLength + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniSetLength + (JNIEnv *, jobject, jlong addr, jfloat len) +{ + b2DistanceJoint* joint = (b2DistanceJoint*)addr; + joint->SetLength( len ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniGetLength + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniGetLength + (JNIEnv *, jobject, jlong addr) +{ + b2DistanceJoint* joint = (b2DistanceJoint*)addr; + return joint->GetLength(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniSetFrequency + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniSetFrequency + (JNIEnv *, jobject, jlong addr, jfloat hz) +{ + b2DistanceJoint* joint = (b2DistanceJoint*)addr; + joint->SetFrequency( hz ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniGetFrequency + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniGetFrequency + (JNIEnv *, jobject, jlong addr ) +{ + b2DistanceJoint* joint = (b2DistanceJoint*)addr; + return joint->GetFrequency(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniSetDampingRatio + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniSetDampingRatio + (JNIEnv *, jobject, jlong addr, jfloat dampingRatio) +{ + b2DistanceJoint* joint = (b2DistanceJoint*)addr; + joint->SetDampingRatio( dampingRatio ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniGetDampingRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniGetDampingRatio + (JNIEnv *, jobject, jlong addr ) +{ + b2DistanceJoint* joint = (b2DistanceJoint*)addr; + return joint->GetDampingRatio(); +} diff --git a/AndEngine/jni/Box2D/DistanceJoint.h b/AndEngine/jni/Box2D/DistanceJoint.h new file mode 100644 index 0000000..44d4fff --- /dev/null +++ b/AndEngine/jni/Box2D/DistanceJoint.h @@ -0,0 +1,77 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_DistanceJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_DistanceJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_DistanceJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniSetLength + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniSetLength + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniGetLength + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniGetLength + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniSetFrequency + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniSetFrequency + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniGetFrequency + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniGetFrequency + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniSetDampingRatio + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniSetDampingRatio + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_DistanceJoint + * Method: jniGetDampingRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_DistanceJoint_jniGetDampingRatio + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2CircleContact.cpp b/AndEngine/jni/Box2D/Dynamics/Contacts/b2CircleContact.cpp new file mode 100644 index 0000000..19da090 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2CircleContact.cpp @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Contacts/b2CircleContact.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2WorldCallbacks.h" +#include "Box2D/Common/b2BlockAllocator.h" +#include "Box2D/Collision/b2TimeOfImpact.h" + +#include + +b2Contact* b2CircleContact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator) +{ + void* mem = allocator->Allocate(sizeof(b2CircleContact)); + return new (mem) b2CircleContact(fixtureA, fixtureB); +} + +void b2CircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) +{ + ((b2CircleContact*)contact)->~b2CircleContact(); + allocator->Free(contact, sizeof(b2CircleContact)); +} + +b2CircleContact::b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) + : b2Contact(fixtureA, fixtureB) +{ + b2Assert(m_fixtureA->GetType() == b2Shape::e_circle); + b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); +} + +void b2CircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) +{ + b2CollideCircles(manifold, + (b2CircleShape*)m_fixtureA->GetShape(), xfA, + (b2CircleShape*)m_fixtureB->GetShape(), xfB); +} diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2CircleContact.h b/AndEngine/jni/Box2D/Dynamics/Contacts/b2CircleContact.h new file mode 100644 index 0000000..1c1dc32 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2CircleContact.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_CIRCLE_CONTACT_H +#define B2_CIRCLE_CONTACT_H + +#include "Box2D/Dynamics/Contacts/b2Contact.h" + +class b2BlockAllocator; + +class b2CircleContact : public b2Contact +{ +public: + static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator); + static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); + + b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); + ~b2CircleContact() {} + + void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB); +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2Contact.cpp b/AndEngine/jni/Box2D/Dynamics/Contacts/b2Contact.cpp new file mode 100644 index 0000000..e7c0bfa --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2Contact.cpp @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/Contacts/b2CircleContact.h" +#include "Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h" +#include "Box2D/Dynamics/Contacts/b2PolygonContact.h" +#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" + +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/b2TimeOfImpact.h" +#include "Box2D/Collision/Shapes/b2Shape.h" +#include "Box2D/Common/b2BlockAllocator.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2World.h" + +b2ContactRegister b2Contact::s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; +bool b2Contact::s_initialized = false; + +void b2Contact::InitializeRegisters() +{ + AddType(b2CircleContact::Create, b2CircleContact::Destroy, b2Shape::e_circle, b2Shape::e_circle); + AddType(b2PolygonAndCircleContact::Create, b2PolygonAndCircleContact::Destroy, b2Shape::e_polygon, b2Shape::e_circle); + AddType(b2PolygonContact::Create, b2PolygonContact::Destroy, b2Shape::e_polygon, b2Shape::e_polygon); +} + +void b2Contact::AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destoryFcn, + b2Shape::Type type1, b2Shape::Type type2) +{ + b2Assert(b2Shape::e_unknown < type1 && type1 < b2Shape::e_typeCount); + b2Assert(b2Shape::e_unknown < type2 && type2 < b2Shape::e_typeCount); + + s_registers[type1][type2].createFcn = createFcn; + s_registers[type1][type2].destroyFcn = destoryFcn; + s_registers[type1][type2].primary = true; + + if (type1 != type2) + { + s_registers[type2][type1].createFcn = createFcn; + s_registers[type2][type1].destroyFcn = destoryFcn; + s_registers[type2][type1].primary = false; + } +} + +b2Contact* b2Contact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator) +{ + if (s_initialized == false) + { + InitializeRegisters(); + s_initialized = true; + } + + b2Shape::Type type1 = fixtureA->GetType(); + b2Shape::Type type2 = fixtureB->GetType(); + + b2Assert(b2Shape::e_unknown < type1 && type1 < b2Shape::e_typeCount); + b2Assert(b2Shape::e_unknown < type2 && type2 < b2Shape::e_typeCount); + + b2ContactCreateFcn* createFcn = s_registers[type1][type2].createFcn; + if (createFcn) + { + if (s_registers[type1][type2].primary) + { + return createFcn(fixtureA, fixtureB, allocator); + } + else + { + return createFcn(fixtureB, fixtureA, allocator); + } + } + else + { + return NULL; + } +} + +void b2Contact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) +{ + b2Assert(s_initialized == true); + + if (contact->m_manifold.pointCount > 0) + { + contact->GetFixtureA()->GetBody()->SetAwake(true); + contact->GetFixtureB()->GetBody()->SetAwake(true); + } + + b2Shape::Type typeA = contact->GetFixtureA()->GetType(); + b2Shape::Type typeB = contact->GetFixtureB()->GetType(); + + b2Assert(b2Shape::e_unknown < typeA && typeB < b2Shape::e_typeCount); + b2Assert(b2Shape::e_unknown < typeA && typeB < b2Shape::e_typeCount); + + b2ContactDestroyFcn* destroyFcn = s_registers[typeA][typeB].destroyFcn; + destroyFcn(contact, allocator); +} + +b2Contact::b2Contact(b2Fixture* fA, b2Fixture* fB) +{ + m_flags = e_enabledFlag; + + m_fixtureA = fA; + m_fixtureB = fB; + + m_manifold.pointCount = 0; + + m_prev = NULL; + m_next = NULL; + + m_nodeA.contact = NULL; + m_nodeA.prev = NULL; + m_nodeA.next = NULL; + m_nodeA.other = NULL; + + m_nodeB.contact = NULL; + m_nodeB.prev = NULL; + m_nodeB.next = NULL; + m_nodeB.other = NULL; + + m_toiCount = 0; +} + +// Update the contact manifold and touching status. +// Note: do not assume the fixture AABBs are overlapping or are valid. +void b2Contact::Update(b2ContactListener* listener) +{ + b2Manifold oldManifold = m_manifold; + + // Re-enable this contact. + m_flags |= e_enabledFlag; + + bool touching = false; + bool wasTouching = (m_flags & e_touchingFlag) == e_touchingFlag; + + bool sensorA = m_fixtureA->IsSensor(); + bool sensorB = m_fixtureB->IsSensor(); + bool sensor = sensorA || sensorB; + + b2Body* bodyA = m_fixtureA->GetBody(); + b2Body* bodyB = m_fixtureB->GetBody(); + const b2Transform& xfA = bodyA->GetTransform(); + const b2Transform& xfB = bodyB->GetTransform(); + + // Is this contact a sensor? + if (sensor) + { + const b2Shape* shapeA = m_fixtureA->GetShape(); + const b2Shape* shapeB = m_fixtureB->GetShape(); + touching = b2TestOverlap(shapeA, shapeB, xfA, xfB); + + // Sensors don't generate manifolds. + m_manifold.pointCount = 0; + } + else + { + Evaluate(&m_manifold, xfA, xfB); + touching = m_manifold.pointCount > 0; + + // Match old contact ids to new contact ids and copy the + // stored impulses to warm start the solver. + for (int32 i = 0; i < m_manifold.pointCount; ++i) + { + b2ManifoldPoint* mp2 = m_manifold.points + i; + mp2->normalImpulse = 0.0f; + mp2->tangentImpulse = 0.0f; + b2ContactID id2 = mp2->id; + + for (int32 j = 0; j < oldManifold.pointCount; ++j) + { + b2ManifoldPoint* mp1 = oldManifold.points + j; + + if (mp1->id.key == id2.key) + { + mp2->normalImpulse = mp1->normalImpulse; + mp2->tangentImpulse = mp1->tangentImpulse; + break; + } + } + } + + if (touching != wasTouching) + { + bodyA->SetAwake(true); + bodyB->SetAwake(true); + } + } + + if (touching) + { + m_flags |= e_touchingFlag; + } + else + { + m_flags &= ~e_touchingFlag; + } + + if (wasTouching == false && touching == true && listener) + { + listener->BeginContact(this); + } + + if (wasTouching == true && touching == false && listener) + { + listener->EndContact(this); + } + + if (sensor == false && touching && listener) + { + listener->PreSolve(this, &oldManifold); + } +} diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2Contact.h b/AndEngine/jni/Box2D/Dynamics/Contacts/b2Contact.h new file mode 100644 index 0000000..4751ce9 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2Contact.h @@ -0,0 +1,242 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_CONTACT_H +#define B2_CONTACT_H + +#include "Box2D/Common/b2Math.h" +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/Shapes/b2Shape.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/b2Fixture.h" + +class b2Body; +class b2Contact; +class b2Fixture; +class b2World; +class b2BlockAllocator; +class b2StackAllocator; +class b2ContactListener; + +typedef b2Contact* b2ContactCreateFcn(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator); +typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator); + +struct b2ContactRegister +{ + b2ContactCreateFcn* createFcn; + b2ContactDestroyFcn* destroyFcn; + bool primary; +}; + +/// A contact edge is used to connect bodies and contacts together +/// in a contact graph where each body is a node and each contact +/// is an edge. A contact edge belongs to a doubly linked list +/// maintained in each attached body. Each contact has two contact +/// nodes, one for each attached body. +struct b2ContactEdge +{ + b2Body* other; ///< provides quick access to the other body attached. + b2Contact* contact; ///< the contact + b2ContactEdge* prev; ///< the previous contact edge in the body's contact list + b2ContactEdge* next; ///< the next contact edge in the body's contact list +}; + +/// The class manages contact between two shapes. A contact exists for each overlapping +/// AABB in the broad-phase (except if filtered). Therefore a contact object may exist +/// that has no contact points. +class b2Contact +{ +public: + + /// Get the contact manifold. Do not modify the manifold unless you understand the + /// internals of Box2D. + b2Manifold* GetManifold(); + const b2Manifold* GetManifold() const; + + /// Get the world manifold. + void GetWorldManifold(b2WorldManifold* worldManifold) const; + + /// Is this contact touching? + bool IsTouching() const; + + /// Enable/disable this contact. This can be used inside the pre-solve + /// contact listener. The contact is only disabled for the current + /// time step (or sub-step in continuous collisions). + void SetEnabled(bool flag); + + /// Has this contact been disabled? + bool IsEnabled() const; + + /// Get the next contact in the world's contact list. + b2Contact* GetNext(); + const b2Contact* GetNext() const; + + /// Get the first fixture in this contact. + b2Fixture* GetFixtureA(); + const b2Fixture* GetFixtureA() const; + + /// Get the second fixture in this contact. + b2Fixture* GetFixtureB(); + const b2Fixture* GetFixtureB() const; + + /// Evaluate this contact with your own manifold and transforms. + virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0; + +protected: + friend class b2ContactManager; + friend class b2World; + friend class b2ContactSolver; + friend class b2Body; + friend class b2Fixture; + + // Flags stored in m_flags + enum + { + // Used when crawling contact graph when forming islands. + e_islandFlag = 0x0001, + + // Set when the shapes are touching. + e_touchingFlag = 0x0002, + + // This contact can be disabled (by user) + e_enabledFlag = 0x0004, + + // This contact needs filtering because a fixture filter was changed. + e_filterFlag = 0x0008, + + // This bullet contact had a TOI event + e_bulletHitFlag = 0x0010, + + }; + + /// Flag this contact for filtering. Filtering will occur the next time step. + void FlagForFiltering(); + + static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn, + b2Shape::Type typeA, b2Shape::Type typeB); + static void InitializeRegisters(); + static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator); + static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator); + static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); + + b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {} + b2Contact(b2Fixture* fixtureA, b2Fixture* fixtureB); + virtual ~b2Contact() {} + + void Update(b2ContactListener* listener); + + static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; + static bool s_initialized; + + uint32 m_flags; + + // World pool and list pointers. + b2Contact* m_prev; + b2Contact* m_next; + + // Nodes for connecting bodies. + b2ContactEdge m_nodeA; + b2ContactEdge m_nodeB; + + b2Fixture* m_fixtureA; + b2Fixture* m_fixtureB; + + b2Manifold m_manifold; + + int32 m_toiCount; +// float32 m_toi; +}; + +inline b2Manifold* b2Contact::GetManifold() +{ + return &m_manifold; +} + +inline const b2Manifold* b2Contact::GetManifold() const +{ + return &m_manifold; +} + +inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const +{ + const b2Body* bodyA = m_fixtureA->GetBody(); + const b2Body* bodyB = m_fixtureB->GetBody(); + const b2Shape* shapeA = m_fixtureA->GetShape(); + const b2Shape* shapeB = m_fixtureB->GetShape(); + + worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius); +} + +inline void b2Contact::SetEnabled(bool flag) +{ + if (flag) + { + m_flags |= e_enabledFlag; + } + else + { + m_flags &= ~e_enabledFlag; + } +} + +inline bool b2Contact::IsEnabled() const +{ + return (m_flags & e_enabledFlag) == e_enabledFlag; +} + +inline bool b2Contact::IsTouching() const +{ + return (m_flags & e_touchingFlag) == e_touchingFlag; +} + +inline b2Contact* b2Contact::GetNext() +{ + return m_next; +} + +inline const b2Contact* b2Contact::GetNext() const +{ + return m_next; +} + +inline b2Fixture* b2Contact::GetFixtureA() +{ + return m_fixtureA; +} + +inline const b2Fixture* b2Contact::GetFixtureA() const +{ + return m_fixtureA; +} + +inline b2Fixture* b2Contact::GetFixtureB() +{ + return m_fixtureB; +} + +inline const b2Fixture* b2Contact::GetFixtureB() const +{ + return m_fixtureB; +} + +inline void b2Contact::FlagForFiltering() +{ + m_flags |= e_filterFlag; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2ContactSolver.cpp b/AndEngine/jni/Box2D/Dynamics/Contacts/b2ContactSolver.cpp new file mode 100644 index 0000000..e2ae392 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2ContactSolver.cpp @@ -0,0 +1,623 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2World.h" +#include "Box2D/Common/b2StackAllocator.h" + +#define B2_DEBUG_SOLVER 0 + +b2ContactSolver::b2ContactSolver(b2Contact** contacts, int32 contactCount, + b2StackAllocator* allocator, float32 impulseRatio) +{ + m_allocator = allocator; + + m_constraintCount = contactCount; + m_constraints = (b2ContactConstraint*)m_allocator->Allocate(m_constraintCount * sizeof(b2ContactConstraint)); + + for (int32 i = 0; i < m_constraintCount; ++i) + { + b2Contact* contact = contacts[i]; + + b2Fixture* fixtureA = contact->m_fixtureA; + b2Fixture* fixtureB = contact->m_fixtureB; + b2Shape* shapeA = fixtureA->GetShape(); + b2Shape* shapeB = fixtureB->GetShape(); + float32 radiusA = shapeA->m_radius; + float32 radiusB = shapeB->m_radius; + b2Body* bodyA = fixtureA->GetBody(); + b2Body* bodyB = fixtureB->GetBody(); + b2Manifold* manifold = contact->GetManifold(); + + float32 friction = b2MixFriction(fixtureA->GetFriction(), fixtureB->GetFriction()); + float32 restitution = b2MixRestitution(fixtureA->GetRestitution(), fixtureB->GetRestitution()); + + b2Vec2 vA = bodyA->m_linearVelocity; + b2Vec2 vB = bodyB->m_linearVelocity; + float32 wA = bodyA->m_angularVelocity; + float32 wB = bodyB->m_angularVelocity; + + b2Assert(manifold->pointCount > 0); + + b2WorldManifold worldManifold; + worldManifold.Initialize(manifold, bodyA->m_xf, radiusA, bodyB->m_xf, radiusB); + + b2ContactConstraint* cc = m_constraints + i; + cc->bodyA = bodyA; + cc->bodyB = bodyB; + cc->manifold = manifold; + cc->normal = worldManifold.normal; + cc->pointCount = manifold->pointCount; + cc->friction = friction; + + cc->localNormal = manifold->localNormal; + cc->localPoint = manifold->localPoint; + cc->radius = radiusA + radiusB; + cc->type = manifold->type; + + for (int32 j = 0; j < cc->pointCount; ++j) + { + b2ManifoldPoint* cp = manifold->points + j; + b2ContactConstraintPoint* ccp = cc->points + j; + + ccp->normalImpulse = impulseRatio * cp->normalImpulse; + ccp->tangentImpulse = impulseRatio * cp->tangentImpulse; + + ccp->localPoint = cp->localPoint; + + ccp->rA = worldManifold.points[j] - bodyA->m_sweep.c; + ccp->rB = worldManifold.points[j] - bodyB->m_sweep.c; + + float32 rnA = b2Cross(ccp->rA, cc->normal); + float32 rnB = b2Cross(ccp->rB, cc->normal); + rnA *= rnA; + rnB *= rnB; + + float32 kNormal = bodyA->m_invMass + bodyB->m_invMass + bodyA->m_invI * rnA + bodyB->m_invI * rnB; + + b2Assert(kNormal > b2_epsilon); + ccp->normalMass = 1.0f / kNormal; + + b2Vec2 tangent = b2Cross(cc->normal, 1.0f); + + float32 rtA = b2Cross(ccp->rA, tangent); + float32 rtB = b2Cross(ccp->rB, tangent); + rtA *= rtA; + rtB *= rtB; + + float32 kTangent = bodyA->m_invMass + bodyB->m_invMass + bodyA->m_invI * rtA + bodyB->m_invI * rtB; + + b2Assert(kTangent > b2_epsilon); + ccp->tangentMass = 1.0f / kTangent; + + // Setup a velocity bias for restitution. + ccp->velocityBias = 0.0f; + float32 vRel = b2Dot(cc->normal, vB + b2Cross(wB, ccp->rB) - vA - b2Cross(wA, ccp->rA)); + if (vRel < -b2_velocityThreshold) + { + ccp->velocityBias = -restitution * vRel; + } + } + + // If we have two points, then prepare the block solver. + if (cc->pointCount == 2) + { + b2ContactConstraintPoint* ccp1 = cc->points + 0; + b2ContactConstraintPoint* ccp2 = cc->points + 1; + + float32 invMassA = bodyA->m_invMass; + float32 invIA = bodyA->m_invI; + float32 invMassB = bodyB->m_invMass; + float32 invIB = bodyB->m_invI; + + float32 rn1A = b2Cross(ccp1->rA, cc->normal); + float32 rn1B = b2Cross(ccp1->rB, cc->normal); + float32 rn2A = b2Cross(ccp2->rA, cc->normal); + float32 rn2B = b2Cross(ccp2->rB, cc->normal); + + float32 k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; + float32 k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; + float32 k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; + + // Ensure a reasonable condition number. + const float32 k_maxConditionNumber = 100.0f; + if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) + { + // K is safe to invert. + cc->K.col1.Set(k11, k12); + cc->K.col2.Set(k12, k22); + cc->normalMass = cc->K.GetInverse(); + } + else + { + // The constraints are redundant, just use one. + // TODO_ERIN use deepest? + cc->pointCount = 1; + } + } + } +} + +b2ContactSolver::~b2ContactSolver() +{ + m_allocator->Free(m_constraints); +} + +void b2ContactSolver::WarmStart() +{ + // Warm start. + for (int32 i = 0; i < m_constraintCount; ++i) + { + b2ContactConstraint* c = m_constraints + i; + + b2Body* bodyA = c->bodyA; + b2Body* bodyB = c->bodyB; + float32 invMassA = bodyA->m_invMass; + float32 invIA = bodyA->m_invI; + float32 invMassB = bodyB->m_invMass; + float32 invIB = bodyB->m_invI; + b2Vec2 normal = c->normal; + b2Vec2 tangent = b2Cross(normal, 1.0f); + + for (int32 j = 0; j < c->pointCount; ++j) + { + b2ContactConstraintPoint* ccp = c->points + j; + b2Vec2 P = ccp->normalImpulse * normal + ccp->tangentImpulse * tangent; + bodyA->m_angularVelocity -= invIA * b2Cross(ccp->rA, P); + bodyA->m_linearVelocity -= invMassA * P; + bodyB->m_angularVelocity += invIB * b2Cross(ccp->rB, P); + bodyB->m_linearVelocity += invMassB * P; + } + } +} + +void b2ContactSolver::SolveVelocityConstraints() +{ + for (int32 i = 0; i < m_constraintCount; ++i) + { + b2ContactConstraint* c = m_constraints + i; + b2Body* bodyA = c->bodyA; + b2Body* bodyB = c->bodyB; + float32 wA = bodyA->m_angularVelocity; + float32 wB = bodyB->m_angularVelocity; + b2Vec2 vA = bodyA->m_linearVelocity; + b2Vec2 vB = bodyB->m_linearVelocity; + float32 invMassA = bodyA->m_invMass; + float32 invIA = bodyA->m_invI; + float32 invMassB = bodyB->m_invMass; + float32 invIB = bodyB->m_invI; + b2Vec2 normal = c->normal; + b2Vec2 tangent = b2Cross(normal, 1.0f); + float32 friction = c->friction; + + b2Assert(c->pointCount == 1 || c->pointCount == 2); + + // Solve tangent constraints + for (int32 j = 0; j < c->pointCount; ++j) + { + b2ContactConstraintPoint* ccp = c->points + j; + + // Relative velocity at contact + b2Vec2 dv = vB + b2Cross(wB, ccp->rB) - vA - b2Cross(wA, ccp->rA); + + // Compute tangent force + float32 vt = b2Dot(dv, tangent); + float32 lambda = ccp->tangentMass * (-vt); + + // b2Clamp the accumulated force + float32 maxFriction = friction * ccp->normalImpulse; + float32 newImpulse = b2Clamp(ccp->tangentImpulse + lambda, -maxFriction, maxFriction); + lambda = newImpulse - ccp->tangentImpulse; + + // Apply contact impulse + b2Vec2 P = lambda * tangent; + + vA -= invMassA * P; + wA -= invIA * b2Cross(ccp->rA, P); + + vB += invMassB * P; + wB += invIB * b2Cross(ccp->rB, P); + + ccp->tangentImpulse = newImpulse; + } + + // Solve normal constraints + if (c->pointCount == 1) + { + b2ContactConstraintPoint* ccp = c->points + 0; + + // Relative velocity at contact + b2Vec2 dv = vB + b2Cross(wB, ccp->rB) - vA - b2Cross(wA, ccp->rA); + + // Compute normal impulse + float32 vn = b2Dot(dv, normal); + float32 lambda = -ccp->normalMass * (vn - ccp->velocityBias); + + // b2Clamp the accumulated impulse + float32 newImpulse = b2Max(ccp->normalImpulse + lambda, 0.0f); + lambda = newImpulse - ccp->normalImpulse; + + // Apply contact impulse + b2Vec2 P = lambda * normal; + vA -= invMassA * P; + wA -= invIA * b2Cross(ccp->rA, P); + + vB += invMassB * P; + wB += invIB * b2Cross(ccp->rB, P); + ccp->normalImpulse = newImpulse; + } + else + { + // Block solver developed in collaboration with Dirk Gregorius (back in 01/07 on Box2D_Lite). + // Build the mini LCP for this contact patch + // + // vn = A * x + b, vn >= 0, , vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2 + // + // A = J * W * JT and J = ( -n, -r1 x n, n, r2 x n ) + // b = vn_0 - velocityBias + // + // The system is solved using the "Total enumeration method" (s. Murty). The complementary constraint vn_i * x_i + // implies that we must have in any solution either vn_i = 0 or x_i = 0. So for the 2D contact problem the cases + // vn1 = 0 and vn2 = 0, x1 = 0 and x2 = 0, x1 = 0 and vn2 = 0, x2 = 0 and vn1 = 0 need to be tested. The first valid + // solution that satisfies the problem is chosen. + // + // In order to account of the accumulated impulse 'a' (because of the iterative nature of the solver which only requires + // that the accumulated impulse is clamped and not the incremental impulse) we change the impulse variable (x_i). + // + // Substitute: + // + // x = x' - a + // + // Plug into above equation: + // + // vn = A * x + b + // = A * (x' - a) + b + // = A * x' + b - A * a + // = A * x' + b' + // b' = b - A * a; + + b2ContactConstraintPoint* cp1 = c->points + 0; + b2ContactConstraintPoint* cp2 = c->points + 1; + + b2Vec2 a(cp1->normalImpulse, cp2->normalImpulse); + b2Assert(a.x >= 0.0f && a.y >= 0.0f); + + // Relative velocity at contact + b2Vec2 dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); + b2Vec2 dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); + + // Compute normal velocity + float32 vn1 = b2Dot(dv1, normal); + float32 vn2 = b2Dot(dv2, normal); + + b2Vec2 b; + b.x = vn1 - cp1->velocityBias; + b.y = vn2 - cp2->velocityBias; + b -= b2Mul(c->K, a); + + const float32 k_errorTol = 1e-3f; + B2_NOT_USED(k_errorTol); + + for (;;) + { + // + // Case 1: vn = 0 + // + // 0 = A * x' + b' + // + // Solve for x': + // + // x' = - inv(A) * b' + // + b2Vec2 x = - b2Mul(c->normalMass, b); + + if (x.x >= 0.0f && x.y >= 0.0f) + { + // Resubstitute for the incremental impulse + b2Vec2 d = x - a; + + // Apply incremental impulse + b2Vec2 P1 = d.x * normal; + b2Vec2 P2 = d.y * normal; + vA -= invMassA * (P1 + P2); + wA -= invIA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + + vB += invMassB * (P1 + P2); + wB += invIB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + + // Accumulate + cp1->normalImpulse = x.x; + cp2->normalImpulse = x.y; + +#if B2_DEBUG_SOLVER == 1 + // Postconditions + dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); + dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); + + // Compute normal velocity + vn1 = b2Dot(dv1, normal); + vn2 = b2Dot(dv2, normal); + + b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol); + b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol); +#endif + break; + } + + // + // Case 2: vn1 = 0 and x2 = 0 + // + // 0 = a11 * x1' + a12 * 0 + b1' + // vn2 = a21 * x1' + a22 * 0 + b2' + // + x.x = - cp1->normalMass * b.x; + x.y = 0.0f; + vn1 = 0.0f; + vn2 = c->K.col1.y * x.x + b.y; + + if (x.x >= 0.0f && vn2 >= 0.0f) + { + // Resubstitute for the incremental impulse + b2Vec2 d = x - a; + + // Apply incremental impulse + b2Vec2 P1 = d.x * normal; + b2Vec2 P2 = d.y * normal; + vA -= invMassA * (P1 + P2); + wA -= invIA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + + vB += invMassB * (P1 + P2); + wB += invIB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + + // Accumulate + cp1->normalImpulse = x.x; + cp2->normalImpulse = x.y; + +#if B2_DEBUG_SOLVER == 1 + // Postconditions + dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); + + // Compute normal velocity + vn1 = b2Dot(dv1, normal); + + b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol); +#endif + break; + } + + + // + // Case 3: vn2 = 0 and x1 = 0 + // + // vn1 = a11 * 0 + a12 * x2' + b1' + // 0 = a21 * 0 + a22 * x2' + b2' + // + x.x = 0.0f; + x.y = - cp2->normalMass * b.y; + vn1 = c->K.col2.x * x.y + b.x; + vn2 = 0.0f; + + if (x.y >= 0.0f && vn1 >= 0.0f) + { + // Resubstitute for the incremental impulse + b2Vec2 d = x - a; + + // Apply incremental impulse + b2Vec2 P1 = d.x * normal; + b2Vec2 P2 = d.y * normal; + vA -= invMassA * (P1 + P2); + wA -= invIA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + + vB += invMassB * (P1 + P2); + wB += invIB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + + // Accumulate + cp1->normalImpulse = x.x; + cp2->normalImpulse = x.y; + +#if B2_DEBUG_SOLVER == 1 + // Postconditions + dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); + + // Compute normal velocity + vn2 = b2Dot(dv2, normal); + + b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol); +#endif + break; + } + + // + // Case 4: x1 = 0 and x2 = 0 + // + // vn1 = b1 + // vn2 = b2; + x.x = 0.0f; + x.y = 0.0f; + vn1 = b.x; + vn2 = b.y; + + if (vn1 >= 0.0f && vn2 >= 0.0f ) + { + // Resubstitute for the incremental impulse + b2Vec2 d = x - a; + + // Apply incremental impulse + b2Vec2 P1 = d.x * normal; + b2Vec2 P2 = d.y * normal; + vA -= invMassA * (P1 + P2); + wA -= invIA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + + vB += invMassB * (P1 + P2); + wB += invIB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + + // Accumulate + cp1->normalImpulse = x.x; + cp2->normalImpulse = x.y; + + break; + } + + // No solution, give up. This is hit sometimes, but it doesn't seem to matter. + break; + } + } + + bodyA->m_linearVelocity = vA; + bodyA->m_angularVelocity = wA; + bodyB->m_linearVelocity = vB; + bodyB->m_angularVelocity = wB; + } +} + +void b2ContactSolver::StoreImpulses() +{ + for (int32 i = 0; i < m_constraintCount; ++i) + { + b2ContactConstraint* c = m_constraints + i; + b2Manifold* m = c->manifold; + + for (int32 j = 0; j < c->pointCount; ++j) + { + m->points[j].normalImpulse = c->points[j].normalImpulse; + m->points[j].tangentImpulse = c->points[j].tangentImpulse; + } + } +} + +struct b2PositionSolverManifold +{ + void Initialize(b2ContactConstraint* cc, int32 index) + { + b2Assert(cc->pointCount > 0); + + switch (cc->type) + { + case b2Manifold::e_circles: + { + b2Vec2 pointA = cc->bodyA->GetWorldPoint(cc->localPoint); + b2Vec2 pointB = cc->bodyB->GetWorldPoint(cc->points[0].localPoint); + if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon) + { + normal = pointB - pointA; + normal.Normalize(); + } + else + { + normal.Set(1.0f, 0.0f); + } + + point = 0.5f * (pointA + pointB); + separation = b2Dot(pointB - pointA, normal) - cc->radius; + } + break; + + case b2Manifold::e_faceA: + { + normal = cc->bodyA->GetWorldVector(cc->localNormal); + b2Vec2 planePoint = cc->bodyA->GetWorldPoint(cc->localPoint); + + b2Vec2 clipPoint = cc->bodyB->GetWorldPoint(cc->points[index].localPoint); + separation = b2Dot(clipPoint - planePoint, normal) - cc->radius; + point = clipPoint; + } + break; + + case b2Manifold::e_faceB: + { + normal = cc->bodyB->GetWorldVector(cc->localNormal); + b2Vec2 planePoint = cc->bodyB->GetWorldPoint(cc->localPoint); + + b2Vec2 clipPoint = cc->bodyA->GetWorldPoint(cc->points[index].localPoint); + separation = b2Dot(clipPoint - planePoint, normal) - cc->radius; + point = clipPoint; + + // Ensure normal points from A to B + normal = -normal; + } + break; + } + } + + b2Vec2 normal; + b2Vec2 point; + float32 separation; +}; + +// Sequential solver. +bool b2ContactSolver::SolvePositionConstraints(float32 baumgarte) +{ + float32 minSeparation = 0.0f; + + for (int32 i = 0; i < m_constraintCount; ++i) + { + b2ContactConstraint* c = m_constraints + i; + b2Body* bodyA = c->bodyA; + b2Body* bodyB = c->bodyB; + + float32 invMassA = bodyA->m_mass * bodyA->m_invMass; + float32 invIA = bodyA->m_mass * bodyA->m_invI; + float32 invMassB = bodyB->m_mass * bodyB->m_invMass; + float32 invIB = bodyB->m_mass * bodyB->m_invI; + + // Solve normal constraints + for (int32 j = 0; j < c->pointCount; ++j) + { + b2PositionSolverManifold psm; + psm.Initialize(c, j); + b2Vec2 normal = psm.normal; + + b2Vec2 point = psm.point; + float32 separation = psm.separation; + + b2Vec2 rA = point - bodyA->m_sweep.c; + b2Vec2 rB = point - bodyB->m_sweep.c; + + // Track max constraint error. + minSeparation = b2Min(minSeparation, separation); + + // Prevent large corrections and allow slop. + float32 C = b2Clamp(baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f); + + // Compute the effective mass. + float32 rnA = b2Cross(rA, normal); + float32 rnB = b2Cross(rB, normal); + float32 K = invMassA + invMassB + invIA * rnA * rnA + invIB * rnB * rnB; + + // Compute normal impulse + float32 impulse = K > 0.0f ? - C / K : 0.0f; + + b2Vec2 P = impulse * normal; + + bodyA->m_sweep.c -= invMassA * P; + bodyA->m_sweep.a -= invIA * b2Cross(rA, P); + bodyA->SynchronizeTransform(); + + bodyB->m_sweep.c += invMassB * P; + bodyB->m_sweep.a += invIB * b2Cross(rB, P); + bodyB->SynchronizeTransform(); + } + } + + // We can't expect minSpeparation >= -b2_linearSlop because we don't + // push the separation above -b2_linearSlop. + return minSeparation >= -1.5f * b2_linearSlop; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2ContactSolver.h b/AndEngine/jni/Box2D/Dynamics/Contacts/b2ContactSolver.h new file mode 100644 index 0000000..d2dd782 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2ContactSolver.h @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_CONTACT_SOLVER_H +#define B2_CONTACT_SOLVER_H + +#include "Box2D/Common/b2Math.h" +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Dynamics/b2Island.h" + +class b2Contact; +class b2Body; +class b2StackAllocator; + +struct b2ContactConstraintPoint +{ + b2Vec2 localPoint; + b2Vec2 rA; + b2Vec2 rB; + float32 normalImpulse; + float32 tangentImpulse; + float32 normalMass; + float32 tangentMass; + float32 velocityBias; +}; + +struct b2ContactConstraint +{ + b2ContactConstraintPoint points[b2_maxManifoldPoints]; + b2Vec2 localNormal; + b2Vec2 localPoint; + b2Vec2 normal; + b2Mat22 normalMass; + b2Mat22 K; + b2Body* bodyA; + b2Body* bodyB; + b2Manifold::Type type; + float32 radius; + float32 friction; + int32 pointCount; + b2Manifold* manifold; +}; + +class b2ContactSolver +{ +public: + b2ContactSolver(b2Contact** contacts, int32 contactCount, + b2StackAllocator* allocator, float32 impulseRatio); + + ~b2ContactSolver(); + + void WarmStart(); + void SolveVelocityConstraints(); + void StoreImpulses(); + + bool SolvePositionConstraints(float32 baumgarte); + + b2StackAllocator* m_allocator; + b2ContactConstraint* m_constraints; + int m_constraintCount; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp new file mode 100644 index 0000000..e43b189 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h" +#include "Box2D/Common/b2BlockAllocator.h" +#include "Box2D/Collision/b2TimeOfImpact.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2WorldCallbacks.h" + +#include + +b2Contact* b2PolygonAndCircleContact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator) +{ + void* mem = allocator->Allocate(sizeof(b2PolygonAndCircleContact)); + return new (mem) b2PolygonAndCircleContact(fixtureA, fixtureB); +} + +void b2PolygonAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) +{ + ((b2PolygonAndCircleContact*)contact)->~b2PolygonAndCircleContact(); + allocator->Free(contact, sizeof(b2PolygonAndCircleContact)); +} + +b2PolygonAndCircleContact::b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB) +: b2Contact(fixtureA, fixtureB) +{ + b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon); + b2Assert(m_fixtureB->GetType() == b2Shape::e_circle); +} + +void b2PolygonAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) +{ + b2CollidePolygonAndCircle( manifold, + (b2PolygonShape*)m_fixtureA->GetShape(), xfA, + (b2CircleShape*)m_fixtureB->GetShape(), xfB); +} diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h new file mode 100644 index 0000000..26fac3a --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_POLYGON_AND_CIRCLE_CONTACT_H +#define B2_POLYGON_AND_CIRCLE_CONTACT_H + +#include "Box2D/Dynamics/Contacts/b2Contact.h" + +class b2BlockAllocator; + +class b2PolygonAndCircleContact : public b2Contact +{ +public: + static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator); + static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); + + b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB); + ~b2PolygonAndCircleContact() {} + + void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB); +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonContact.cpp b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonContact.cpp new file mode 100644 index 0000000..470d3cb --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonContact.cpp @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Contacts/b2PolygonContact.h" +#include "Box2D/Common/b2BlockAllocator.h" +#include "Box2D/Collision/b2TimeOfImpact.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2WorldCallbacks.h" + +#include + +b2Contact* b2PolygonContact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator) +{ + void* mem = allocator->Allocate(sizeof(b2PolygonContact)); + return new (mem) b2PolygonContact(fixtureA, fixtureB); +} + +void b2PolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator) +{ + ((b2PolygonContact*)contact)->~b2PolygonContact(); + allocator->Free(contact, sizeof(b2PolygonContact)); +} + +b2PolygonContact::b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB) + : b2Contact(fixtureA, fixtureB) +{ + b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon); + b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon); +} + +void b2PolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) +{ + b2CollidePolygons( manifold, + (b2PolygonShape*)m_fixtureA->GetShape(), xfA, + (b2PolygonShape*)m_fixtureB->GetShape(), xfB); +} diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonContact.h b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonContact.h new file mode 100644 index 0000000..672450a --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2PolygonContact.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_POLYGON_CONTACT_H +#define B2_POLYGON_CONTACT_H + +#include "Box2D/Dynamics/Contacts/b2Contact.h" + +class b2BlockAllocator; + +class b2PolygonContact : public b2Contact +{ +public: + static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator); + static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); + + b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB); + ~b2PolygonContact() {} + + void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB); +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2TOISolver.cpp b/AndEngine/jni/Box2D/Dynamics/Contacts/b2TOISolver.cpp new file mode 100644 index 0000000..56e52ce --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2TOISolver.cpp @@ -0,0 +1,231 @@ +/* +* Copyright (c) 2006-2010 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Contacts/b2TOISolver.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Common/b2StackAllocator.h" + +struct b2TOIConstraint +{ + b2Vec2 localPoints[b2_maxManifoldPoints]; + b2Vec2 localNormal; + b2Vec2 localPoint; + b2Manifold::Type type; + float32 radius; + int32 pointCount; + b2Body* bodyA; + b2Body* bodyB; +}; + +b2TOISolver::b2TOISolver(b2StackAllocator* allocator) +{ + m_allocator = allocator; + m_constraints = NULL; + m_count = NULL; + m_toiBody = NULL; +} + +b2TOISolver::~b2TOISolver() +{ + Clear(); +} + +void b2TOISolver::Clear() +{ + if (m_allocator && m_constraints) + { + m_allocator->Free(m_constraints); + m_constraints = NULL; + } +} + +void b2TOISolver::Initialize(b2Contact** contacts, int32 count, b2Body* toiBody) +{ + Clear(); + + m_count = count; + m_toiBody = toiBody; + + m_constraints = (b2TOIConstraint*) m_allocator->Allocate(m_count * sizeof(b2TOIConstraint)); + + for (int32 i = 0; i < m_count; ++i) + { + b2Contact* contact = contacts[i]; + + b2Fixture* fixtureA = contact->GetFixtureA(); + b2Fixture* fixtureB = contact->GetFixtureB(); + b2Shape* shapeA = fixtureA->GetShape(); + b2Shape* shapeB = fixtureB->GetShape(); + float32 radiusA = shapeA->m_radius; + float32 radiusB = shapeB->m_radius; + b2Body* bodyA = fixtureA->GetBody(); + b2Body* bodyB = fixtureB->GetBody(); + b2Manifold* manifold = contact->GetManifold(); + + b2Assert(manifold->pointCount > 0); + + b2TOIConstraint* constraint = m_constraints + i; + constraint->bodyA = bodyA; + constraint->bodyB = bodyB; + constraint->localNormal = manifold->localNormal; + constraint->localPoint = manifold->localPoint; + constraint->type = manifold->type; + constraint->pointCount = manifold->pointCount; + constraint->radius = radiusA + radiusB; + + for (int32 j = 0; j < constraint->pointCount; ++j) + { + b2ManifoldPoint* cp = manifold->points + j; + constraint->localPoints[j] = cp->localPoint; + } + } +} + +struct b2TOISolverManifold +{ + void Initialize(b2TOIConstraint* cc, int32 index) + { + b2Assert(cc->pointCount > 0); + + switch (cc->type) + { + case b2Manifold::e_circles: + { + b2Vec2 pointA = cc->bodyA->GetWorldPoint(cc->localPoint); + b2Vec2 pointB = cc->bodyB->GetWorldPoint(cc->localPoints[0]); + if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon) + { + normal = pointB - pointA; + normal.Normalize(); + } + else + { + normal.Set(1.0f, 0.0f); + } + + point = 0.5f * (pointA + pointB); + separation = b2Dot(pointB - pointA, normal) - cc->radius; + } + break; + + case b2Manifold::e_faceA: + { + normal = cc->bodyA->GetWorldVector(cc->localNormal); + b2Vec2 planePoint = cc->bodyA->GetWorldPoint(cc->localPoint); + + b2Vec2 clipPoint = cc->bodyB->GetWorldPoint(cc->localPoints[index]); + separation = b2Dot(clipPoint - planePoint, normal) - cc->radius; + point = clipPoint; + } + break; + + case b2Manifold::e_faceB: + { + normal = cc->bodyB->GetWorldVector(cc->localNormal); + b2Vec2 planePoint = cc->bodyB->GetWorldPoint(cc->localPoint); + + b2Vec2 clipPoint = cc->bodyA->GetWorldPoint(cc->localPoints[index]); + separation = b2Dot(clipPoint - planePoint, normal) - cc->radius; + point = clipPoint; + + // Ensure normal points from A to B + normal = -normal; + } + break; + } + } + + b2Vec2 normal; + b2Vec2 point; + float32 separation; +}; + +// Push out the toi body to provide clearance for further simulation. +bool b2TOISolver::Solve(float32 baumgarte) +{ + float32 minSeparation = 0.0f; + + for (int32 i = 0; i < m_count; ++i) + { + b2TOIConstraint* c = m_constraints + i; + b2Body* bodyA = c->bodyA; + b2Body* bodyB = c->bodyB; + + float32 massA = bodyA->m_mass; + float32 massB = bodyB->m_mass; + + // Only the TOI body should move. + if (bodyA == m_toiBody) + { + massB = 0.0f; + } + else + { + massA = 0.0f; + } + + float32 invMassA = massA * bodyA->m_invMass; + float32 invIA = massA * bodyA->m_invI; + float32 invMassB = massB * bodyB->m_invMass; + float32 invIB = massB * bodyB->m_invI; + + // Solve normal constraints + for (int32 j = 0; j < c->pointCount; ++j) + { + b2TOISolverManifold psm; + psm.Initialize(c, j); + b2Vec2 normal = psm.normal; + + b2Vec2 point = psm.point; + float32 separation = psm.separation; + + b2Vec2 rA = point - bodyA->m_sweep.c; + b2Vec2 rB = point - bodyB->m_sweep.c; + + // Track max constraint error. + minSeparation = b2Min(minSeparation, separation); + + // Prevent large corrections and allow slop. + float32 C = b2Clamp(baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f); + + // Compute the effective mass. + float32 rnA = b2Cross(rA, normal); + float32 rnB = b2Cross(rB, normal); + float32 K = invMassA + invMassB + invIA * rnA * rnA + invIB * rnB * rnB; + + // Compute normal impulse + float32 impulse = K > 0.0f ? - C / K : 0.0f; + + b2Vec2 P = impulse * normal; + + bodyA->m_sweep.c -= invMassA * P; + bodyA->m_sweep.a -= invIA * b2Cross(rA, P); + bodyA->SynchronizeTransform(); + + bodyB->m_sweep.c += invMassB * P; + bodyB->m_sweep.a += invIB * b2Cross(rB, P); + bodyB->SynchronizeTransform(); + } + } + + // We can't expect minSpeparation >= -b2_linearSlop because we don't + // push the separation above -b2_linearSlop. + return minSeparation >= -1.5f * b2_linearSlop; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Contacts/b2TOISolver.h b/AndEngine/jni/Box2D/Dynamics/Contacts/b2TOISolver.h new file mode 100644 index 0000000..ec15ced --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Contacts/b2TOISolver.h @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2006-2010 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_TOI_SOLVER_H +#define B2_TOI_SOLVER_H + +#include "Box2D/Common/b2Math.h" + +class b2Contact; +class b2Body; +struct b2TOIConstraint; +class b2StackAllocator; + +/// This is a pure position solver for a single movable body in contact with +/// multiple non-moving bodies. +class b2TOISolver +{ +public: + b2TOISolver(b2StackAllocator* allocator); + ~b2TOISolver(); + + void Initialize(b2Contact** contacts, int32 contactCount, b2Body* toiBody); + void Clear(); + + // Perform one solver iteration. Returns true if converged. + bool Solve(float32 baumgarte); + +private: + + b2TOIConstraint* m_constraints; + int32 m_count; + b2Body* m_toiBody; + b2StackAllocator* m_allocator; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2DistanceJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2DistanceJoint.cpp new file mode 100644 index 0000000..6d8b3f1 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2DistanceJoint.cpp @@ -0,0 +1,211 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2DistanceJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// 1-D constrained system +// m (v2 - v1) = lambda +// v2 + (beta/h) * x1 + gamma * lambda = 0, gamma has units of inverse mass. +// x2 = x1 + h * v2 + +// 1-D mass-damper-spring system +// m (v2 - v1) + h * d * v2 + h * k * + +// C = norm(p2 - p1) - L +// u = (p2 - p1) / norm(p2 - p1) +// Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1)) +// J = [-u -cross(r1, u) u cross(r2, u)] +// K = J * invM * JT +// = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2 + +void b2DistanceJointDef::Initialize(b2Body* b1, b2Body* b2, + const b2Vec2& anchor1, const b2Vec2& anchor2) +{ + bodyA = b1; + bodyB = b2; + localAnchorA = bodyA->GetLocalPoint(anchor1); + localAnchorB = bodyB->GetLocalPoint(anchor2); + b2Vec2 d = anchor2 - anchor1; + length = d.Length(); +} + + +b2DistanceJoint::b2DistanceJoint(const b2DistanceJointDef* def) +: b2Joint(def) +{ + m_localAnchor1 = def->localAnchorA; + m_localAnchor2 = def->localAnchorB; + m_length = def->length; + m_frequencyHz = def->frequencyHz; + m_dampingRatio = def->dampingRatio; + m_impulse = 0.0f; + m_gamma = 0.0f; + m_bias = 0.0f; +} + +void b2DistanceJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + // Compute the effective mass matrix. + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + m_u = b2->m_sweep.c + r2 - b1->m_sweep.c - r1; + + // Handle singularity. + float32 length = m_u.Length(); + if (length > b2_linearSlop) + { + m_u *= 1.0f / length; + } + else + { + m_u.Set(0.0f, 0.0f); + } + + float32 cr1u = b2Cross(r1, m_u); + float32 cr2u = b2Cross(r2, m_u); + float32 invMass = b1->m_invMass + b1->m_invI * cr1u * cr1u + b2->m_invMass + b2->m_invI * cr2u * cr2u; + + m_mass = invMass != 0.0f ? 1.0f / invMass : 0.0f; + + if (m_frequencyHz > 0.0f) + { + float32 C = length - m_length; + + // Frequency + float32 omega = 2.0f * b2_pi * m_frequencyHz; + + // Damping coefficient + float32 d = 2.0f * m_mass * m_dampingRatio * omega; + + // Spring stiffness + float32 k = m_mass * omega * omega; + + // magic formulas + m_gamma = step.dt * (d + step.dt * k); + m_gamma = m_gamma != 0.0f ? 1.0f / m_gamma : 0.0f; + m_bias = C * step.dt * k * m_gamma; + + m_mass = invMass + m_gamma; + m_mass = m_mass != 0.0f ? 1.0f / m_mass : 0.0f; + } + + if (step.warmStarting) + { + // Scale the impulse to support a variable time step. + m_impulse *= step.dtRatio; + + b2Vec2 P = m_impulse * m_u; + b1->m_linearVelocity -= b1->m_invMass * P; + b1->m_angularVelocity -= b1->m_invI * b2Cross(r1, P); + b2->m_linearVelocity += b2->m_invMass * P; + b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P); + } + else + { + m_impulse = 0.0f; + } +} + +void b2DistanceJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + B2_NOT_USED(step); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + // Cdot = dot(u, v + cross(w, r)) + b2Vec2 v1 = b1->m_linearVelocity + b2Cross(b1->m_angularVelocity, r1); + b2Vec2 v2 = b2->m_linearVelocity + b2Cross(b2->m_angularVelocity, r2); + float32 Cdot = b2Dot(m_u, v2 - v1); + + float32 impulse = -m_mass * (Cdot + m_bias + m_gamma * m_impulse); + m_impulse += impulse; + + b2Vec2 P = impulse * m_u; + b1->m_linearVelocity -= b1->m_invMass * P; + b1->m_angularVelocity -= b1->m_invI * b2Cross(r1, P); + b2->m_linearVelocity += b2->m_invMass * P; + b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P); +} + +bool b2DistanceJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + if (m_frequencyHz > 0.0f) + { + // There is no position correction for soft distance constraints. + return true; + } + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + b2Vec2 d = b2->m_sweep.c + r2 - b1->m_sweep.c - r1; + + float32 length = d.Normalize(); + float32 C = length - m_length; + C = b2Clamp(C, -b2_maxLinearCorrection, b2_maxLinearCorrection); + + float32 impulse = -m_mass * C; + m_u = d; + b2Vec2 P = impulse * m_u; + + b1->m_sweep.c -= b1->m_invMass * P; + b1->m_sweep.a -= b1->m_invI * b2Cross(r1, P); + b2->m_sweep.c += b2->m_invMass * P; + b2->m_sweep.a += b2->m_invI * b2Cross(r2, P); + + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + + return b2Abs(C) < b2_linearSlop; +} + +b2Vec2 b2DistanceJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchor1); +} + +b2Vec2 b2DistanceJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor2); +} + +b2Vec2 b2DistanceJoint::GetReactionForce(float32 inv_dt) const +{ + b2Vec2 F = (inv_dt * m_impulse) * m_u; + return F; +} + +float32 b2DistanceJoint::GetReactionTorque(float32 inv_dt) const +{ + B2_NOT_USED(inv_dt); + return 0.0f; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2DistanceJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2DistanceJoint.h new file mode 100644 index 0000000..ee06655 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2DistanceJoint.h @@ -0,0 +1,140 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_DISTANCE_JOINT_H +#define B2_DISTANCE_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Distance joint definition. This requires defining an +/// anchor point on both bodies and the non-zero length of the +/// distance joint. The definition uses local anchor points +/// so that the initial configuration can violate the constraint +/// slightly. This helps when saving and loading a game. +/// @warning Do not use a zero or short length. +struct b2DistanceJointDef : public b2JointDef +{ + b2DistanceJointDef() + { + type = e_distanceJoint; + localAnchorA.Set(0.0f, 0.0f); + localAnchorB.Set(0.0f, 0.0f); + length = 1.0f; + frequencyHz = 0.0f; + dampingRatio = 0.0f; + } + + /// Initialize the bodies, anchors, and length using the world + /// anchors. + void Initialize(b2Body* bodyA, b2Body* bodyB, + const b2Vec2& anchorA, const b2Vec2& anchorB); + + /// The local anchor point relative to body1's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to body2's origin. + b2Vec2 localAnchorB; + + /// The natural length between the anchor points. + float32 length; + + /// The mass-spring-damper frequency in Hertz. + float32 frequencyHz; + + /// The damping ratio. 0 = no damping, 1 = critical damping. + float32 dampingRatio; +}; + +/// A distance joint constrains two points on two bodies +/// to remain at a fixed distance from each other. You can view +/// this as a massless, rigid rod. +class b2DistanceJoint : public b2Joint +{ +public: + + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Set/get the natural length. + /// Manipulating the length can lead to non-physical behavior when the frequency is zero. + void SetLength(float32 length); + float32 GetLength() const; + + // Set/get frequency in Hz. + void SetFrequency(float32 hz); + float32 GetFrequency() const; + + // Set/get damping ratio. + void SetDampingRatio(float32 ratio); + float32 GetDampingRatio() const; + +protected: + + friend class b2Joint; + b2DistanceJoint(const b2DistanceJointDef* data); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_localAnchor1; + b2Vec2 m_localAnchor2; + b2Vec2 m_u; + float32 m_frequencyHz; + float32 m_dampingRatio; + float32 m_gamma; + float32 m_bias; + float32 m_impulse; + float32 m_mass; + float32 m_length; +}; + +inline void b2DistanceJoint::SetLength(float32 length) +{ + m_length = length; +} + +inline float32 b2DistanceJoint::GetLength() const +{ + return m_length; +} + +inline void b2DistanceJoint::SetFrequency(float32 hz) +{ + m_frequencyHz = hz; +} + +inline float32 b2DistanceJoint::GetFrequency() const +{ + return m_frequencyHz; +} + +inline void b2DistanceJoint::SetDampingRatio(float32 ratio) +{ + m_dampingRatio = ratio; +} + +inline float32 b2DistanceJoint::GetDampingRatio() const +{ + return m_dampingRatio; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2FrictionJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2FrictionJoint.cpp new file mode 100644 index 0000000..f387dc6 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2FrictionJoint.cpp @@ -0,0 +1,229 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2FrictionJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Point-to-point constraint +// Cdot = v2 - v1 +// = v2 + cross(w2, r2) - v1 - cross(w1, r1) +// J = [-I -r1_skew I r2_skew ] +// Identity used: +// w k % (rx i + ry j) = w * (-ry i + rx j) + +// Angle constraint +// Cdot = w2 - w1 +// J = [0 0 -1 0 0 1] +// K = invI1 + invI2 + +void b2FrictionJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor) +{ + bodyA = bA; + bodyB = bB; + localAnchorA = bodyA->GetLocalPoint(anchor); + localAnchorB = bodyB->GetLocalPoint(anchor); +} + +b2FrictionJoint::b2FrictionJoint(const b2FrictionJointDef* def) +: b2Joint(def) +{ + m_localAnchorA = def->localAnchorA; + m_localAnchorB = def->localAnchorB; + + m_linearImpulse.SetZero(); + m_angularImpulse = 0.0f; + + m_maxForce = def->maxForce; + m_maxTorque = def->maxTorque; +} + +void b2FrictionJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + + // Compute the effective mass matrix. + b2Vec2 rA = b2Mul(bA->GetTransform().R, m_localAnchorA - bA->GetLocalCenter()); + b2Vec2 rB = b2Mul(bB->GetTransform().R, m_localAnchorB - bB->GetLocalCenter()); + + // J = [-I -r1_skew I r2_skew] + // [ 0 -1 0 1] + // r_skew = [-ry; rx] + + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] + // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] + + float32 mA = bA->m_invMass, mB = bB->m_invMass; + float32 iA = bA->m_invI, iB = bB->m_invI; + + b2Mat22 K1; + K1.col1.x = mA + mB; K1.col2.x = 0.0f; + K1.col1.y = 0.0f; K1.col2.y = mA + mB; + + b2Mat22 K2; + K2.col1.x = iA * rA.y * rA.y; K2.col2.x = -iA * rA.x * rA.y; + K2.col1.y = -iA * rA.x * rA.y; K2.col2.y = iA * rA.x * rA.x; + + b2Mat22 K3; + K3.col1.x = iB * rB.y * rB.y; K3.col2.x = -iB * rB.x * rB.y; + K3.col1.y = -iB * rB.x * rB.y; K3.col2.y = iB * rB.x * rB.x; + + b2Mat22 K = K1 + K2 + K3; + m_linearMass = K.GetInverse(); + + m_angularMass = iA + iB; + if (m_angularMass > 0.0f) + { + m_angularMass = 1.0f / m_angularMass; + } + + if (step.warmStarting) + { + // Scale impulses to support a variable time step. + m_linearImpulse *= step.dtRatio; + m_angularImpulse *= step.dtRatio; + + b2Vec2 P(m_linearImpulse.x, m_linearImpulse.y); + + bA->m_linearVelocity -= mA * P; + bA->m_angularVelocity -= iA * (b2Cross(rA, P) + m_angularImpulse); + + bB->m_linearVelocity += mB * P; + bB->m_angularVelocity += iB * (b2Cross(rB, P) + m_angularImpulse); + } + else + { + m_linearImpulse.SetZero(); + m_angularImpulse = 0.0f; + } +} + +void b2FrictionJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + B2_NOT_USED(step); + + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + + b2Vec2 vA = bA->m_linearVelocity; + float32 wA = bA->m_angularVelocity; + b2Vec2 vB = bB->m_linearVelocity; + float32 wB = bB->m_angularVelocity; + + float32 mA = bA->m_invMass, mB = bB->m_invMass; + float32 iA = bA->m_invI, iB = bB->m_invI; + + b2Vec2 rA = b2Mul(bA->GetTransform().R, m_localAnchorA - bA->GetLocalCenter()); + b2Vec2 rB = b2Mul(bB->GetTransform().R, m_localAnchorB - bB->GetLocalCenter()); + + // Solve angular friction + { + float32 Cdot = wB - wA; + float32 impulse = -m_angularMass * Cdot; + + float32 oldImpulse = m_angularImpulse; + float32 maxImpulse = step.dt * m_maxTorque; + m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_angularImpulse - oldImpulse; + + wA -= iA * impulse; + wB += iB * impulse; + } + + // Solve linear friction + { + b2Vec2 Cdot = vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA); + + b2Vec2 impulse = -b2Mul(m_linearMass, Cdot); + b2Vec2 oldImpulse = m_linearImpulse; + m_linearImpulse += impulse; + + float32 maxImpulse = step.dt * m_maxForce; + + if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) + { + m_linearImpulse.Normalize(); + m_linearImpulse *= maxImpulse; + } + + impulse = m_linearImpulse - oldImpulse; + + vA -= mA * impulse; + wA -= iA * b2Cross(rA, impulse); + + vB += mB * impulse; + wB += iB * b2Cross(rB, impulse); + } + + bA->m_linearVelocity = vA; + bA->m_angularVelocity = wA; + bB->m_linearVelocity = vB; + bB->m_angularVelocity = wB; +} + +bool b2FrictionJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + return true; +} + +b2Vec2 b2FrictionJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchorA); +} + +b2Vec2 b2FrictionJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchorB); +} + +b2Vec2 b2FrictionJoint::GetReactionForce(float32 inv_dt) const +{ + return inv_dt * m_linearImpulse; +} + +float32 b2FrictionJoint::GetReactionTorque(float32 inv_dt) const +{ + return inv_dt * m_angularImpulse; +} + +void b2FrictionJoint::SetMaxForce(float32 force) +{ + b2Assert(b2IsValid(force) && force >= 0.0f); + m_maxForce = force; +} + +float32 b2FrictionJoint::GetMaxForce() const +{ + return m_maxForce; +} + +void b2FrictionJoint::SetMaxTorque(float32 torque) +{ + b2Assert(b2IsValid(torque) && torque >= 0.0f); + m_maxTorque = torque; +} + +float32 b2FrictionJoint::GetMaxTorque() const +{ + return m_maxTorque; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2FrictionJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2FrictionJoint.h new file mode 100644 index 0000000..f97f99c --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2FrictionJoint.h @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_FRICTION_JOINT_H +#define B2_FRICTION_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Friction joint definition. +struct b2FrictionJointDef : public b2JointDef +{ + b2FrictionJointDef() + { + type = e_frictionJoint; + localAnchorA.SetZero(); + localAnchorB.SetZero(); + maxForce = 0.0f; + maxTorque = 0.0f; + } + + /// Initialize the bodies, anchors, axis, and reference angle using the world + /// anchor and world axis. + void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); + + /// The local anchor point relative to bodyA's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to bodyB's origin. + b2Vec2 localAnchorB; + + /// The maximum friction force in N. + float32 maxForce; + + /// The maximum friction torque in N-m. + float32 maxTorque; +}; + +/// Friction joint. This is used for top-down friction. +/// It provides 2D translational friction and angular friction. +class b2FrictionJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Set the maximum friction force in N. + void SetMaxForce(float32 force); + + /// Get the maximum friction force in N. + float32 GetMaxForce() const; + + /// Set the maximum friction torque in N*m. + void SetMaxTorque(float32 torque); + + /// Get the maximum friction torque in N*m. + float32 GetMaxTorque() const; + +protected: + + friend class b2Joint; + + b2FrictionJoint(const b2FrictionJointDef* def); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_localAnchorA; + b2Vec2 m_localAnchorB; + + b2Mat22 m_linearMass; + float32 m_angularMass; + + b2Vec2 m_linearImpulse; + float32 m_angularImpulse; + + float32 m_maxForce; + float32 m_maxTorque; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2GearJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2GearJoint.cpp new file mode 100644 index 0000000..b396247 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2GearJoint.cpp @@ -0,0 +1,259 @@ +/* +* Copyright (c) 2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2GearJoint.h" +#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" +#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Gear Joint: +// C0 = (coordinate1 + ratio * coordinate2)_initial +// C = C0 - (cordinate1 + ratio * coordinate2) = 0 +// Cdot = -(Cdot1 + ratio * Cdot2) +// J = -[J1 ratio * J2] +// K = J * invM * JT +// = J1 * invM1 * J1T + ratio * ratio * J2 * invM2 * J2T +// +// Revolute: +// coordinate = rotation +// Cdot = angularVelocity +// J = [0 0 1] +// K = J * invM * JT = invI +// +// Prismatic: +// coordinate = dot(p - pg, ug) +// Cdot = dot(v + cross(w, r), ug) +// J = [ug cross(r, ug)] +// K = J * invM * JT = invMass + invI * cross(r, ug)^2 + +b2GearJoint::b2GearJoint(const b2GearJointDef* def) +: b2Joint(def) +{ + b2JointType type1 = def->joint1->GetType(); + b2JointType type2 = def->joint2->GetType(); + + b2Assert(type1 == e_revoluteJoint || type1 == e_prismaticJoint); + b2Assert(type2 == e_revoluteJoint || type2 == e_prismaticJoint); + b2Assert(def->joint1->GetBodyA()->GetType() == b2_staticBody); + b2Assert(def->joint2->GetBodyA()->GetType() == b2_staticBody); + + m_revolute1 = NULL; + m_prismatic1 = NULL; + m_revolute2 = NULL; + m_prismatic2 = NULL; + + float32 coordinate1, coordinate2; + + m_ground1 = def->joint1->GetBodyA(); + m_bodyA = def->joint1->GetBodyB(); + if (type1 == e_revoluteJoint) + { + m_revolute1 = (b2RevoluteJoint*)def->joint1; + m_groundAnchor1 = m_revolute1->m_localAnchor1; + m_localAnchor1 = m_revolute1->m_localAnchor2; + coordinate1 = m_revolute1->GetJointAngle(); + } + else + { + m_prismatic1 = (b2PrismaticJoint*)def->joint1; + m_groundAnchor1 = m_prismatic1->m_localAnchor1; + m_localAnchor1 = m_prismatic1->m_localAnchor2; + coordinate1 = m_prismatic1->GetJointTranslation(); + } + + m_ground2 = def->joint2->GetBodyA(); + m_bodyB = def->joint2->GetBodyB(); + if (type2 == e_revoluteJoint) + { + m_revolute2 = (b2RevoluteJoint*)def->joint2; + m_groundAnchor2 = m_revolute2->m_localAnchor1; + m_localAnchor2 = m_revolute2->m_localAnchor2; + coordinate2 = m_revolute2->GetJointAngle(); + } + else + { + m_prismatic2 = (b2PrismaticJoint*)def->joint2; + m_groundAnchor2 = m_prismatic2->m_localAnchor1; + m_localAnchor2 = m_prismatic2->m_localAnchor2; + coordinate2 = m_prismatic2->GetJointTranslation(); + } + + m_ratio = def->ratio; + + m_constant = coordinate1 + m_ratio * coordinate2; + + m_impulse = 0.0f; +} + +void b2GearJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* g1 = m_ground1; + b2Body* g2 = m_ground2; + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + float32 K = 0.0f; + m_J.SetZero(); + + if (m_revolute1) + { + m_J.angularA = -1.0f; + K += b1->m_invI; + } + else + { + b2Vec2 ug = b2Mul(g1->GetTransform().R, m_prismatic1->m_localXAxis1); + b2Vec2 r = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + float32 crug = b2Cross(r, ug); + m_J.linearA = -ug; + m_J.angularA = -crug; + K += b1->m_invMass + b1->m_invI * crug * crug; + } + + if (m_revolute2) + { + m_J.angularB = -m_ratio; + K += m_ratio * m_ratio * b2->m_invI; + } + else + { + b2Vec2 ug = b2Mul(g2->GetTransform().R, m_prismatic2->m_localXAxis1); + b2Vec2 r = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + float32 crug = b2Cross(r, ug); + m_J.linearB = -m_ratio * ug; + m_J.angularB = -m_ratio * crug; + K += m_ratio * m_ratio * (b2->m_invMass + b2->m_invI * crug * crug); + } + + // Compute effective mass. + m_mass = K > 0.0f ? 1.0f / K : 0.0f; + + if (step.warmStarting) + { + // Warm starting. + b1->m_linearVelocity += b1->m_invMass * m_impulse * m_J.linearA; + b1->m_angularVelocity += b1->m_invI * m_impulse * m_J.angularA; + b2->m_linearVelocity += b2->m_invMass * m_impulse * m_J.linearB; + b2->m_angularVelocity += b2->m_invI * m_impulse * m_J.angularB; + } + else + { + m_impulse = 0.0f; + } +} + +void b2GearJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + B2_NOT_USED(step); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + float32 Cdot = m_J.Compute( b1->m_linearVelocity, b1->m_angularVelocity, + b2->m_linearVelocity, b2->m_angularVelocity); + + float32 impulse = m_mass * (-Cdot); + m_impulse += impulse; + + b1->m_linearVelocity += b1->m_invMass * impulse * m_J.linearA; + b1->m_angularVelocity += b1->m_invI * impulse * m_J.angularA; + b2->m_linearVelocity += b2->m_invMass * impulse * m_J.linearB; + b2->m_angularVelocity += b2->m_invI * impulse * m_J.angularB; +} + +bool b2GearJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + float32 linearError = 0.0f; + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + float32 coordinate1, coordinate2; + if (m_revolute1) + { + coordinate1 = m_revolute1->GetJointAngle(); + } + else + { + coordinate1 = m_prismatic1->GetJointTranslation(); + } + + if (m_revolute2) + { + coordinate2 = m_revolute2->GetJointAngle(); + } + else + { + coordinate2 = m_prismatic2->GetJointTranslation(); + } + + float32 C = m_constant - (coordinate1 + m_ratio * coordinate2); + + float32 impulse = m_mass * (-C); + + b1->m_sweep.c += b1->m_invMass * impulse * m_J.linearA; + b1->m_sweep.a += b1->m_invI * impulse * m_J.angularA; + b2->m_sweep.c += b2->m_invMass * impulse * m_J.linearB; + b2->m_sweep.a += b2->m_invI * impulse * m_J.angularB; + + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + + // TODO_ERIN not implemented + return linearError < b2_linearSlop; +} + +b2Vec2 b2GearJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchor1); +} + +b2Vec2 b2GearJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor2); +} + +b2Vec2 b2GearJoint::GetReactionForce(float32 inv_dt) const +{ + // TODO_ERIN not tested + b2Vec2 P = m_impulse * m_J.linearB; + return inv_dt * P; +} + +float32 b2GearJoint::GetReactionTorque(float32 inv_dt) const +{ + // TODO_ERIN not tested + b2Vec2 r = b2Mul(m_bodyB->GetTransform().R, m_localAnchor2 - m_bodyB->GetLocalCenter()); + b2Vec2 P = m_impulse * m_J.linearB; + float32 L = m_impulse * m_J.angularB - b2Cross(r, P); + return inv_dt * L; +} + +void b2GearJoint::SetRatio(float32 ratio) +{ + b2Assert(b2IsValid(ratio)); + m_ratio = ratio; +} + +float32 b2GearJoint::GetRatio() const +{ + return m_ratio; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2GearJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2GearJoint.h new file mode 100644 index 0000000..4978088 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2GearJoint.h @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_GEAR_JOINT_H +#define B2_GEAR_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +class b2RevoluteJoint; +class b2PrismaticJoint; + +/// Gear joint definition. This definition requires two existing +/// revolute or prismatic joints (any combination will work). +/// The provided joints must attach a dynamic body to a static body. +struct b2GearJointDef : public b2JointDef +{ + b2GearJointDef() + { + type = e_gearJoint; + joint1 = NULL; + joint2 = NULL; + ratio = 1.0f; + } + + /// The first revolute/prismatic joint attached to the gear joint. + b2Joint* joint1; + + /// The second revolute/prismatic joint attached to the gear joint. + b2Joint* joint2; + + /// The gear ratio. + /// @see b2GearJoint for explanation. + float32 ratio; +}; + +/// A gear joint is used to connect two joints together. Either joint +/// can be a revolute or prismatic joint. You specify a gear ratio +/// to bind the motions together: +/// coordinate1 + ratio * coordinate2 = constant +/// The ratio can be negative or positive. If one joint is a revolute joint +/// and the other joint is a prismatic joint, then the ratio will have units +/// of length or units of 1/length. +/// @warning The revolute and prismatic joints must be attached to +/// fixed bodies (which must be body1 on those joints). +class b2GearJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Set/Get the gear ratio. + void SetRatio(float32 ratio); + float32 GetRatio() const; + +protected: + + friend class b2Joint; + b2GearJoint(const b2GearJointDef* data); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte); + + b2Body* m_ground1; + b2Body* m_ground2; + + // One of these is NULL. + b2RevoluteJoint* m_revolute1; + b2PrismaticJoint* m_prismatic1; + + // One of these is NULL. + b2RevoluteJoint* m_revolute2; + b2PrismaticJoint* m_prismatic2; + + b2Vec2 m_groundAnchor1; + b2Vec2 m_groundAnchor2; + + b2Vec2 m_localAnchor1; + b2Vec2 m_localAnchor2; + + b2Jacobian m_J; + + float32 m_constant; + float32 m_ratio; + + // Effective mass + float32 m_mass; + + // Impulse for accumulation/warm starting. + float32 m_impulse; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2Joint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2Joint.cpp new file mode 100644 index 0000000..2429667 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2Joint.cpp @@ -0,0 +1,186 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2Joint.h" +#include "Box2D/Dynamics/Joints/b2DistanceJoint.h" +#include "Box2D/Dynamics/Joints/b2LineJoint.h" +#include "Box2D/Dynamics/Joints/b2MouseJoint.h" +#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" +#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" +#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" +#include "Box2D/Dynamics/Joints/b2GearJoint.h" +#include "Box2D/Dynamics/Joints/b2WeldJoint.h" +#include "Box2D/Dynamics/Joints/b2FrictionJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2World.h" +#include "Box2D/Common/b2BlockAllocator.h" + +#include + +b2Joint* b2Joint::Create(const b2JointDef* def, b2BlockAllocator* allocator) +{ + b2Joint* joint = NULL; + + switch (def->type) + { + case e_distanceJoint: + { + void* mem = allocator->Allocate(sizeof(b2DistanceJoint)); + joint = new (mem) b2DistanceJoint((b2DistanceJointDef*)def); + } + break; + + case e_mouseJoint: + { + void* mem = allocator->Allocate(sizeof(b2MouseJoint)); + joint = new (mem) b2MouseJoint((b2MouseJointDef*)def); + } + break; + + case e_prismaticJoint: + { + void* mem = allocator->Allocate(sizeof(b2PrismaticJoint)); + joint = new (mem) b2PrismaticJoint((b2PrismaticJointDef*)def); + } + break; + + case e_revoluteJoint: + { + void* mem = allocator->Allocate(sizeof(b2RevoluteJoint)); + joint = new (mem) b2RevoluteJoint((b2RevoluteJointDef*)def); + } + break; + + case e_pulleyJoint: + { + void* mem = allocator->Allocate(sizeof(b2PulleyJoint)); + joint = new (mem) b2PulleyJoint((b2PulleyJointDef*)def); + } + break; + + case e_gearJoint: + { + void* mem = allocator->Allocate(sizeof(b2GearJoint)); + joint = new (mem) b2GearJoint((b2GearJointDef*)def); + } + break; + + case e_lineJoint: + { + void* mem = allocator->Allocate(sizeof(b2LineJoint)); + joint = new (mem) b2LineJoint((b2LineJointDef*)def); + } + break; + + case e_weldJoint: + { + void* mem = allocator->Allocate(sizeof(b2WeldJoint)); + joint = new (mem) b2WeldJoint((b2WeldJointDef*)def); + } + break; + + case e_frictionJoint: + { + void* mem = allocator->Allocate(sizeof(b2FrictionJoint)); + joint = new (mem) b2FrictionJoint((b2FrictionJointDef*)def); + } + break; + + default: + b2Assert(false); + break; + } + + return joint; +} + +void b2Joint::Destroy(b2Joint* joint, b2BlockAllocator* allocator) +{ + joint->~b2Joint(); + switch (joint->m_type) + { + case e_distanceJoint: + allocator->Free(joint, sizeof(b2DistanceJoint)); + break; + + case e_mouseJoint: + allocator->Free(joint, sizeof(b2MouseJoint)); + break; + + case e_prismaticJoint: + allocator->Free(joint, sizeof(b2PrismaticJoint)); + break; + + case e_revoluteJoint: + allocator->Free(joint, sizeof(b2RevoluteJoint)); + break; + + case e_pulleyJoint: + allocator->Free(joint, sizeof(b2PulleyJoint)); + break; + + case e_gearJoint: + allocator->Free(joint, sizeof(b2GearJoint)); + break; + + case e_lineJoint: + allocator->Free(joint, sizeof(b2LineJoint)); + break; + + case e_weldJoint: + allocator->Free(joint, sizeof(b2WeldJoint)); + break; + + case e_frictionJoint: + allocator->Free(joint, sizeof(b2FrictionJoint)); + break; + + default: + b2Assert(false); + break; + } +} + +b2Joint::b2Joint(const b2JointDef* def) +{ + b2Assert(def->bodyA != def->bodyB); + + m_type = def->type; + m_prev = NULL; + m_next = NULL; + m_bodyA = def->bodyA; + m_bodyB = def->bodyB; + m_collideConnected = def->collideConnected; + m_islandFlag = false; + m_userData = def->userData; + + m_edgeA.joint = NULL; + m_edgeA.other = NULL; + m_edgeA.prev = NULL; + m_edgeA.next = NULL; + + m_edgeB.joint = NULL; + m_edgeB.other = NULL; + m_edgeB.prev = NULL; + m_edgeB.next = NULL; +} + +bool b2Joint::IsActive() const +{ + return m_bodyA->IsActive() && m_bodyB->IsActive(); +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2Joint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2Joint.h new file mode 100644 index 0000000..eb8d075 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2Joint.h @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_JOINT_H +#define B2_JOINT_H + +#include "Box2D/Common/b2Math.h" + +class b2Body; +class b2Joint; +struct b2TimeStep; +class b2BlockAllocator; + +enum b2JointType +{ + e_unknownJoint, + e_revoluteJoint, + e_prismaticJoint, + e_distanceJoint, + e_pulleyJoint, + e_mouseJoint, + e_gearJoint, + e_lineJoint, + e_weldJoint, + e_frictionJoint, +}; + +enum b2LimitState +{ + e_inactiveLimit, + e_atLowerLimit, + e_atUpperLimit, + e_equalLimits +}; + +struct b2Jacobian +{ + b2Vec2 linearA; + float32 angularA; + b2Vec2 linearB; + float32 angularB; + + void SetZero(); + void Set(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2); + float32 Compute(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2); +}; + +/// A joint edge is used to connect bodies and joints together +/// in a joint graph where each body is a node and each joint +/// is an edge. A joint edge belongs to a doubly linked list +/// maintained in each attached body. Each joint has two joint +/// nodes, one for each attached body. +struct b2JointEdge +{ + b2Body* other; ///< provides quick access to the other body attached. + b2Joint* joint; ///< the joint + b2JointEdge* prev; ///< the previous joint edge in the body's joint list + b2JointEdge* next; ///< the next joint edge in the body's joint list +}; + +/// Joint definitions are used to construct joints. +struct b2JointDef +{ + b2JointDef() + { + type = e_unknownJoint; + userData = NULL; + bodyA = NULL; + bodyB = NULL; + collideConnected = false; + } + + /// The joint type is set automatically for concrete joint types. + b2JointType type; + + /// Use this to attach application specific data to your joints. + void* userData; + + /// The first attached body. + b2Body* bodyA; + + /// The second attached body. + b2Body* bodyB; + + /// Set this flag to true if the attached bodies should collide. + bool collideConnected; +}; + +/// The base joint class. Joints are used to constraint two bodies together in +/// various fashions. Some joints also feature limits and motors. +class b2Joint +{ +public: + + /// Get the type of the concrete joint. + b2JointType GetType() const; + + /// Get the first body attached to this joint. + b2Body* GetBodyA(); + + /// Get the second body attached to this joint. + b2Body* GetBodyB(); + + /// Get the anchor point on bodyA in world coordinates. + virtual b2Vec2 GetAnchorA() const = 0; + + /// Get the anchor point on bodyB in world coordinates. + virtual b2Vec2 GetAnchorB() const = 0; + + /// Get the reaction force on body2 at the joint anchor in Newtons. + virtual b2Vec2 GetReactionForce(float32 inv_dt) const = 0; + + /// Get the reaction torque on body2 in N*m. + virtual float32 GetReactionTorque(float32 inv_dt) const = 0; + + /// Get the next joint the world joint list. + b2Joint* GetNext(); + + /// Get the user data pointer. + void* GetUserData() const; + + /// Set the user data pointer. + void SetUserData(void* data); + + /// Short-cut function to determine if either body is inactive. + bool IsActive() const; + +protected: + friend class b2World; + friend class b2Body; + friend class b2Island; + + static b2Joint* Create(const b2JointDef* def, b2BlockAllocator* allocator); + static void Destroy(b2Joint* joint, b2BlockAllocator* allocator); + + b2Joint(const b2JointDef* def); + virtual ~b2Joint() {} + + virtual void InitVelocityConstraints(const b2TimeStep& step) = 0; + virtual void SolveVelocityConstraints(const b2TimeStep& step) = 0; + + // This returns true if the position errors are within tolerance. + virtual bool SolvePositionConstraints(float32 baumgarte) = 0; + + b2JointType m_type; + b2Joint* m_prev; + b2Joint* m_next; + b2JointEdge m_edgeA; + b2JointEdge m_edgeB; + b2Body* m_bodyA; + b2Body* m_bodyB; + + bool m_islandFlag; + bool m_collideConnected; + + void* m_userData; + + // Cache here per time step to reduce cache misses. + b2Vec2 m_localCenterA, m_localCenterB; + float32 m_invMassA, m_invIA; + float32 m_invMassB, m_invIB; +}; + +inline void b2Jacobian::SetZero() +{ + linearA.SetZero(); angularA = 0.0f; + linearB.SetZero(); angularB = 0.0f; +} + +inline void b2Jacobian::Set(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2) +{ + linearA = x1; angularA = a1; + linearB = x2; angularB = a2; +} + +inline float32 b2Jacobian::Compute(const b2Vec2& x1, float32 a1, const b2Vec2& x2, float32 a2) +{ + return b2Dot(linearA, x1) + angularA * a1 + b2Dot(linearB, x2) + angularB * a2; +} + +inline b2JointType b2Joint::GetType() const +{ + return m_type; +} + +inline b2Body* b2Joint::GetBodyA() +{ + return m_bodyA; +} + +inline b2Body* b2Joint::GetBodyB() +{ + return m_bodyB; +} + +inline b2Joint* b2Joint::GetNext() +{ + return m_next; +} + +inline void* b2Joint::GetUserData() const +{ + return m_userData; +} + +inline void b2Joint::SetUserData(void* data) +{ + m_userData = data; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2LineJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2LineJoint.cpp new file mode 100644 index 0000000..ed39fce --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2LineJoint.cpp @@ -0,0 +1,591 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2LineJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Linear constraint (point-to-line) +// d = p2 - p1 = x2 + r2 - x1 - r1 +// C = dot(perp, d) +// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1)) +// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2) +// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)] +// +// K = J * invM * JT +// +// J = [-a -s1 a s2] +// a = perp +// s1 = cross(d + r1, a) = cross(p2 - x1, a) +// s2 = cross(r2, a) = cross(p2 - x2, a) + + +// Motor/Limit linear constraint +// C = dot(ax1, d) +// Cdot = = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2) +// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)] + +// Block Solver +// We develop a block solver that includes the joint limit. This makes the limit stiff (inelastic) even +// when the mass has poor distribution (leading to large torques about the joint anchor points). +// +// The Jacobian has 3 rows: +// J = [-uT -s1 uT s2] // linear +// [-vT -a1 vT a2] // limit +// +// u = perp +// v = axis +// s1 = cross(d + r1, u), s2 = cross(r2, u) +// a1 = cross(d + r1, v), a2 = cross(r2, v) + +// M * (v2 - v1) = JT * df +// J * v2 = bias +// +// v2 = v1 + invM * JT * df +// J * (v1 + invM * JT * df) = bias +// K * df = bias - J * v1 = -Cdot +// K = J * invM * JT +// Cdot = J * v1 - bias +// +// Now solve for f2. +// df = f2 - f1 +// K * (f2 - f1) = -Cdot +// f2 = invK * (-Cdot) + f1 +// +// Clamp accumulated limit impulse. +// lower: f2(2) = max(f2(2), 0) +// upper: f2(2) = min(f2(2), 0) +// +// Solve for correct f2(1) +// K(1,1) * f2(1) = -Cdot(1) - K(1,2) * f2(2) + K(1,1:2) * f1 +// = -Cdot(1) - K(1,2) * f2(2) + K(1,1) * f1(1) + K(1,2) * f1(2) +// K(1,1) * f2(1) = -Cdot(1) - K(1,2) * (f2(2) - f1(2)) + K(1,1) * f1(1) +// f2(1) = invK(1,1) * (-Cdot(1) - K(1,2) * (f2(2) - f1(2))) + f1(1) +// +// Now compute impulse to be applied: +// df = f2 - f1 + +void b2LineJointDef::Initialize(b2Body* b1, b2Body* b2, const b2Vec2& anchor, const b2Vec2& axis) +{ + bodyA = b1; + bodyB = b2; + localAnchorA = bodyA->GetLocalPoint(anchor); + localAnchorB = bodyB->GetLocalPoint(anchor); + localAxisA = bodyA->GetLocalVector(axis); +} + +b2LineJoint::b2LineJoint(const b2LineJointDef* def) +: b2Joint(def) +{ + m_localAnchor1 = def->localAnchorA; + m_localAnchor2 = def->localAnchorB; + m_localXAxis1 = def->localAxisA; + m_localYAxis1 = b2Cross(1.0f, m_localXAxis1); + + m_impulse.SetZero(); + m_motorMass = 0.0; + m_motorImpulse = 0.0f; + + m_lowerTranslation = def->lowerTranslation; + m_upperTranslation = def->upperTranslation; + m_maxMotorForce = def->maxMotorForce; + m_motorSpeed = def->motorSpeed; + m_enableLimit = def->enableLimit; + m_enableMotor = def->enableMotor; + m_limitState = e_inactiveLimit; + + m_axis.SetZero(); + m_perp.SetZero(); +} + +void b2LineJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + m_localCenterA = b1->GetLocalCenter(); + m_localCenterB = b2->GetLocalCenter(); + + b2Transform xf1 = b1->GetTransform(); + b2Transform xf2 = b2->GetTransform(); + + // Compute the effective masses. + b2Vec2 r1 = b2Mul(xf1.R, m_localAnchor1 - m_localCenterA); + b2Vec2 r2 = b2Mul(xf2.R, m_localAnchor2 - m_localCenterB); + b2Vec2 d = b2->m_sweep.c + r2 - b1->m_sweep.c - r1; + + m_invMassA = b1->m_invMass; + m_invIA = b1->m_invI; + m_invMassB = b2->m_invMass; + m_invIB = b2->m_invI; + + // Compute motor Jacobian and effective mass. + { + m_axis = b2Mul(xf1.R, m_localXAxis1); + m_a1 = b2Cross(d + r1, m_axis); + m_a2 = b2Cross(r2, m_axis); + + m_motorMass = m_invMassA + m_invMassB + m_invIA * m_a1 * m_a1 + m_invIB * m_a2 * m_a2; + if (m_motorMass > b2_epsilon) + { + m_motorMass = 1.0f / m_motorMass; + } + else + { + m_motorMass = 0.0f; + } + } + + // Prismatic constraint. + { + m_perp = b2Mul(xf1.R, m_localYAxis1); + + m_s1 = b2Cross(d + r1, m_perp); + m_s2 = b2Cross(r2, m_perp); + + float32 m1 = m_invMassA, m2 = m_invMassB; + float32 i1 = m_invIA, i2 = m_invIB; + + float32 k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2; + float32 k12 = i1 * m_s1 * m_a1 + i2 * m_s2 * m_a2; + float32 k22 = m1 + m2 + i1 * m_a1 * m_a1 + i2 * m_a2 * m_a2; + + m_K.col1.Set(k11, k12); + m_K.col2.Set(k12, k22); + } + + // Compute motor and limit terms. + if (m_enableLimit) + { + float32 jointTranslation = b2Dot(m_axis, d); + if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) + { + m_limitState = e_equalLimits; + } + else if (jointTranslation <= m_lowerTranslation) + { + if (m_limitState != e_atLowerLimit) + { + m_limitState = e_atLowerLimit; + m_impulse.y = 0.0f; + } + } + else if (jointTranslation >= m_upperTranslation) + { + if (m_limitState != e_atUpperLimit) + { + m_limitState = e_atUpperLimit; + m_impulse.y = 0.0f; + } + } + else + { + m_limitState = e_inactiveLimit; + m_impulse.y = 0.0f; + } + } + else + { + m_limitState = e_inactiveLimit; + } + + if (m_enableMotor == false) + { + m_motorImpulse = 0.0f; + } + + if (step.warmStarting) + { + // Account for variable time step. + m_impulse *= step.dtRatio; + m_motorImpulse *= step.dtRatio; + + b2Vec2 P = m_impulse.x * m_perp + (m_motorImpulse + m_impulse.y) * m_axis; + float32 L1 = m_impulse.x * m_s1 + (m_motorImpulse + m_impulse.y) * m_a1; + float32 L2 = m_impulse.x * m_s2 + (m_motorImpulse + m_impulse.y) * m_a2; + + b1->m_linearVelocity -= m_invMassA * P; + b1->m_angularVelocity -= m_invIA * L1; + + b2->m_linearVelocity += m_invMassB * P; + b2->m_angularVelocity += m_invIB * L2; + } + else + { + m_impulse.SetZero(); + m_motorImpulse = 0.0f; + } +} + +void b2LineJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 v1 = b1->m_linearVelocity; + float32 w1 = b1->m_angularVelocity; + b2Vec2 v2 = b2->m_linearVelocity; + float32 w2 = b2->m_angularVelocity; + + // Solve linear motor constraint. + if (m_enableMotor && m_limitState != e_equalLimits) + { + float32 Cdot = b2Dot(m_axis, v2 - v1) + m_a2 * w2 - m_a1 * w1; + float32 impulse = m_motorMass * (m_motorSpeed - Cdot); + float32 oldImpulse = m_motorImpulse; + float32 maxImpulse = step.dt * m_maxMotorForce; + m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_motorImpulse - oldImpulse; + + b2Vec2 P = impulse * m_axis; + float32 L1 = impulse * m_a1; + float32 L2 = impulse * m_a2; + + v1 -= m_invMassA * P; + w1 -= m_invIA * L1; + + v2 += m_invMassB * P; + w2 += m_invIB * L2; + } + + float32 Cdot1 = b2Dot(m_perp, v2 - v1) + m_s2 * w2 - m_s1 * w1; + + if (m_enableLimit && m_limitState != e_inactiveLimit) + { + // Solve prismatic and limit constraint in block form. + float32 Cdot2 = b2Dot(m_axis, v2 - v1) + m_a2 * w2 - m_a1 * w1; + b2Vec2 Cdot(Cdot1, Cdot2); + + b2Vec2 f1 = m_impulse; + b2Vec2 df = m_K.Solve(-Cdot); + m_impulse += df; + + if (m_limitState == e_atLowerLimit) + { + m_impulse.y = b2Max(m_impulse.y, 0.0f); + } + else if (m_limitState == e_atUpperLimit) + { + m_impulse.y = b2Min(m_impulse.y, 0.0f); + } + + // f2(1) = invK(1,1) * (-Cdot(1) - K(1,2) * (f2(2) - f1(2))) + f1(1) + float32 b = -Cdot1 - (m_impulse.y - f1.y) * m_K.col2.x; + float32 f2r; + if (m_K.col1.x != 0.0f) + { + f2r = b / m_K.col1.x + f1.x; + } + else + { + f2r = f1.x; + } + + m_impulse.x = f2r; + + df = m_impulse - f1; + + b2Vec2 P = df.x * m_perp + df.y * m_axis; + float32 L1 = df.x * m_s1 + df.y * m_a1; + float32 L2 = df.x * m_s2 + df.y * m_a2; + + v1 -= m_invMassA * P; + w1 -= m_invIA * L1; + + v2 += m_invMassB * P; + w2 += m_invIB * L2; + } + else + { + // Limit is inactive, just solve the prismatic constraint in block form. + float32 df; + if (m_K.col1.x != 0.0f) + { + df = - Cdot1 / m_K.col1.x; + } + else + { + df = 0.0f; + } + m_impulse.x += df; + + b2Vec2 P = df * m_perp; + float32 L1 = df * m_s1; + float32 L2 = df * m_s2; + + v1 -= m_invMassA * P; + w1 -= m_invIA * L1; + + v2 += m_invMassB * P; + w2 += m_invIB * L2; + } + + b1->m_linearVelocity = v1; + b1->m_angularVelocity = w1; + b2->m_linearVelocity = v2; + b2->m_angularVelocity = w2; +} + +bool b2LineJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 c1 = b1->m_sweep.c; + float32 a1 = b1->m_sweep.a; + + b2Vec2 c2 = b2->m_sweep.c; + float32 a2 = b2->m_sweep.a; + + // Solve linear limit constraint. + float32 linearError = 0.0f, angularError = 0.0f; + bool active = false; + float32 C2 = 0.0f; + + b2Mat22 R1(a1), R2(a2); + + b2Vec2 r1 = b2Mul(R1, m_localAnchor1 - m_localCenterA); + b2Vec2 r2 = b2Mul(R2, m_localAnchor2 - m_localCenterB); + b2Vec2 d = c2 + r2 - c1 - r1; + + if (m_enableLimit) + { + m_axis = b2Mul(R1, m_localXAxis1); + + m_a1 = b2Cross(d + r1, m_axis); + m_a2 = b2Cross(r2, m_axis); + + float32 translation = b2Dot(m_axis, d); + if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) + { + // Prevent large angular corrections + C2 = b2Clamp(translation, -b2_maxLinearCorrection, b2_maxLinearCorrection); + linearError = b2Abs(translation); + active = true; + } + else if (translation <= m_lowerTranslation) + { + // Prevent large linear corrections and allow some slop. + C2 = b2Clamp(translation - m_lowerTranslation + b2_linearSlop, -b2_maxLinearCorrection, 0.0f); + linearError = m_lowerTranslation - translation; + active = true; + } + else if (translation >= m_upperTranslation) + { + // Prevent large linear corrections and allow some slop. + C2 = b2Clamp(translation - m_upperTranslation - b2_linearSlop, 0.0f, b2_maxLinearCorrection); + linearError = translation - m_upperTranslation; + active = true; + } + } + + m_perp = b2Mul(R1, m_localYAxis1); + + m_s1 = b2Cross(d + r1, m_perp); + m_s2 = b2Cross(r2, m_perp); + + b2Vec2 impulse; + float32 C1; + C1 = b2Dot(m_perp, d); + + linearError = b2Max(linearError, b2Abs(C1)); + angularError = 0.0f; + + if (active) + { + float32 m1 = m_invMassA, m2 = m_invMassB; + float32 i1 = m_invIA, i2 = m_invIB; + + float32 k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2; + float32 k12 = i1 * m_s1 * m_a1 + i2 * m_s2 * m_a2; + float32 k22 = m1 + m2 + i1 * m_a1 * m_a1 + i2 * m_a2 * m_a2; + + m_K.col1.Set(k11, k12); + m_K.col2.Set(k12, k22); + + b2Vec2 C; + C.x = C1; + C.y = C2; + + impulse = m_K.Solve(-C); + } + else + { + float32 m1 = m_invMassA, m2 = m_invMassB; + float32 i1 = m_invIA, i2 = m_invIB; + + float32 k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2; + + float32 impulse1; + if (k11 != 0.0f) + { + impulse1 = - C1 / k11; + } + else + { + impulse1 = 0.0f; + } + + impulse.x = impulse1; + impulse.y = 0.0f; + } + + b2Vec2 P = impulse.x * m_perp + impulse.y * m_axis; + float32 L1 = impulse.x * m_s1 + impulse.y * m_a1; + float32 L2 = impulse.x * m_s2 + impulse.y * m_a2; + + c1 -= m_invMassA * P; + a1 -= m_invIA * L1; + c2 += m_invMassB * P; + a2 += m_invIB * L2; + + // TODO_ERIN remove need for this. + b1->m_sweep.c = c1; + b1->m_sweep.a = a1; + b2->m_sweep.c = c2; + b2->m_sweep.a = a2; + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + + return linearError <= b2_linearSlop && angularError <= b2_angularSlop; +} + +b2Vec2 b2LineJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchor1); +} + +b2Vec2 b2LineJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor2); +} + +b2Vec2 b2LineJoint::GetReactionForce(float32 inv_dt) const +{ + return inv_dt * (m_impulse.x * m_perp + (m_motorImpulse + m_impulse.y) * m_axis); +} + +float32 b2LineJoint::GetReactionTorque(float32 inv_dt) const +{ + B2_NOT_USED(inv_dt); + return 0.0f; +} + +float32 b2LineJoint::GetJointTranslation() const +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 p1 = b1->GetWorldPoint(m_localAnchor1); + b2Vec2 p2 = b2->GetWorldPoint(m_localAnchor2); + b2Vec2 d = p2 - p1; + b2Vec2 axis = b1->GetWorldVector(m_localXAxis1); + + float32 translation = b2Dot(d, axis); + return translation; +} + +float32 b2LineJoint::GetJointSpeed() const +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + b2Vec2 p1 = b1->m_sweep.c + r1; + b2Vec2 p2 = b2->m_sweep.c + r2; + b2Vec2 d = p2 - p1; + b2Vec2 axis = b1->GetWorldVector(m_localXAxis1); + + b2Vec2 v1 = b1->m_linearVelocity; + b2Vec2 v2 = b2->m_linearVelocity; + float32 w1 = b1->m_angularVelocity; + float32 w2 = b2->m_angularVelocity; + + float32 speed = b2Dot(d, b2Cross(w1, axis)) + b2Dot(axis, v2 + b2Cross(w2, r2) - v1 - b2Cross(w1, r1)); + return speed; +} + +bool b2LineJoint::IsLimitEnabled() const +{ + return m_enableLimit; +} + +void b2LineJoint::EnableLimit(bool flag) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableLimit = flag; +} + +float32 b2LineJoint::GetLowerLimit() const +{ + return m_lowerTranslation; +} + +float32 b2LineJoint::GetUpperLimit() const +{ + return m_upperTranslation; +} + +void b2LineJoint::SetLimits(float32 lower, float32 upper) +{ + b2Assert(lower <= upper); + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_lowerTranslation = lower; + m_upperTranslation = upper; +} + +bool b2LineJoint::IsMotorEnabled() const +{ + return m_enableMotor; +} + +void b2LineJoint::EnableMotor(bool flag) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableMotor = flag; +} + +void b2LineJoint::SetMotorSpeed(float32 speed) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_motorSpeed = speed; +} + +void b2LineJoint::SetMaxMotorForce(float32 force) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_maxMotorForce = force; +} + +float32 b2LineJoint::GetMotorForce() const +{ + return m_motorImpulse; +} + + + + + diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2LineJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2LineJoint.h new file mode 100644 index 0000000..b44892a --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2LineJoint.h @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_LINE_JOINT_H +#define B2_LINE_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Line joint definition. This requires defining a line of +/// motion using an axis and an anchor point. The definition uses local +/// anchor points and a local axis so that the initial configuration +/// can violate the constraint slightly. The joint translation is zero +/// when the local anchor points coincide in world space. Using local +/// anchors and a local axis helps when saving and loading a game. +struct b2LineJointDef : public b2JointDef +{ + b2LineJointDef() + { + type = e_lineJoint; + localAnchorA.SetZero(); + localAnchorB.SetZero(); + localAxisA.Set(1.0f, 0.0f); + enableLimit = false; + lowerTranslation = 0.0f; + upperTranslation = 0.0f; + enableMotor = false; + maxMotorForce = 0.0f; + motorSpeed = 0.0f; + } + + /// Initialize the bodies, anchors, axis, and reference angle using the world + /// anchor and world axis. + void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis); + + /// The local anchor point relative to body1's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to body2's origin. + b2Vec2 localAnchorB; + + /// The local translation axis in body1. + b2Vec2 localAxisA; + + /// Enable/disable the joint limit. + bool enableLimit; + + /// The lower translation limit, usually in meters. + float32 lowerTranslation; + + /// The upper translation limit, usually in meters. + float32 upperTranslation; + + /// Enable/disable the joint motor. + bool enableMotor; + + /// The maximum motor torque, usually in N-m. + float32 maxMotorForce; + + /// The desired motor speed in radians per second. + float32 motorSpeed; +}; + +/// A line joint. This joint provides two degrees of freedom: translation +/// along an axis fixed in body1 and rotation in the plane. You can use a +/// joint limit to restrict the range of motion and a joint motor to drive +/// the motion or to model joint friction. +class b2LineJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Get the current joint translation, usually in meters. + float32 GetJointTranslation() const; + + /// Get the current joint translation speed, usually in meters per second. + float32 GetJointSpeed() const; + + /// Is the joint limit enabled? + bool IsLimitEnabled() const; + + /// Enable/disable the joint limit. + void EnableLimit(bool flag); + + /// Get the lower joint limit, usually in meters. + float32 GetLowerLimit() const; + + /// Get the upper joint limit, usually in meters. + float32 GetUpperLimit() const; + + /// Set the joint limits, usually in meters. + void SetLimits(float32 lower, float32 upper); + + /// Is the joint motor enabled? + bool IsMotorEnabled() const; + + /// Enable/disable the joint motor. + void EnableMotor(bool flag); + + /// Set the motor speed, usually in meters per second. + void SetMotorSpeed(float32 speed); + + /// Get the motor speed, usually in meters per second. + float32 GetMotorSpeed() const; + + /// Set/Get the maximum motor force, usually in N. + void SetMaxMotorForce(float32 force); + float32 GetMaxMotorForce() const; + + /// Get the current motor force, usually in N. + float32 GetMotorForce() const; + +protected: + + friend class b2Joint; + b2LineJoint(const b2LineJointDef* def); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_localAnchor1; + b2Vec2 m_localAnchor2; + b2Vec2 m_localXAxis1; + b2Vec2 m_localYAxis1; + + b2Vec2 m_axis, m_perp; + float32 m_s1, m_s2; + float32 m_a1, m_a2; + + b2Mat22 m_K; + b2Vec2 m_impulse; + + float32 m_motorMass; // effective mass for motor/limit translational constraint. + float32 m_motorImpulse; + + float32 m_lowerTranslation; + float32 m_upperTranslation; + float32 m_maxMotorForce; + float32 m_motorSpeed; + + bool m_enableLimit; + bool m_enableMotor; + b2LimitState m_limitState; +}; + +inline float32 b2LineJoint::GetMotorSpeed() const +{ + return m_motorSpeed; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2MouseJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2MouseJoint.cpp new file mode 100644 index 0000000..519e786 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2MouseJoint.cpp @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2MouseJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" +#include + +// p = attached point, m = mouse point +// C = p - m +// Cdot = v +// = v + cross(w, r) +// J = [I r_skew] +// Identity used: +// w k % (rx i + ry j) = w * (-ry i + rx j) + +b2MouseJoint::b2MouseJoint(const b2MouseJointDef* def) +: b2Joint(def) +{ + b2Assert(def->target.IsValid()); + b2Assert(b2IsValid(def->maxForce) && def->maxForce >= 0.0f); + b2Assert(b2IsValid(def->frequencyHz) && def->frequencyHz >= 0.0f); + b2Assert(b2IsValid(def->dampingRatio) && def->dampingRatio >= 0.0f); + + m_target = def->target; + m_localAnchor = b2MulT(m_bodyB->GetTransform(), m_target); + + m_maxForce = def->maxForce; + m_impulse.SetZero(); + + m_frequencyHz = def->frequencyHz; + m_dampingRatio = def->dampingRatio; + + m_beta = 0.0f; + m_gamma = 0.0f; +} + +void b2MouseJoint::SetTarget(const b2Vec2& target) +{ + if (m_bodyB->IsAwake() == false) + { + m_bodyB->SetAwake(true); + } + m_target = target; +} + +const b2Vec2& b2MouseJoint::GetTarget() const +{ + return m_target; +} + +void b2MouseJoint::SetMaxForce(float32 force) +{ + m_maxForce = force; +} + +float32 b2MouseJoint::GetMaxForce() const +{ + return m_maxForce; +} + +void b2MouseJoint::SetFrequency(float32 hz) +{ + m_frequencyHz = hz; +} + +float32 b2MouseJoint::GetFrequency() const +{ + return m_frequencyHz; +} + +void b2MouseJoint::SetDampingRatio(float32 ratio) +{ + m_dampingRatio = ratio; +} + +float32 b2MouseJoint::GetDampingRatio() const +{ + return m_dampingRatio; +} + +void b2MouseJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b = m_bodyB; + + float32 mass = b->GetMass(); + + // Frequency + float32 omega = 2.0f * b2_pi * m_frequencyHz; + + // Damping coefficient + float32 d = 2.0f * mass * m_dampingRatio * omega; + + // Spring stiffness + float32 k = mass * (omega * omega); + + // magic formulas + // gamma has units of inverse mass. + // beta has units of inverse time. + b2Assert(d + step.dt * k > b2_epsilon); + m_gamma = step.dt * (d + step.dt * k); + if (m_gamma != 0.0f) + { + m_gamma = 1.0f / m_gamma; + } + m_beta = step.dt * k * m_gamma; + + // Compute the effective mass matrix. + b2Vec2 r = b2Mul(b->GetTransform().R, m_localAnchor - b->GetLocalCenter()); + + // K = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)] + // = [1/m1+1/m2 0 ] + invI1 * [r1.y*r1.y -r1.x*r1.y] + invI2 * [r1.y*r1.y -r1.x*r1.y] + // [ 0 1/m1+1/m2] [-r1.x*r1.y r1.x*r1.x] [-r1.x*r1.y r1.x*r1.x] + float32 invMass = b->m_invMass; + float32 invI = b->m_invI; + + b2Mat22 K1; + K1.col1.x = invMass; K1.col2.x = 0.0f; + K1.col1.y = 0.0f; K1.col2.y = invMass; + + b2Mat22 K2; + K2.col1.x = invI * r.y * r.y; K2.col2.x = -invI * r.x * r.y; + K2.col1.y = -invI * r.x * r.y; K2.col2.y = invI * r.x * r.x; + + b2Mat22 K = K1 + K2; + K.col1.x += m_gamma; + K.col2.y += m_gamma; + + m_mass = K.GetInverse(); + + m_C = b->m_sweep.c + r - m_target; + + // Cheat with some damping + b->m_angularVelocity *= 0.98f; + + // Warm starting. + m_impulse *= step.dtRatio; + b->m_linearVelocity += invMass * m_impulse; + b->m_angularVelocity += invI * b2Cross(r, m_impulse); +} + +void b2MouseJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b = m_bodyB; + + b2Vec2 r = b2Mul(b->GetTransform().R, m_localAnchor - b->GetLocalCenter()); + + // Cdot = v + cross(w, r) + b2Vec2 Cdot = b->m_linearVelocity + b2Cross(b->m_angularVelocity, r); + b2Vec2 impulse = b2Mul(m_mass, -(Cdot + m_beta * m_C + m_gamma * m_impulse)); + + b2Vec2 oldImpulse = m_impulse; + m_impulse += impulse; + float32 maxImpulse = step.dt * m_maxForce; + if (m_impulse.LengthSquared() > maxImpulse * maxImpulse) + { + m_impulse *= maxImpulse / m_impulse.Length(); + } + impulse = m_impulse - oldImpulse; + + b->m_linearVelocity += b->m_invMass * impulse; + b->m_angularVelocity += b->m_invI * b2Cross(r, impulse); +} + +b2Vec2 b2MouseJoint::GetAnchorA() const +{ + return m_target; +} + +b2Vec2 b2MouseJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor); +} + +b2Vec2 b2MouseJoint::GetReactionForce(float32 inv_dt) const +{ + return inv_dt * m_impulse; +} + +float32 b2MouseJoint::GetReactionTorque(float32 inv_dt) const +{ + return inv_dt * 0.0f; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2MouseJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2MouseJoint.h new file mode 100644 index 0000000..42bf7c8 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2MouseJoint.h @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_MOUSE_JOINT_H +#define B2_MOUSE_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Mouse joint definition. This requires a world target point, +/// tuning parameters, and the time step. +struct b2MouseJointDef : public b2JointDef +{ + b2MouseJointDef() + { + type = e_mouseJoint; + target.Set(0.0f, 0.0f); + maxForce = 0.0f; + frequencyHz = 5.0f; + dampingRatio = 0.7f; + } + + /// The initial world target point. This is assumed + /// to coincide with the body anchor initially. + b2Vec2 target; + + /// The maximum constraint force that can be exerted + /// to move the candidate body. Usually you will express + /// as some multiple of the weight (multiplier * mass * gravity). + float32 maxForce; + + /// The response speed. + float32 frequencyHz; + + /// The damping ratio. 0 = no damping, 1 = critical damping. + float32 dampingRatio; +}; + +/// A mouse joint is used to make a point on a body track a +/// specified world point. This a soft constraint with a maximum +/// force. This allows the constraint to stretch and without +/// applying huge forces. +/// NOTE: this joint is not documented in the manual because it was +/// developed to be used in the testbed. If you want to learn how to +/// use the mouse joint, look at the testbed. +class b2MouseJoint : public b2Joint +{ +public: + + /// Implements b2Joint. + b2Vec2 GetAnchorA() const; + + /// Implements b2Joint. + b2Vec2 GetAnchorB() const; + + /// Implements b2Joint. + b2Vec2 GetReactionForce(float32 inv_dt) const; + + /// Implements b2Joint. + float32 GetReactionTorque(float32 inv_dt) const; + + /// Use this to update the target point. + void SetTarget(const b2Vec2& target); + const b2Vec2& GetTarget() const; + + /// Set/get the maximum force in Newtons. + void SetMaxForce(float32 force); + float32 GetMaxForce() const; + + /// Set/get the frequency in Hertz. + void SetFrequency(float32 hz); + float32 GetFrequency() const; + + /// Set/get the damping ratio (dimensionless). + void SetDampingRatio(float32 ratio); + float32 GetDampingRatio() const; + +protected: + friend class b2Joint; + + b2MouseJoint(const b2MouseJointDef* def); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte) { B2_NOT_USED(baumgarte); return true; } + + b2Vec2 m_localAnchor; + b2Vec2 m_target; + b2Vec2 m_impulse; + + b2Mat22 m_mass; // effective mass for point-to-point constraint. + b2Vec2 m_C; // position error + float32 m_maxForce; + float32 m_frequencyHz; + float32 m_dampingRatio; + float32 m_beta; + float32 m_gamma; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp new file mode 100644 index 0000000..a50b59b --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp @@ -0,0 +1,586 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2PrismaticJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Linear constraint (point-to-line) +// d = p2 - p1 = x2 + r2 - x1 - r1 +// C = dot(perp, d) +// Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1)) +// = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2) +// J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)] +// +// Angular constraint +// C = a2 - a1 + a_initial +// Cdot = w2 - w1 +// J = [0 0 -1 0 0 1] +// +// K = J * invM * JT +// +// J = [-a -s1 a s2] +// [0 -1 0 1] +// a = perp +// s1 = cross(d + r1, a) = cross(p2 - x1, a) +// s2 = cross(r2, a) = cross(p2 - x2, a) + + +// Motor/Limit linear constraint +// C = dot(ax1, d) +// Cdot = = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2) +// J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)] + +// Block Solver +// We develop a block solver that includes the joint limit. This makes the limit stiff (inelastic) even +// when the mass has poor distribution (leading to large torques about the joint anchor points). +// +// The Jacobian has 3 rows: +// J = [-uT -s1 uT s2] // linear +// [0 -1 0 1] // angular +// [-vT -a1 vT a2] // limit +// +// u = perp +// v = axis +// s1 = cross(d + r1, u), s2 = cross(r2, u) +// a1 = cross(d + r1, v), a2 = cross(r2, v) + +// M * (v2 - v1) = JT * df +// J * v2 = bias +// +// v2 = v1 + invM * JT * df +// J * (v1 + invM * JT * df) = bias +// K * df = bias - J * v1 = -Cdot +// K = J * invM * JT +// Cdot = J * v1 - bias +// +// Now solve for f2. +// df = f2 - f1 +// K * (f2 - f1) = -Cdot +// f2 = invK * (-Cdot) + f1 +// +// Clamp accumulated limit impulse. +// lower: f2(3) = max(f2(3), 0) +// upper: f2(3) = min(f2(3), 0) +// +// Solve for correct f2(1:2) +// K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:3) * f1 +// = -Cdot(1:2) - K(1:2,3) * f2(3) + K(1:2,1:2) * f1(1:2) + K(1:2,3) * f1(3) +// K(1:2, 1:2) * f2(1:2) = -Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3)) + K(1:2,1:2) * f1(1:2) +// f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) + f1(1:2) +// +// Now compute impulse to be applied: +// df = f2 - f1 + +void b2PrismaticJointDef::Initialize(b2Body* b1, b2Body* b2, const b2Vec2& anchor, const b2Vec2& axis) +{ + bodyA = b1; + bodyB = b2; + localAnchorA = bodyA->GetLocalPoint(anchor); + localAnchorB = bodyB->GetLocalPoint(anchor); + localAxis1 = bodyA->GetLocalVector(axis); + referenceAngle = bodyB->GetAngle() - bodyA->GetAngle(); +} + +b2PrismaticJoint::b2PrismaticJoint(const b2PrismaticJointDef* def) +: b2Joint(def) +{ + m_localAnchor1 = def->localAnchorA; + m_localAnchor2 = def->localAnchorB; + m_localXAxis1 = def->localAxis1; + m_localYAxis1 = b2Cross(1.0f, m_localXAxis1); + m_refAngle = def->referenceAngle; + + m_impulse.SetZero(); + m_motorMass = 0.0; + m_motorImpulse = 0.0f; + + m_lowerTranslation = def->lowerTranslation; + m_upperTranslation = def->upperTranslation; + m_maxMotorForce = def->maxMotorForce; + m_motorSpeed = def->motorSpeed; + m_enableLimit = def->enableLimit; + m_enableMotor = def->enableMotor; + m_limitState = e_inactiveLimit; + + m_axis.SetZero(); + m_perp.SetZero(); +} + +void b2PrismaticJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + m_localCenterA = b1->GetLocalCenter(); + m_localCenterB = b2->GetLocalCenter(); + + b2Transform xf1 = b1->GetTransform(); + b2Transform xf2 = b2->GetTransform(); + + // Compute the effective masses. + b2Vec2 r1 = b2Mul(xf1.R, m_localAnchor1 - m_localCenterA); + b2Vec2 r2 = b2Mul(xf2.R, m_localAnchor2 - m_localCenterB); + b2Vec2 d = b2->m_sweep.c + r2 - b1->m_sweep.c - r1; + + m_invMassA = b1->m_invMass; + m_invIA = b1->m_invI; + m_invMassB = b2->m_invMass; + m_invIB = b2->m_invI; + + // Compute motor Jacobian and effective mass. + { + m_axis = b2Mul(xf1.R, m_localXAxis1); + m_a1 = b2Cross(d + r1, m_axis); + m_a2 = b2Cross(r2, m_axis); + + m_motorMass = m_invMassA + m_invMassB + m_invIA * m_a1 * m_a1 + m_invIB * m_a2 * m_a2; + if (m_motorMass > b2_epsilon) + { + m_motorMass = 1.0f / m_motorMass; + } + } + + // Prismatic constraint. + { + m_perp = b2Mul(xf1.R, m_localYAxis1); + + m_s1 = b2Cross(d + r1, m_perp); + m_s2 = b2Cross(r2, m_perp); + + float32 m1 = m_invMassA, m2 = m_invMassB; + float32 i1 = m_invIA, i2 = m_invIB; + + float32 k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2; + float32 k12 = i1 * m_s1 + i2 * m_s2; + float32 k13 = i1 * m_s1 * m_a1 + i2 * m_s2 * m_a2; + float32 k22 = i1 + i2; + float32 k23 = i1 * m_a1 + i2 * m_a2; + float32 k33 = m1 + m2 + i1 * m_a1 * m_a1 + i2 * m_a2 * m_a2; + + m_K.col1.Set(k11, k12, k13); + m_K.col2.Set(k12, k22, k23); + m_K.col3.Set(k13, k23, k33); + } + + // Compute motor and limit terms. + if (m_enableLimit) + { + float32 jointTranslation = b2Dot(m_axis, d); + if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) + { + m_limitState = e_equalLimits; + } + else if (jointTranslation <= m_lowerTranslation) + { + if (m_limitState != e_atLowerLimit) + { + m_limitState = e_atLowerLimit; + m_impulse.z = 0.0f; + } + } + else if (jointTranslation >= m_upperTranslation) + { + if (m_limitState != e_atUpperLimit) + { + m_limitState = e_atUpperLimit; + m_impulse.z = 0.0f; + } + } + else + { + m_limitState = e_inactiveLimit; + m_impulse.z = 0.0f; + } + } + else + { + m_limitState = e_inactiveLimit; + m_impulse.z = 0.0f; + } + + if (m_enableMotor == false) + { + m_motorImpulse = 0.0f; + } + + if (step.warmStarting) + { + // Account for variable time step. + m_impulse *= step.dtRatio; + m_motorImpulse *= step.dtRatio; + + b2Vec2 P = m_impulse.x * m_perp + (m_motorImpulse + m_impulse.z) * m_axis; + float32 L1 = m_impulse.x * m_s1 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a1; + float32 L2 = m_impulse.x * m_s2 + m_impulse.y + (m_motorImpulse + m_impulse.z) * m_a2; + + b1->m_linearVelocity -= m_invMassA * P; + b1->m_angularVelocity -= m_invIA * L1; + + b2->m_linearVelocity += m_invMassB * P; + b2->m_angularVelocity += m_invIB * L2; + } + else + { + m_impulse.SetZero(); + m_motorImpulse = 0.0f; + } +} + +void b2PrismaticJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 v1 = b1->m_linearVelocity; + float32 w1 = b1->m_angularVelocity; + b2Vec2 v2 = b2->m_linearVelocity; + float32 w2 = b2->m_angularVelocity; + + // Solve linear motor constraint. + if (m_enableMotor && m_limitState != e_equalLimits) + { + float32 Cdot = b2Dot(m_axis, v2 - v1) + m_a2 * w2 - m_a1 * w1; + float32 impulse = m_motorMass * (m_motorSpeed - Cdot); + float32 oldImpulse = m_motorImpulse; + float32 maxImpulse = step.dt * m_maxMotorForce; + m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_motorImpulse - oldImpulse; + + b2Vec2 P = impulse * m_axis; + float32 L1 = impulse * m_a1; + float32 L2 = impulse * m_a2; + + v1 -= m_invMassA * P; + w1 -= m_invIA * L1; + + v2 += m_invMassB * P; + w2 += m_invIB * L2; + } + + b2Vec2 Cdot1; + Cdot1.x = b2Dot(m_perp, v2 - v1) + m_s2 * w2 - m_s1 * w1; + Cdot1.y = w2 - w1; + + if (m_enableLimit && m_limitState != e_inactiveLimit) + { + // Solve prismatic and limit constraint in block form. + float32 Cdot2; + Cdot2 = b2Dot(m_axis, v2 - v1) + m_a2 * w2 - m_a1 * w1; + b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); + + b2Vec3 f1 = m_impulse; + b2Vec3 df = m_K.Solve33(-Cdot); + m_impulse += df; + + if (m_limitState == e_atLowerLimit) + { + m_impulse.z = b2Max(m_impulse.z, 0.0f); + } + else if (m_limitState == e_atUpperLimit) + { + m_impulse.z = b2Min(m_impulse.z, 0.0f); + } + + // f2(1:2) = invK(1:2,1:2) * (-Cdot(1:2) - K(1:2,3) * (f2(3) - f1(3))) + f1(1:2) + b2Vec2 b = -Cdot1 - (m_impulse.z - f1.z) * b2Vec2(m_K.col3.x, m_K.col3.y); + b2Vec2 f2r = m_K.Solve22(b) + b2Vec2(f1.x, f1.y); + m_impulse.x = f2r.x; + m_impulse.y = f2r.y; + + df = m_impulse - f1; + + b2Vec2 P = df.x * m_perp + df.z * m_axis; + float32 L1 = df.x * m_s1 + df.y + df.z * m_a1; + float32 L2 = df.x * m_s2 + df.y + df.z * m_a2; + + v1 -= m_invMassA * P; + w1 -= m_invIA * L1; + + v2 += m_invMassB * P; + w2 += m_invIB * L2; + } + else + { + // Limit is inactive, just solve the prismatic constraint in block form. + b2Vec2 df = m_K.Solve22(-Cdot1); + m_impulse.x += df.x; + m_impulse.y += df.y; + + b2Vec2 P = df.x * m_perp; + float32 L1 = df.x * m_s1 + df.y; + float32 L2 = df.x * m_s2 + df.y; + + v1 -= m_invMassA * P; + w1 -= m_invIA * L1; + + v2 += m_invMassB * P; + w2 += m_invIB * L2; + } + + b1->m_linearVelocity = v1; + b1->m_angularVelocity = w1; + b2->m_linearVelocity = v2; + b2->m_angularVelocity = w2; +} + +bool b2PrismaticJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 c1 = b1->m_sweep.c; + float32 a1 = b1->m_sweep.a; + + b2Vec2 c2 = b2->m_sweep.c; + float32 a2 = b2->m_sweep.a; + + // Solve linear limit constraint. + float32 linearError = 0.0f, angularError = 0.0f; + bool active = false; + float32 C2 = 0.0f; + + b2Mat22 R1(a1), R2(a2); + + b2Vec2 r1 = b2Mul(R1, m_localAnchor1 - m_localCenterA); + b2Vec2 r2 = b2Mul(R2, m_localAnchor2 - m_localCenterB); + b2Vec2 d = c2 + r2 - c1 - r1; + + if (m_enableLimit) + { + m_axis = b2Mul(R1, m_localXAxis1); + + m_a1 = b2Cross(d + r1, m_axis); + m_a2 = b2Cross(r2, m_axis); + + float32 translation = b2Dot(m_axis, d); + if (b2Abs(m_upperTranslation - m_lowerTranslation) < 2.0f * b2_linearSlop) + { + // Prevent large angular corrections + C2 = b2Clamp(translation, -b2_maxLinearCorrection, b2_maxLinearCorrection); + linearError = b2Abs(translation); + active = true; + } + else if (translation <= m_lowerTranslation) + { + // Prevent large linear corrections and allow some slop. + C2 = b2Clamp(translation - m_lowerTranslation + b2_linearSlop, -b2_maxLinearCorrection, 0.0f); + linearError = m_lowerTranslation - translation; + active = true; + } + else if (translation >= m_upperTranslation) + { + // Prevent large linear corrections and allow some slop. + C2 = b2Clamp(translation - m_upperTranslation - b2_linearSlop, 0.0f, b2_maxLinearCorrection); + linearError = translation - m_upperTranslation; + active = true; + } + } + + m_perp = b2Mul(R1, m_localYAxis1); + + m_s1 = b2Cross(d + r1, m_perp); + m_s2 = b2Cross(r2, m_perp); + + b2Vec3 impulse; + b2Vec2 C1; + C1.x = b2Dot(m_perp, d); + C1.y = a2 - a1 - m_refAngle; + + linearError = b2Max(linearError, b2Abs(C1.x)); + angularError = b2Abs(C1.y); + + if (active) + { + float32 m1 = m_invMassA, m2 = m_invMassB; + float32 i1 = m_invIA, i2 = m_invIB; + + float32 k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2; + float32 k12 = i1 * m_s1 + i2 * m_s2; + float32 k13 = i1 * m_s1 * m_a1 + i2 * m_s2 * m_a2; + float32 k22 = i1 + i2; + float32 k23 = i1 * m_a1 + i2 * m_a2; + float32 k33 = m1 + m2 + i1 * m_a1 * m_a1 + i2 * m_a2 * m_a2; + + m_K.col1.Set(k11, k12, k13); + m_K.col2.Set(k12, k22, k23); + m_K.col3.Set(k13, k23, k33); + + b2Vec3 C; + C.x = C1.x; + C.y = C1.y; + C.z = C2; + + impulse = m_K.Solve33(-C); + } + else + { + float32 m1 = m_invMassA, m2 = m_invMassB; + float32 i1 = m_invIA, i2 = m_invIB; + + float32 k11 = m1 + m2 + i1 * m_s1 * m_s1 + i2 * m_s2 * m_s2; + float32 k12 = i1 * m_s1 + i2 * m_s2; + float32 k22 = i1 + i2; + + m_K.col1.Set(k11, k12, 0.0f); + m_K.col2.Set(k12, k22, 0.0f); + + b2Vec2 impulse1 = m_K.Solve22(-C1); + impulse.x = impulse1.x; + impulse.y = impulse1.y; + impulse.z = 0.0f; + } + + b2Vec2 P = impulse.x * m_perp + impulse.z * m_axis; + float32 L1 = impulse.x * m_s1 + impulse.y + impulse.z * m_a1; + float32 L2 = impulse.x * m_s2 + impulse.y + impulse.z * m_a2; + + c1 -= m_invMassA * P; + a1 -= m_invIA * L1; + c2 += m_invMassB * P; + a2 += m_invIB * L2; + + // TODO_ERIN remove need for this. + b1->m_sweep.c = c1; + b1->m_sweep.a = a1; + b2->m_sweep.c = c2; + b2->m_sweep.a = a2; + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + + return linearError <= b2_linearSlop && angularError <= b2_angularSlop; +} + +b2Vec2 b2PrismaticJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchor1); +} + +b2Vec2 b2PrismaticJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor2); +} + +b2Vec2 b2PrismaticJoint::GetReactionForce(float32 inv_dt) const +{ + return inv_dt * (m_impulse.x * m_perp + (m_motorImpulse + m_impulse.z) * m_axis); +} + +float32 b2PrismaticJoint::GetReactionTorque(float32 inv_dt) const +{ + return inv_dt * m_impulse.y; +} + +float32 b2PrismaticJoint::GetJointTranslation() const +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 p1 = b1->GetWorldPoint(m_localAnchor1); + b2Vec2 p2 = b2->GetWorldPoint(m_localAnchor2); + b2Vec2 d = p2 - p1; + b2Vec2 axis = b1->GetWorldVector(m_localXAxis1); + + float32 translation = b2Dot(d, axis); + return translation; +} + +float32 b2PrismaticJoint::GetJointSpeed() const +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + b2Vec2 p1 = b1->m_sweep.c + r1; + b2Vec2 p2 = b2->m_sweep.c + r2; + b2Vec2 d = p2 - p1; + b2Vec2 axis = b1->GetWorldVector(m_localXAxis1); + + b2Vec2 v1 = b1->m_linearVelocity; + b2Vec2 v2 = b2->m_linearVelocity; + float32 w1 = b1->m_angularVelocity; + float32 w2 = b2->m_angularVelocity; + + float32 speed = b2Dot(d, b2Cross(w1, axis)) + b2Dot(axis, v2 + b2Cross(w2, r2) - v1 - b2Cross(w1, r1)); + return speed; +} + +bool b2PrismaticJoint::IsLimitEnabled() const +{ + return m_enableLimit; +} + +void b2PrismaticJoint::EnableLimit(bool flag) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableLimit = flag; +} + +float32 b2PrismaticJoint::GetLowerLimit() const +{ + return m_lowerTranslation; +} + +float32 b2PrismaticJoint::GetUpperLimit() const +{ + return m_upperTranslation; +} + +void b2PrismaticJoint::SetLimits(float32 lower, float32 upper) +{ + b2Assert(lower <= upper); + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_lowerTranslation = lower; + m_upperTranslation = upper; +} + +bool b2PrismaticJoint::IsMotorEnabled() const +{ + return m_enableMotor; +} + +void b2PrismaticJoint::EnableMotor(bool flag) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableMotor = flag; +} + +void b2PrismaticJoint::SetMotorSpeed(float32 speed) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_motorSpeed = speed; +} + +void b2PrismaticJoint::SetMaxMotorForce(float32 force) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_maxMotorForce = force; +} + +float32 b2PrismaticJoint::GetMotorForce() const +{ + return m_motorImpulse; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2PrismaticJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2PrismaticJoint.h new file mode 100644 index 0000000..f162253 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2PrismaticJoint.h @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_PRISMATIC_JOINT_H +#define B2_PRISMATIC_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Prismatic joint definition. This requires defining a line of +/// motion using an axis and an anchor point. The definition uses local +/// anchor points and a local axis so that the initial configuration +/// can violate the constraint slightly. The joint translation is zero +/// when the local anchor points coincide in world space. Using local +/// anchors and a local axis helps when saving and loading a game. +/// @warning at least one body should by dynamic with a non-fixed rotation. +struct b2PrismaticJointDef : public b2JointDef +{ + b2PrismaticJointDef() + { + type = e_prismaticJoint; + localAnchorA.SetZero(); + localAnchorB.SetZero(); + localAxis1.Set(1.0f, 0.0f); + referenceAngle = 0.0f; + enableLimit = false; + lowerTranslation = 0.0f; + upperTranslation = 0.0f; + enableMotor = false; + maxMotorForce = 0.0f; + motorSpeed = 0.0f; + } + + /// Initialize the bodies, anchors, axis, and reference angle using the world + /// anchor and world axis. + void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor, const b2Vec2& axis); + + /// The local anchor point relative to body1's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to body2's origin. + b2Vec2 localAnchorB; + + /// The local translation axis in body1. + b2Vec2 localAxis1; + + /// The constrained angle between the bodies: body2_angle - body1_angle. + float32 referenceAngle; + + /// Enable/disable the joint limit. + bool enableLimit; + + /// The lower translation limit, usually in meters. + float32 lowerTranslation; + + /// The upper translation limit, usually in meters. + float32 upperTranslation; + + /// Enable/disable the joint motor. + bool enableMotor; + + /// The maximum motor torque, usually in N-m. + float32 maxMotorForce; + + /// The desired motor speed in radians per second. + float32 motorSpeed; +}; + +/// A prismatic joint. This joint provides one degree of freedom: translation +/// along an axis fixed in body1. Relative rotation is prevented. You can +/// use a joint limit to restrict the range of motion and a joint motor to +/// drive the motion or to model joint friction. +class b2PrismaticJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Get the current joint translation, usually in meters. + float32 GetJointTranslation() const; + + /// Get the current joint translation speed, usually in meters per second. + float32 GetJointSpeed() const; + + /// Is the joint limit enabled? + bool IsLimitEnabled() const; + + /// Enable/disable the joint limit. + void EnableLimit(bool flag); + + /// Get the lower joint limit, usually in meters. + float32 GetLowerLimit() const; + + /// Get the upper joint limit, usually in meters. + float32 GetUpperLimit() const; + + /// Set the joint limits, usually in meters. + void SetLimits(float32 lower, float32 upper); + + /// Is the joint motor enabled? + bool IsMotorEnabled() const; + + /// Enable/disable the joint motor. + void EnableMotor(bool flag); + + /// Set the motor speed, usually in meters per second. + void SetMotorSpeed(float32 speed); + + /// Get the motor speed, usually in meters per second. + float32 GetMotorSpeed() const; + + /// Set the maximum motor force, usually in N. + void SetMaxMotorForce(float32 force); + + /// Get the current motor force, usually in N. + float32 GetMotorForce() const; + +protected: + friend class b2Joint; + friend class b2GearJoint; + b2PrismaticJoint(const b2PrismaticJointDef* def); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_localAnchor1; + b2Vec2 m_localAnchor2; + b2Vec2 m_localXAxis1; + b2Vec2 m_localYAxis1; + float32 m_refAngle; + + b2Vec2 m_axis, m_perp; + float32 m_s1, m_s2; + float32 m_a1, m_a2; + + b2Mat33 m_K; + b2Vec3 m_impulse; + + float32 m_motorMass; // effective mass for motor/limit translational constraint. + float32 m_motorImpulse; + + float32 m_lowerTranslation; + float32 m_upperTranslation; + float32 m_maxMotorForce; + float32 m_motorSpeed; + + bool m_enableLimit; + bool m_enableMotor; + b2LimitState m_limitState; +}; + +inline float32 b2PrismaticJoint::GetMotorSpeed() const +{ + return m_motorSpeed; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2PulleyJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2PulleyJoint.cpp new file mode 100644 index 0000000..2159711 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2PulleyJoint.cpp @@ -0,0 +1,427 @@ +/* +* Copyright (c) 2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Pulley: +// length1 = norm(p1 - s1) +// length2 = norm(p2 - s2) +// C0 = (length1 + ratio * length2)_initial +// C = C0 - (length1 + ratio * length2) >= 0 +// u1 = (p1 - s1) / norm(p1 - s1) +// u2 = (p2 - s2) / norm(p2 - s2) +// Cdot = -dot(u1, v1 + cross(w1, r1)) - ratio * dot(u2, v2 + cross(w2, r2)) +// J = -[u1 cross(r1, u1) ratio * u2 ratio * cross(r2, u2)] +// K = J * invM * JT +// = invMass1 + invI1 * cross(r1, u1)^2 + ratio^2 * (invMass2 + invI2 * cross(r2, u2)^2) +// +// Limit: +// C = maxLength - length +// u = (p - s) / norm(p - s) +// Cdot = -dot(u, v + cross(w, r)) +// K = invMass + invI * cross(r, u)^2 +// 0 <= impulse + +void b2PulleyJointDef::Initialize(b2Body* b1, b2Body* b2, + const b2Vec2& ga1, const b2Vec2& ga2, + const b2Vec2& anchor1, const b2Vec2& anchor2, + float32 r) +{ + bodyA = b1; + bodyB = b2; + groundAnchorA = ga1; + groundAnchorB = ga2; + localAnchorA = bodyA->GetLocalPoint(anchor1); + localAnchorB = bodyB->GetLocalPoint(anchor2); + b2Vec2 d1 = anchor1 - ga1; + lengthA = d1.Length(); + b2Vec2 d2 = anchor2 - ga2; + lengthB = d2.Length(); + ratio = r; + b2Assert(ratio > b2_epsilon); + float32 C = lengthA + ratio * lengthB; + maxLengthA = C - ratio * b2_minPulleyLength; + maxLengthB = (C - b2_minPulleyLength) / ratio; +} + +b2PulleyJoint::b2PulleyJoint(const b2PulleyJointDef* def) +: b2Joint(def) +{ + m_groundAnchor1 = def->groundAnchorA; + m_groundAnchor2 = def->groundAnchorB; + m_localAnchor1 = def->localAnchorA; + m_localAnchor2 = def->localAnchorB; + + b2Assert(def->ratio != 0.0f); + m_ratio = def->ratio; + + m_constant = def->lengthA + m_ratio * def->lengthB; + + m_maxLength1 = b2Min(def->maxLengthA, m_constant - m_ratio * b2_minPulleyLength); + m_maxLength2 = b2Min(def->maxLengthB, (m_constant - b2_minPulleyLength) / m_ratio); + + m_impulse = 0.0f; + m_limitImpulse1 = 0.0f; + m_limitImpulse2 = 0.0f; +} + +void b2PulleyJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + b2Vec2 p1 = b1->m_sweep.c + r1; + b2Vec2 p2 = b2->m_sweep.c + r2; + + b2Vec2 s1 = m_groundAnchor1; + b2Vec2 s2 = m_groundAnchor2; + + // Get the pulley axes. + m_u1 = p1 - s1; + m_u2 = p2 - s2; + + float32 length1 = m_u1.Length(); + float32 length2 = m_u2.Length(); + + if (length1 > b2_linearSlop) + { + m_u1 *= 1.0f / length1; + } + else + { + m_u1.SetZero(); + } + + if (length2 > b2_linearSlop) + { + m_u2 *= 1.0f / length2; + } + else + { + m_u2.SetZero(); + } + + float32 C = m_constant - length1 - m_ratio * length2; + if (C > 0.0f) + { + m_state = e_inactiveLimit; + m_impulse = 0.0f; + } + else + { + m_state = e_atUpperLimit; + } + + if (length1 < m_maxLength1) + { + m_limitState1 = e_inactiveLimit; + m_limitImpulse1 = 0.0f; + } + else + { + m_limitState1 = e_atUpperLimit; + } + + if (length2 < m_maxLength2) + { + m_limitState2 = e_inactiveLimit; + m_limitImpulse2 = 0.0f; + } + else + { + m_limitState2 = e_atUpperLimit; + } + + // Compute effective mass. + float32 cr1u1 = b2Cross(r1, m_u1); + float32 cr2u2 = b2Cross(r2, m_u2); + + m_limitMass1 = b1->m_invMass + b1->m_invI * cr1u1 * cr1u1; + m_limitMass2 = b2->m_invMass + b2->m_invI * cr2u2 * cr2u2; + m_pulleyMass = m_limitMass1 + m_ratio * m_ratio * m_limitMass2; + b2Assert(m_limitMass1 > b2_epsilon); + b2Assert(m_limitMass2 > b2_epsilon); + b2Assert(m_pulleyMass > b2_epsilon); + m_limitMass1 = 1.0f / m_limitMass1; + m_limitMass2 = 1.0f / m_limitMass2; + m_pulleyMass = 1.0f / m_pulleyMass; + + if (step.warmStarting) + { + // Scale impulses to support variable time steps. + m_impulse *= step.dtRatio; + m_limitImpulse1 *= step.dtRatio; + m_limitImpulse2 *= step.dtRatio; + + // Warm starting. + b2Vec2 P1 = -(m_impulse + m_limitImpulse1) * m_u1; + b2Vec2 P2 = (-m_ratio * m_impulse - m_limitImpulse2) * m_u2; + b1->m_linearVelocity += b1->m_invMass * P1; + b1->m_angularVelocity += b1->m_invI * b2Cross(r1, P1); + b2->m_linearVelocity += b2->m_invMass * P2; + b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P2); + } + else + { + m_impulse = 0.0f; + m_limitImpulse1 = 0.0f; + m_limitImpulse2 = 0.0f; + } +} + +void b2PulleyJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + B2_NOT_USED(step); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + if (m_state == e_atUpperLimit) + { + b2Vec2 v1 = b1->m_linearVelocity + b2Cross(b1->m_angularVelocity, r1); + b2Vec2 v2 = b2->m_linearVelocity + b2Cross(b2->m_angularVelocity, r2); + + float32 Cdot = -b2Dot(m_u1, v1) - m_ratio * b2Dot(m_u2, v2); + float32 impulse = m_pulleyMass * (-Cdot); + float32 oldImpulse = m_impulse; + m_impulse = b2Max(0.0f, m_impulse + impulse); + impulse = m_impulse - oldImpulse; + + b2Vec2 P1 = -impulse * m_u1; + b2Vec2 P2 = -m_ratio * impulse * m_u2; + b1->m_linearVelocity += b1->m_invMass * P1; + b1->m_angularVelocity += b1->m_invI * b2Cross(r1, P1); + b2->m_linearVelocity += b2->m_invMass * P2; + b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P2); + } + + if (m_limitState1 == e_atUpperLimit) + { + b2Vec2 v1 = b1->m_linearVelocity + b2Cross(b1->m_angularVelocity, r1); + + float32 Cdot = -b2Dot(m_u1, v1); + float32 impulse = -m_limitMass1 * Cdot; + float32 oldImpulse = m_limitImpulse1; + m_limitImpulse1 = b2Max(0.0f, m_limitImpulse1 + impulse); + impulse = m_limitImpulse1 - oldImpulse; + + b2Vec2 P1 = -impulse * m_u1; + b1->m_linearVelocity += b1->m_invMass * P1; + b1->m_angularVelocity += b1->m_invI * b2Cross(r1, P1); + } + + if (m_limitState2 == e_atUpperLimit) + { + b2Vec2 v2 = b2->m_linearVelocity + b2Cross(b2->m_angularVelocity, r2); + + float32 Cdot = -b2Dot(m_u2, v2); + float32 impulse = -m_limitMass2 * Cdot; + float32 oldImpulse = m_limitImpulse2; + m_limitImpulse2 = b2Max(0.0f, m_limitImpulse2 + impulse); + impulse = m_limitImpulse2 - oldImpulse; + + b2Vec2 P2 = -impulse * m_u2; + b2->m_linearVelocity += b2->m_invMass * P2; + b2->m_angularVelocity += b2->m_invI * b2Cross(r2, P2); + } +} + +bool b2PulleyJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 s1 = m_groundAnchor1; + b2Vec2 s2 = m_groundAnchor2; + + float32 linearError = 0.0f; + + if (m_state == e_atUpperLimit) + { + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + b2Vec2 p1 = b1->m_sweep.c + r1; + b2Vec2 p2 = b2->m_sweep.c + r2; + + // Get the pulley axes. + m_u1 = p1 - s1; + m_u2 = p2 - s2; + + float32 length1 = m_u1.Length(); + float32 length2 = m_u2.Length(); + + if (length1 > b2_linearSlop) + { + m_u1 *= 1.0f / length1; + } + else + { + m_u1.SetZero(); + } + + if (length2 > b2_linearSlop) + { + m_u2 *= 1.0f / length2; + } + else + { + m_u2.SetZero(); + } + + float32 C = m_constant - length1 - m_ratio * length2; + linearError = b2Max(linearError, -C); + + C = b2Clamp(C + b2_linearSlop, -b2_maxLinearCorrection, 0.0f); + float32 impulse = -m_pulleyMass * C; + + b2Vec2 P1 = -impulse * m_u1; + b2Vec2 P2 = -m_ratio * impulse * m_u2; + + b1->m_sweep.c += b1->m_invMass * P1; + b1->m_sweep.a += b1->m_invI * b2Cross(r1, P1); + b2->m_sweep.c += b2->m_invMass * P2; + b2->m_sweep.a += b2->m_invI * b2Cross(r2, P2); + + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + } + + if (m_limitState1 == e_atUpperLimit) + { + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 p1 = b1->m_sweep.c + r1; + + m_u1 = p1 - s1; + float32 length1 = m_u1.Length(); + + if (length1 > b2_linearSlop) + { + m_u1 *= 1.0f / length1; + } + else + { + m_u1.SetZero(); + } + + float32 C = m_maxLength1 - length1; + linearError = b2Max(linearError, -C); + C = b2Clamp(C + b2_linearSlop, -b2_maxLinearCorrection, 0.0f); + float32 impulse = -m_limitMass1 * C; + + b2Vec2 P1 = -impulse * m_u1; + b1->m_sweep.c += b1->m_invMass * P1; + b1->m_sweep.a += b1->m_invI * b2Cross(r1, P1); + + b1->SynchronizeTransform(); + } + + if (m_limitState2 == e_atUpperLimit) + { + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + b2Vec2 p2 = b2->m_sweep.c + r2; + + m_u2 = p2 - s2; + float32 length2 = m_u2.Length(); + + if (length2 > b2_linearSlop) + { + m_u2 *= 1.0f / length2; + } + else + { + m_u2.SetZero(); + } + + float32 C = m_maxLength2 - length2; + linearError = b2Max(linearError, -C); + C = b2Clamp(C + b2_linearSlop, -b2_maxLinearCorrection, 0.0f); + float32 impulse = -m_limitMass2 * C; + + b2Vec2 P2 = -impulse * m_u2; + b2->m_sweep.c += b2->m_invMass * P2; + b2->m_sweep.a += b2->m_invI * b2Cross(r2, P2); + + b2->SynchronizeTransform(); + } + + return linearError < b2_linearSlop; +} + +b2Vec2 b2PulleyJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchor1); +} + +b2Vec2 b2PulleyJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor2); +} + +b2Vec2 b2PulleyJoint::GetReactionForce(float32 inv_dt) const +{ + b2Vec2 P = m_impulse * m_u2; + return inv_dt * P; +} + +float32 b2PulleyJoint::GetReactionTorque(float32 inv_dt) const +{ + B2_NOT_USED(inv_dt); + return 0.0f; +} + +b2Vec2 b2PulleyJoint::GetGroundAnchorA() const +{ + return m_groundAnchor1; +} + +b2Vec2 b2PulleyJoint::GetGroundAnchorB() const +{ + return m_groundAnchor2; +} + +float32 b2PulleyJoint::GetLength1() const +{ + b2Vec2 p = m_bodyA->GetWorldPoint(m_localAnchor1); + b2Vec2 s = m_groundAnchor1; + b2Vec2 d = p - s; + return d.Length(); +} + +float32 b2PulleyJoint::GetLength2() const +{ + b2Vec2 p = m_bodyB->GetWorldPoint(m_localAnchor2); + b2Vec2 s = m_groundAnchor2; + b2Vec2 d = p - s; + return d.Length(); +} + +float32 b2PulleyJoint::GetRatio() const +{ + return m_ratio; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2PulleyJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2PulleyJoint.h new file mode 100644 index 0000000..2605292 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2PulleyJoint.h @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_PULLEY_JOINT_H +#define B2_PULLEY_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +const float32 b2_minPulleyLength = 2.0f; + +/// Pulley joint definition. This requires two ground anchors, +/// two dynamic body anchor points, max lengths for each side, +/// and a pulley ratio. +struct b2PulleyJointDef : public b2JointDef +{ + b2PulleyJointDef() + { + type = e_pulleyJoint; + groundAnchorA.Set(-1.0f, 1.0f); + groundAnchorB.Set(1.0f, 1.0f); + localAnchorA.Set(-1.0f, 0.0f); + localAnchorB.Set(1.0f, 0.0f); + lengthA = 0.0f; + maxLengthA = 0.0f; + lengthB = 0.0f; + maxLengthB = 0.0f; + ratio = 1.0f; + collideConnected = true; + } + + /// Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors. + void Initialize(b2Body* bodyA, b2Body* bodyB, + const b2Vec2& groundAnchorA, const b2Vec2& groundAnchorB, + const b2Vec2& anchorA, const b2Vec2& anchorB, + float32 ratio); + + /// The first ground anchor in world coordinates. This point never moves. + b2Vec2 groundAnchorA; + + /// The second ground anchor in world coordinates. This point never moves. + b2Vec2 groundAnchorB; + + /// The local anchor point relative to bodyA's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to bodyB's origin. + b2Vec2 localAnchorB; + + /// The a reference length for the segment attached to bodyA. + float32 lengthA; + + /// The maximum length of the segment attached to bodyA. + float32 maxLengthA; + + /// The a reference length for the segment attached to bodyB. + float32 lengthB; + + /// The maximum length of the segment attached to bodyB. + float32 maxLengthB; + + /// The pulley ratio, used to simulate a block-and-tackle. + float32 ratio; +}; + +/// The pulley joint is connected to two bodies and two fixed ground points. +/// The pulley supports a ratio such that: +/// length1 + ratio * length2 <= constant +/// Yes, the force transmitted is scaled by the ratio. +/// The pulley also enforces a maximum length limit on both sides. This is +/// useful to prevent one side of the pulley hitting the top. +class b2PulleyJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Get the first ground anchor. + b2Vec2 GetGroundAnchorA() const; + + /// Get the second ground anchor. + b2Vec2 GetGroundAnchorB() const; + + /// Get the current length of the segment attached to body1. + float32 GetLength1() const; + + /// Get the current length of the segment attached to body2. + float32 GetLength2() const; + + /// Get the pulley ratio. + float32 GetRatio() const; + +protected: + + friend class b2Joint; + b2PulleyJoint(const b2PulleyJointDef* data); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_groundAnchor1; + b2Vec2 m_groundAnchor2; + b2Vec2 m_localAnchor1; + b2Vec2 m_localAnchor2; + + b2Vec2 m_u1; + b2Vec2 m_u2; + + float32 m_constant; + float32 m_ratio; + + float32 m_maxLength1; + float32 m_maxLength2; + + // Effective masses + float32 m_pulleyMass; + float32 m_limitMass1; + float32 m_limitMass2; + + // Impulses for accumulation/warm starting. + float32 m_impulse; + float32 m_limitImpulse1; + float32 m_limitImpulse2; + + b2LimitState m_state; + b2LimitState m_limitState1; + b2LimitState m_limitState2; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp new file mode 100644 index 0000000..ba8fa22 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp @@ -0,0 +1,478 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2RevoluteJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Point-to-point constraint +// C = p2 - p1 +// Cdot = v2 - v1 +// = v2 + cross(w2, r2) - v1 - cross(w1, r1) +// J = [-I -r1_skew I r2_skew ] +// Identity used: +// w k % (rx i + ry j) = w * (-ry i + rx j) + +// Motor constraint +// Cdot = w2 - w1 +// J = [0 0 -1 0 0 1] +// K = invI1 + invI2 + +void b2RevoluteJointDef::Initialize(b2Body* b1, b2Body* b2, const b2Vec2& anchor) +{ + bodyA = b1; + bodyB = b2; + localAnchorA = bodyA->GetLocalPoint(anchor); + localAnchorB = bodyB->GetLocalPoint(anchor); + referenceAngle = bodyB->GetAngle() - bodyA->GetAngle(); +} + +b2RevoluteJoint::b2RevoluteJoint(const b2RevoluteJointDef* def) +: b2Joint(def) +{ + m_localAnchor1 = def->localAnchorA; + m_localAnchor2 = def->localAnchorB; + m_referenceAngle = def->referenceAngle; + + m_impulse.SetZero(); + m_motorImpulse = 0.0f; + + m_lowerAngle = def->lowerAngle; + m_upperAngle = def->upperAngle; + m_maxMotorTorque = def->maxMotorTorque; + m_motorSpeed = def->motorSpeed; + m_enableLimit = def->enableLimit; + m_enableMotor = def->enableMotor; + m_limitState = e_inactiveLimit; +} + +void b2RevoluteJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + if (m_enableMotor || m_enableLimit) + { + // You cannot create a rotation limit between bodies that + // both have fixed rotation. + b2Assert(b1->m_invI > 0.0f || b2->m_invI > 0.0f); + } + + // Compute the effective mass matrix. + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + // J = [-I -r1_skew I r2_skew] + // [ 0 -1 0 1] + // r_skew = [-ry; rx] + + // Matlab + // K = [ m1+r1y^2*i1+m2+r2y^2*i2, -r1y*i1*r1x-r2y*i2*r2x, -r1y*i1-r2y*i2] + // [ -r1y*i1*r1x-r2y*i2*r2x, m1+r1x^2*i1+m2+r2x^2*i2, r1x*i1+r2x*i2] + // [ -r1y*i1-r2y*i2, r1x*i1+r2x*i2, i1+i2] + + float32 m1 = b1->m_invMass, m2 = b2->m_invMass; + float32 i1 = b1->m_invI, i2 = b2->m_invI; + + m_mass.col1.x = m1 + m2 + r1.y * r1.y * i1 + r2.y * r2.y * i2; + m_mass.col2.x = -r1.y * r1.x * i1 - r2.y * r2.x * i2; + m_mass.col3.x = -r1.y * i1 - r2.y * i2; + m_mass.col1.y = m_mass.col2.x; + m_mass.col2.y = m1 + m2 + r1.x * r1.x * i1 + r2.x * r2.x * i2; + m_mass.col3.y = r1.x * i1 + r2.x * i2; + m_mass.col1.z = m_mass.col3.x; + m_mass.col2.z = m_mass.col3.y; + m_mass.col3.z = i1 + i2; + + m_motorMass = i1 + i2; + if (m_motorMass > 0.0f) + { + m_motorMass = 1.0f / m_motorMass; + } + + if (m_enableMotor == false) + { + m_motorImpulse = 0.0f; + } + + if (m_enableLimit) + { + float32 jointAngle = b2->m_sweep.a - b1->m_sweep.a - m_referenceAngle; + if (b2Abs(m_upperAngle - m_lowerAngle) < 2.0f * b2_angularSlop) + { + m_limitState = e_equalLimits; + } + else if (jointAngle <= m_lowerAngle) + { + if (m_limitState != e_atLowerLimit) + { + m_impulse.z = 0.0f; + } + m_limitState = e_atLowerLimit; + } + else if (jointAngle >= m_upperAngle) + { + if (m_limitState != e_atUpperLimit) + { + m_impulse.z = 0.0f; + } + m_limitState = e_atUpperLimit; + } + else + { + m_limitState = e_inactiveLimit; + m_impulse.z = 0.0f; + } + } + else + { + m_limitState = e_inactiveLimit; + } + + if (step.warmStarting) + { + // Scale impulses to support a variable time step. + m_impulse *= step.dtRatio; + m_motorImpulse *= step.dtRatio; + + b2Vec2 P(m_impulse.x, m_impulse.y); + + b1->m_linearVelocity -= m1 * P; + b1->m_angularVelocity -= i1 * (b2Cross(r1, P) + m_motorImpulse + m_impulse.z); + + b2->m_linearVelocity += m2 * P; + b2->m_angularVelocity += i2 * (b2Cross(r2, P) + m_motorImpulse + m_impulse.z); + } + else + { + m_impulse.SetZero(); + m_motorImpulse = 0.0f; + } +} + +void b2RevoluteJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + b2Vec2 v1 = b1->m_linearVelocity; + float32 w1 = b1->m_angularVelocity; + b2Vec2 v2 = b2->m_linearVelocity; + float32 w2 = b2->m_angularVelocity; + + float32 m1 = b1->m_invMass, m2 = b2->m_invMass; + float32 i1 = b1->m_invI, i2 = b2->m_invI; + + // Solve motor constraint. + if (m_enableMotor && m_limitState != e_equalLimits) + { + float32 Cdot = w2 - w1 - m_motorSpeed; + float32 impulse = m_motorMass * (-Cdot); + float32 oldImpulse = m_motorImpulse; + float32 maxImpulse = step.dt * m_maxMotorTorque; + m_motorImpulse = b2Clamp(m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = m_motorImpulse - oldImpulse; + + w1 -= i1 * impulse; + w2 += i2 * impulse; + } + + // Solve limit constraint. + if (m_enableLimit && m_limitState != e_inactiveLimit) + { + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + // Solve point-to-point constraint + b2Vec2 Cdot1 = v2 + b2Cross(w2, r2) - v1 - b2Cross(w1, r1); + float32 Cdot2 = w2 - w1; + b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); + + b2Vec3 impulse = m_mass.Solve33(-Cdot); + + if (m_limitState == e_equalLimits) + { + m_impulse += impulse; + } + else if (m_limitState == e_atLowerLimit) + { + float32 newImpulse = m_impulse.z + impulse.z; + if (newImpulse < 0.0f) + { + b2Vec2 reduced = m_mass.Solve22(-Cdot1); + impulse.x = reduced.x; + impulse.y = reduced.y; + impulse.z = -m_impulse.z; + m_impulse.x += reduced.x; + m_impulse.y += reduced.y; + m_impulse.z = 0.0f; + } + } + else if (m_limitState == e_atUpperLimit) + { + float32 newImpulse = m_impulse.z + impulse.z; + if (newImpulse > 0.0f) + { + b2Vec2 reduced = m_mass.Solve22(-Cdot1); + impulse.x = reduced.x; + impulse.y = reduced.y; + impulse.z = -m_impulse.z; + m_impulse.x += reduced.x; + m_impulse.y += reduced.y; + m_impulse.z = 0.0f; + } + } + + b2Vec2 P(impulse.x, impulse.y); + + v1 -= m1 * P; + w1 -= i1 * (b2Cross(r1, P) + impulse.z); + + v2 += m2 * P; + w2 += i2 * (b2Cross(r2, P) + impulse.z); + } + else + { + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + // Solve point-to-point constraint + b2Vec2 Cdot = v2 + b2Cross(w2, r2) - v1 - b2Cross(w1, r1); + b2Vec2 impulse = m_mass.Solve22(-Cdot); + + m_impulse.x += impulse.x; + m_impulse.y += impulse.y; + + v1 -= m1 * impulse; + w1 -= i1 * b2Cross(r1, impulse); + + v2 += m2 * impulse; + w2 += i2 * b2Cross(r2, impulse); + } + + b1->m_linearVelocity = v1; + b1->m_angularVelocity = w1; + b2->m_linearVelocity = v2; + b2->m_angularVelocity = w2; +} + +bool b2RevoluteJoint::SolvePositionConstraints(float32 baumgarte) +{ + // TODO_ERIN block solve with limit. + + B2_NOT_USED(baumgarte); + + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + + float32 angularError = 0.0f; + float32 positionError = 0.0f; + + // Solve angular limit constraint. + if (m_enableLimit && m_limitState != e_inactiveLimit) + { + float32 angle = b2->m_sweep.a - b1->m_sweep.a - m_referenceAngle; + float32 limitImpulse = 0.0f; + + if (m_limitState == e_equalLimits) + { + // Prevent large angular corrections + float32 C = b2Clamp(angle - m_lowerAngle, -b2_maxAngularCorrection, b2_maxAngularCorrection); + limitImpulse = -m_motorMass * C; + angularError = b2Abs(C); + } + else if (m_limitState == e_atLowerLimit) + { + float32 C = angle - m_lowerAngle; + angularError = -C; + + // Prevent large angular corrections and allow some slop. + C = b2Clamp(C + b2_angularSlop, -b2_maxAngularCorrection, 0.0f); + limitImpulse = -m_motorMass * C; + } + else if (m_limitState == e_atUpperLimit) + { + float32 C = angle - m_upperAngle; + angularError = C; + + // Prevent large angular corrections and allow some slop. + C = b2Clamp(C - b2_angularSlop, 0.0f, b2_maxAngularCorrection); + limitImpulse = -m_motorMass * C; + } + + b1->m_sweep.a -= b1->m_invI * limitImpulse; + b2->m_sweep.a += b2->m_invI * limitImpulse; + + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + } + + // Solve point-to-point constraint. + { + b2Vec2 r1 = b2Mul(b1->GetTransform().R, m_localAnchor1 - b1->GetLocalCenter()); + b2Vec2 r2 = b2Mul(b2->GetTransform().R, m_localAnchor2 - b2->GetLocalCenter()); + + b2Vec2 C = b2->m_sweep.c + r2 - b1->m_sweep.c - r1; + positionError = C.Length(); + + float32 invMass1 = b1->m_invMass, invMass2 = b2->m_invMass; + float32 invI1 = b1->m_invI, invI2 = b2->m_invI; + + // Handle large detachment. + const float32 k_allowedStretch = 10.0f * b2_linearSlop; + if (C.LengthSquared() > k_allowedStretch * k_allowedStretch) + { + // Use a particle solution (no rotation). + b2Vec2 u = C; u.Normalize(); + float32 m = invMass1 + invMass2; + if (m > 0.0f) + { + m = 1.0f / m; + } + b2Vec2 impulse = m * (-C); + const float32 k_beta = 0.5f; + b1->m_sweep.c -= k_beta * invMass1 * impulse; + b2->m_sweep.c += k_beta * invMass2 * impulse; + + C = b2->m_sweep.c + r2 - b1->m_sweep.c - r1; + } + + b2Mat22 K1; + K1.col1.x = invMass1 + invMass2; K1.col2.x = 0.0f; + K1.col1.y = 0.0f; K1.col2.y = invMass1 + invMass2; + + b2Mat22 K2; + K2.col1.x = invI1 * r1.y * r1.y; K2.col2.x = -invI1 * r1.x * r1.y; + K2.col1.y = -invI1 * r1.x * r1.y; K2.col2.y = invI1 * r1.x * r1.x; + + b2Mat22 K3; + K3.col1.x = invI2 * r2.y * r2.y; K3.col2.x = -invI2 * r2.x * r2.y; + K3.col1.y = -invI2 * r2.x * r2.y; K3.col2.y = invI2 * r2.x * r2.x; + + b2Mat22 K = K1 + K2 + K3; + b2Vec2 impulse = K.Solve(-C); + + b1->m_sweep.c -= b1->m_invMass * impulse; + b1->m_sweep.a -= b1->m_invI * b2Cross(r1, impulse); + + b2->m_sweep.c += b2->m_invMass * impulse; + b2->m_sweep.a += b2->m_invI * b2Cross(r2, impulse); + + b1->SynchronizeTransform(); + b2->SynchronizeTransform(); + } + + return positionError <= b2_linearSlop && angularError <= b2_angularSlop; +} + +b2Vec2 b2RevoluteJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchor1); +} + +b2Vec2 b2RevoluteJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchor2); +} + +b2Vec2 b2RevoluteJoint::GetReactionForce(float32 inv_dt) const +{ + b2Vec2 P(m_impulse.x, m_impulse.y); + return inv_dt * P; +} + +float32 b2RevoluteJoint::GetReactionTorque(float32 inv_dt) const +{ + return inv_dt * m_impulse.z; +} + +float32 b2RevoluteJoint::GetJointAngle() const +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + return b2->m_sweep.a - b1->m_sweep.a - m_referenceAngle; +} + +float32 b2RevoluteJoint::GetJointSpeed() const +{ + b2Body* b1 = m_bodyA; + b2Body* b2 = m_bodyB; + return b2->m_angularVelocity - b1->m_angularVelocity; +} + +bool b2RevoluteJoint::IsMotorEnabled() const +{ + return m_enableMotor; +} + +void b2RevoluteJoint::EnableMotor(bool flag) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableMotor = flag; +} + +float32 b2RevoluteJoint::GetMotorTorque() const +{ + return m_motorImpulse; +} + +void b2RevoluteJoint::SetMotorSpeed(float32 speed) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_motorSpeed = speed; +} + +void b2RevoluteJoint::SetMaxMotorTorque(float32 torque) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_maxMotorTorque = torque; +} + +bool b2RevoluteJoint::IsLimitEnabled() const +{ + return m_enableLimit; +} + +void b2RevoluteJoint::EnableLimit(bool flag) +{ + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_enableLimit = flag; +} + +float32 b2RevoluteJoint::GetLowerLimit() const +{ + return m_lowerAngle; +} + +float32 b2RevoluteJoint::GetUpperLimit() const +{ + return m_upperAngle; +} + +void b2RevoluteJoint::SetLimits(float32 lower, float32 upper) +{ + b2Assert(lower <= upper); + m_bodyA->SetAwake(true); + m_bodyB->SetAwake(true); + m_lowerAngle = lower; + m_upperAngle = upper; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2RevoluteJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2RevoluteJoint.h new file mode 100644 index 0000000..bf54b05 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2RevoluteJoint.h @@ -0,0 +1,174 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_REVOLUTE_JOINT_H +#define B2_REVOLUTE_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Revolute joint definition. This requires defining an +/// anchor point where the bodies are joined. The definition +/// uses local anchor points so that the initial configuration +/// can violate the constraint slightly. You also need to +/// specify the initial relative angle for joint limits. This +/// helps when saving and loading a game. +/// The local anchor points are measured from the body's origin +/// rather than the center of mass because: +/// 1. you might not know where the center of mass will be. +/// 2. if you add/remove shapes from a body and recompute the mass, +/// the joints will be broken. +struct b2RevoluteJointDef : public b2JointDef +{ + b2RevoluteJointDef() + { + type = e_revoluteJoint; + localAnchorA.Set(0.0f, 0.0f); + localAnchorB.Set(0.0f, 0.0f); + referenceAngle = 0.0f; + lowerAngle = 0.0f; + upperAngle = 0.0f; + maxMotorTorque = 0.0f; + motorSpeed = 0.0f; + enableLimit = false; + enableMotor = false; + } + + /// Initialize the bodies, anchors, and reference angle using a world + /// anchor point. + void Initialize(b2Body* bodyA, b2Body* bodyB, const b2Vec2& anchor); + + /// The local anchor point relative to body1's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to body2's origin. + b2Vec2 localAnchorB; + + /// The body2 angle minus body1 angle in the reference state (radians). + float32 referenceAngle; + + /// A flag to enable joint limits. + bool enableLimit; + + /// The lower angle for the joint limit (radians). + float32 lowerAngle; + + /// The upper angle for the joint limit (radians). + float32 upperAngle; + + /// A flag to enable the joint motor. + bool enableMotor; + + /// The desired motor speed. Usually in radians per second. + float32 motorSpeed; + + /// The maximum motor torque used to achieve the desired motor speed. + /// Usually in N-m. + float32 maxMotorTorque; +}; + +/// A revolute joint constrains two bodies to share a common point while they +/// are free to rotate about the point. The relative rotation about the shared +/// point is the joint angle. You can limit the relative rotation with +/// a joint limit that specifies a lower and upper angle. You can use a motor +/// to drive the relative rotation about the shared point. A maximum motor torque +/// is provided so that infinite forces are not generated. +class b2RevoluteJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + + /// Get the current joint angle in radians. + float32 GetJointAngle() const; + + /// Get the current joint angle speed in radians per second. + float32 GetJointSpeed() const; + + /// Is the joint limit enabled? + bool IsLimitEnabled() const; + + /// Enable/disable the joint limit. + void EnableLimit(bool flag); + + /// Get the lower joint limit in radians. + float32 GetLowerLimit() const; + + /// Get the upper joint limit in radians. + float32 GetUpperLimit() const; + + /// Set the joint limits in radians. + void SetLimits(float32 lower, float32 upper); + + /// Is the joint motor enabled? + bool IsMotorEnabled() const; + + /// Enable/disable the joint motor. + void EnableMotor(bool flag); + + /// Set the motor speed in radians per second. + void SetMotorSpeed(float32 speed); + + /// Get the motor speed in radians per second. + float32 GetMotorSpeed() const; + + /// Set the maximum motor torque, usually in N-m. + void SetMaxMotorTorque(float32 torque); + + /// Get the current motor torque, usually in N-m. + float32 GetMotorTorque() const; + +protected: + + friend class b2Joint; + friend class b2GearJoint; + + b2RevoluteJoint(const b2RevoluteJointDef* def); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_localAnchor1; // relative + b2Vec2 m_localAnchor2; + b2Vec3 m_impulse; + float32 m_motorImpulse; + + b2Mat33 m_mass; // effective mass for point-to-point constraint. + float32 m_motorMass; // effective mass for motor/limit angular constraint. + + bool m_enableMotor; + float32 m_maxMotorTorque; + float32 m_motorSpeed; + + bool m_enableLimit; + float32 m_referenceAngle; + float32 m_lowerAngle; + float32 m_upperAngle; + b2LimitState m_limitState; +}; + +inline float32 b2RevoluteJoint::GetMotorSpeed() const +{ + return m_motorSpeed; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2WeldJoint.cpp b/AndEngine/jni/Box2D/Dynamics/Joints/b2WeldJoint.cpp new file mode 100644 index 0000000..abe4ab3 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2WeldJoint.cpp @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/Joints/b2WeldJoint.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +// Point-to-point constraint +// C = p2 - p1 +// Cdot = v2 - v1 +// = v2 + cross(w2, r2) - v1 - cross(w1, r1) +// J = [-I -r1_skew I r2_skew ] +// Identity used: +// w k % (rx i + ry j) = w * (-ry i + rx j) + +// Angle constraint +// C = angle2 - angle1 - referenceAngle +// Cdot = w2 - w1 +// J = [0 0 -1 0 0 1] +// K = invI1 + invI2 + +void b2WeldJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor) +{ + bodyA = bA; + bodyB = bB; + localAnchorA = bodyA->GetLocalPoint(anchor); + localAnchorB = bodyB->GetLocalPoint(anchor); + referenceAngle = bodyB->GetAngle() - bodyA->GetAngle(); +} + +b2WeldJoint::b2WeldJoint(const b2WeldJointDef* def) +: b2Joint(def) +{ + m_localAnchorA = def->localAnchorA; + m_localAnchorB = def->localAnchorB; + m_referenceAngle = def->referenceAngle; + + m_impulse.SetZero(); +} + +void b2WeldJoint::InitVelocityConstraints(const b2TimeStep& step) +{ + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + + // Compute the effective mass matrix. + b2Vec2 rA = b2Mul(bA->GetTransform().R, m_localAnchorA - bA->GetLocalCenter()); + b2Vec2 rB = b2Mul(bB->GetTransform().R, m_localAnchorB - bB->GetLocalCenter()); + + // J = [-I -r1_skew I r2_skew] + // [ 0 -1 0 1] + // r_skew = [-ry; rx] + + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] + // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] + + float32 mA = bA->m_invMass, mB = bB->m_invMass; + float32 iA = bA->m_invI, iB = bB->m_invI; + + m_mass.col1.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB; + m_mass.col2.x = -rA.y * rA.x * iA - rB.y * rB.x * iB; + m_mass.col3.x = -rA.y * iA - rB.y * iB; + m_mass.col1.y = m_mass.col2.x; + m_mass.col2.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB; + m_mass.col3.y = rA.x * iA + rB.x * iB; + m_mass.col1.z = m_mass.col3.x; + m_mass.col2.z = m_mass.col3.y; + m_mass.col3.z = iA + iB; + + if (step.warmStarting) + { + // Scale impulses to support a variable time step. + m_impulse *= step.dtRatio; + + b2Vec2 P(m_impulse.x, m_impulse.y); + + bA->m_linearVelocity -= mA * P; + bA->m_angularVelocity -= iA * (b2Cross(rA, P) + m_impulse.z); + + bB->m_linearVelocity += mB * P; + bB->m_angularVelocity += iB * (b2Cross(rB, P) + m_impulse.z); + } + else + { + m_impulse.SetZero(); + } +} + +void b2WeldJoint::SolveVelocityConstraints(const b2TimeStep& step) +{ + B2_NOT_USED(step); + + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + + b2Vec2 vA = bA->m_linearVelocity; + float32 wA = bA->m_angularVelocity; + b2Vec2 vB = bB->m_linearVelocity; + float32 wB = bB->m_angularVelocity; + + float32 mA = bA->m_invMass, mB = bB->m_invMass; + float32 iA = bA->m_invI, iB = bB->m_invI; + + b2Vec2 rA = b2Mul(bA->GetTransform().R, m_localAnchorA - bA->GetLocalCenter()); + b2Vec2 rB = b2Mul(bB->GetTransform().R, m_localAnchorB - bB->GetLocalCenter()); + + // Solve point-to-point constraint + b2Vec2 Cdot1 = vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA); + float32 Cdot2 = wB - wA; + b2Vec3 Cdot(Cdot1.x, Cdot1.y, Cdot2); + + b2Vec3 impulse = m_mass.Solve33(-Cdot); + m_impulse += impulse; + + b2Vec2 P(impulse.x, impulse.y); + + vA -= mA * P; + wA -= iA * (b2Cross(rA, P) + impulse.z); + + vB += mB * P; + wB += iB * (b2Cross(rB, P) + impulse.z); + + bA->m_linearVelocity = vA; + bA->m_angularVelocity = wA; + bB->m_linearVelocity = vB; + bB->m_angularVelocity = wB; +} + +bool b2WeldJoint::SolvePositionConstraints(float32 baumgarte) +{ + B2_NOT_USED(baumgarte); + + b2Body* bA = m_bodyA; + b2Body* bB = m_bodyB; + + float32 mA = bA->m_invMass, mB = bB->m_invMass; + float32 iA = bA->m_invI, iB = bB->m_invI; + + b2Vec2 rA = b2Mul(bA->GetTransform().R, m_localAnchorA - bA->GetLocalCenter()); + b2Vec2 rB = b2Mul(bB->GetTransform().R, m_localAnchorB - bB->GetLocalCenter()); + + b2Vec2 C1 = bB->m_sweep.c + rB - bA->m_sweep.c - rA; + float32 C2 = bB->m_sweep.a - bA->m_sweep.a - m_referenceAngle; + + // Handle large detachment. + const float32 k_allowedStretch = 10.0f * b2_linearSlop; + float32 positionError = C1.Length(); + float32 angularError = b2Abs(C2); + if (positionError > k_allowedStretch) + { + iA *= 1.0f; + iB *= 1.0f; + } + + m_mass.col1.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB; + m_mass.col2.x = -rA.y * rA.x * iA - rB.y * rB.x * iB; + m_mass.col3.x = -rA.y * iA - rB.y * iB; + m_mass.col1.y = m_mass.col2.x; + m_mass.col2.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB; + m_mass.col3.y = rA.x * iA + rB.x * iB; + m_mass.col1.z = m_mass.col3.x; + m_mass.col2.z = m_mass.col3.y; + m_mass.col3.z = iA + iB; + + b2Vec3 C(C1.x, C1.y, C2); + + b2Vec3 impulse = m_mass.Solve33(-C); + + b2Vec2 P(impulse.x, impulse.y); + + bA->m_sweep.c -= mA * P; + bA->m_sweep.a -= iA * (b2Cross(rA, P) + impulse.z); + + bB->m_sweep.c += mB * P; + bB->m_sweep.a += iB * (b2Cross(rB, P) + impulse.z); + + bA->SynchronizeTransform(); + bB->SynchronizeTransform(); + + return positionError <= b2_linearSlop && angularError <= b2_angularSlop; +} + +b2Vec2 b2WeldJoint::GetAnchorA() const +{ + return m_bodyA->GetWorldPoint(m_localAnchorA); +} + +b2Vec2 b2WeldJoint::GetAnchorB() const +{ + return m_bodyB->GetWorldPoint(m_localAnchorB); +} + +b2Vec2 b2WeldJoint::GetReactionForce(float32 inv_dt) const +{ + b2Vec2 P(m_impulse.x, m_impulse.y); + return inv_dt * P; +} + +float32 b2WeldJoint::GetReactionTorque(float32 inv_dt) const +{ + return inv_dt * m_impulse.z; +} diff --git a/AndEngine/jni/Box2D/Dynamics/Joints/b2WeldJoint.h b/AndEngine/jni/Box2D/Dynamics/Joints/b2WeldJoint.h new file mode 100644 index 0000000..a0face1 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/Joints/b2WeldJoint.h @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_WELD_JOINT_H +#define B2_WELD_JOINT_H + +#include "Box2D/Dynamics/Joints/b2Joint.h" + +/// Weld joint definition. You need to specify local anchor points +/// where they are attached and the relative body angle. The position +/// of the anchor points is important for computing the reaction torque. +struct b2WeldJointDef : public b2JointDef +{ + b2WeldJointDef() + { + type = e_weldJoint; + localAnchorA.Set(0.0f, 0.0f); + localAnchorB.Set(0.0f, 0.0f); + referenceAngle = 0.0f; + } + + /// Initialize the bodies, anchors, and reference angle using a world + /// anchor point. + void Initialize(b2Body* body1, b2Body* body2, const b2Vec2& anchor); + + /// The local anchor point relative to body1's origin. + b2Vec2 localAnchorA; + + /// The local anchor point relative to body2's origin. + b2Vec2 localAnchorB; + + /// The body2 angle minus body1 angle in the reference state (radians). + float32 referenceAngle; +}; + +/// A weld joint essentially glues two bodies together. A weld joint may +/// distort somewhat because the island constraint solver is approximate. +class b2WeldJoint : public b2Joint +{ +public: + b2Vec2 GetAnchorA() const; + b2Vec2 GetAnchorB() const; + + b2Vec2 GetReactionForce(float32 inv_dt) const; + float32 GetReactionTorque(float32 inv_dt) const; + +protected: + + friend class b2Joint; + + b2WeldJoint(const b2WeldJointDef* def); + + void InitVelocityConstraints(const b2TimeStep& step); + void SolveVelocityConstraints(const b2TimeStep& step); + + bool SolvePositionConstraints(float32 baumgarte); + + b2Vec2 m_localAnchorA; + b2Vec2 m_localAnchorB; + float32 m_referenceAngle; + + b2Vec3 m_impulse; + + b2Mat33 m_mass; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2Body.cpp b/AndEngine/jni/Box2D/Dynamics/b2Body.cpp new file mode 100644 index 0000000..729f5a6 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2Body.cpp @@ -0,0 +1,470 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2World.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/Joints/b2Joint.h" + +b2Body::b2Body(const b2BodyDef* bd, b2World* world) +{ + b2Assert(bd->position.IsValid()); + b2Assert(bd->linearVelocity.IsValid()); + b2Assert(b2IsValid(bd->angle)); + b2Assert(b2IsValid(bd->angularVelocity)); + b2Assert(b2IsValid(bd->inertiaScale) && bd->inertiaScale >= 0.0f); + b2Assert(b2IsValid(bd->angularDamping) && bd->angularDamping >= 0.0f); + b2Assert(b2IsValid(bd->linearDamping) && bd->linearDamping >= 0.0f); + + m_flags = 0; + + if (bd->bullet) + { + m_flags |= e_bulletFlag; + } + if (bd->fixedRotation) + { + m_flags |= e_fixedRotationFlag; + } + if (bd->allowSleep) + { + m_flags |= e_autoSleepFlag; + } + if (bd->awake) + { + m_flags |= e_awakeFlag; + } + if (bd->active) + { + m_flags |= e_activeFlag; + } + + m_world = world; + + m_xf.position = bd->position; + m_xf.R.Set(bd->angle); + + m_sweep.localCenter.SetZero(); + m_sweep.a0 = m_sweep.a = bd->angle; + m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); + + m_jointList = NULL; + m_contactList = NULL; + m_prev = NULL; + m_next = NULL; + + m_linearVelocity = bd->linearVelocity; + m_angularVelocity = bd->angularVelocity; + + m_linearDamping = bd->linearDamping; + m_angularDamping = bd->angularDamping; + + m_force.SetZero(); + m_torque = 0.0f; + + m_sleepTime = 0.0f; + + m_type = bd->type; + + if (m_type == b2_dynamicBody) + { + m_mass = 1.0f; + m_invMass = 1.0f; + } + else + { + m_mass = 0.0f; + m_invMass = 0.0f; + } + + m_I = 0.0f; + m_invI = 0.0f; + + m_userData = bd->userData; + + m_fixtureList = NULL; + m_fixtureCount = 0; +} + +b2Body::~b2Body() +{ + // shapes and joints are destroyed in b2World::Destroy +} + +void b2Body::SetType(b2BodyType type) +{ + if (m_type == type) + { + return; + } + + m_type = type; + + ResetMassData(); + + if (m_type == b2_staticBody) + { + m_linearVelocity.SetZero(); + m_angularVelocity = 0.0f; + } + + SetAwake(true); + + m_force.SetZero(); + m_torque = 0.0f; + + // Since the body type changed, we need to flag contacts for filtering. + for (b2ContactEdge* ce = m_contactList; ce; ce = ce->next) + { + ce->contact->FlagForFiltering(); + } +} + +b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def) +{ + b2Assert(m_world->IsLocked() == false); + if (m_world->IsLocked() == true) + { + return NULL; + } + + b2BlockAllocator* allocator = &m_world->m_blockAllocator; + + void* memory = allocator->Allocate(sizeof(b2Fixture)); + b2Fixture* fixture = new (memory) b2Fixture; + fixture->Create(allocator, this, def); + + if (m_flags & e_activeFlag) + { + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; + fixture->CreateProxy(broadPhase, m_xf); + } + + fixture->m_next = m_fixtureList; + m_fixtureList = fixture; + ++m_fixtureCount; + + fixture->m_body = this; + + // Adjust mass properties if needed. + if (fixture->m_density > 0.0f) + { + ResetMassData(); + } + + // Let the world know we have a new fixture. This will cause new contacts + // to be created at the beginning of the next time step. + m_world->m_flags |= b2World::e_newFixture; + + return fixture; +} + +b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density) +{ + b2FixtureDef def; + def.shape = shape; + def.density = density; + + return CreateFixture(&def); +} + +void b2Body::DestroyFixture(b2Fixture* fixture) +{ + b2Assert(m_world->IsLocked() == false); + if (m_world->IsLocked() == true) + { + return; + } + + b2Assert(fixture->m_body == this); + + // Remove the fixture from this body's singly linked list. + b2Assert(m_fixtureCount > 0); + b2Fixture** node = &m_fixtureList; + bool found = false; + while (*node != NULL) + { + if (*node == fixture) + { + *node = fixture->m_next; + found = true; + break; + } + + node = &(*node)->m_next; + } + + // You tried to remove a shape that is not attached to this body. + b2Assert(found); + + // Destroy any contacts associated with the fixture. + b2ContactEdge* edge = m_contactList; + while (edge) + { + b2Contact* c = edge->contact; + edge = edge->next; + + b2Fixture* fixtureA = c->GetFixtureA(); + b2Fixture* fixtureB = c->GetFixtureB(); + + if (fixture == fixtureA || fixture == fixtureB) + { + // This destroys the contact and removes it from + // this body's contact list. + m_world->m_contactManager.Destroy(c); + } + } + + b2BlockAllocator* allocator = &m_world->m_blockAllocator; + + if (m_flags & e_activeFlag) + { + b2Assert(fixture->m_proxyId != b2BroadPhase::e_nullProxy); + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; + fixture->DestroyProxy(broadPhase); + } + else + { + b2Assert(fixture->m_proxyId == b2BroadPhase::e_nullProxy); + } + + fixture->Destroy(allocator); + fixture->m_body = NULL; + fixture->m_next = NULL; + fixture->~b2Fixture(); + allocator->Free(fixture, sizeof(b2Fixture)); + + --m_fixtureCount; + + // Reset the mass data. + ResetMassData(); +} + +void b2Body::ResetMassData() +{ + // Compute mass data from shapes. Each shape has its own density. + m_mass = 0.0f; + m_invMass = 0.0f; + m_I = 0.0f; + m_invI = 0.0f; + m_sweep.localCenter.SetZero(); + + // Static and kinematic bodies have zero mass. + if (m_type == b2_staticBody || m_type == b2_kinematicBody) + { + m_sweep.c0 = m_sweep.c = m_xf.position; + return; + } + + b2Assert(m_type == b2_dynamicBody); + + // Accumulate mass over all fixtures. + b2Vec2 center = b2Vec2_zero; + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + if (f->m_density == 0.0f) + { + continue; + } + + b2MassData massData; + f->GetMassData(&massData); + m_mass += massData.mass; + center += massData.mass * massData.center; + m_I += massData.I; + } + + // Compute center of mass. + if (m_mass > 0.0f) + { + m_invMass = 1.0f / m_mass; + center *= m_invMass; + } + else + { + // Force all dynamic bodies to have a positive mass. + m_mass = 1.0f; + m_invMass = 1.0f; + } + + if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) + { + // Center the inertia about the center of mass. + m_I -= m_mass * b2Dot(center, center); + b2Assert(m_I > 0.0f); + m_invI = 1.0f / m_I; + + } + else + { + m_I = 0.0f; + m_invI = 0.0f; + } + + // Move center of mass. + b2Vec2 oldCenter = m_sweep.c; + m_sweep.localCenter = center; + m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); + + // Update center of mass velocity. + m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter); +} + +void b2Body::SetMassData(const b2MassData* massData) +{ + b2Assert(m_world->IsLocked() == false); + if (m_world->IsLocked() == true) + { + return; + } + + if (m_type != b2_dynamicBody) + { + return; + } + + m_invMass = 0.0f; + m_I = 0.0f; + m_invI = 0.0f; + + m_mass = massData->mass; + if (m_mass <= 0.0f) + { + m_mass = 1.0f; + } + + m_invMass = 1.0f / m_mass; + + if (massData->I > 0.0f && (m_flags & b2Body::e_fixedRotationFlag) == 0) + { + m_I = massData->I - m_mass * b2Dot(massData->center, massData->center); + b2Assert(m_I > 0.0f); + m_invI = 1.0f / m_I; + } + + // Move center of mass. + b2Vec2 oldCenter = m_sweep.c; + m_sweep.localCenter = massData->center; + m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); + + // Update center of mass velocity. + m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter); +} + +bool b2Body::ShouldCollide(const b2Body* other) const +{ + // At least one body should be dynamic. + if (m_type != b2_dynamicBody && other->m_type != b2_dynamicBody) + { + return false; + } + + // Does a joint prevent collision? + for (b2JointEdge* jn = m_jointList; jn; jn = jn->next) + { + if (jn->other == other) + { + if (jn->joint->m_collideConnected == false) + { + return false; + } + } + } + + return true; +} + +void b2Body::SetTransform(const b2Vec2& position, float32 angle) +{ + b2Assert(m_world->IsLocked() == false); + if (m_world->IsLocked() == true) + { + return; + } + + m_xf.R.Set(angle); + m_xf.position = position; + + m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter); + m_sweep.a0 = m_sweep.a = angle; + + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + f->Synchronize(broadPhase, m_xf, m_xf); + } + + m_world->m_contactManager.FindNewContacts(); +} + +void b2Body::SynchronizeFixtures() +{ + b2Transform xf1; + xf1.R.Set(m_sweep.a0); + xf1.position = m_sweep.c0 - b2Mul(xf1.R, m_sweep.localCenter); + + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + f->Synchronize(broadPhase, xf1, m_xf); + } +} + +void b2Body::SetActive(bool flag) +{ + if (flag == IsActive()) + { + return; + } + + if (flag) + { + m_flags |= e_activeFlag; + + // Create all proxies. + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + f->CreateProxy(broadPhase, m_xf); + } + + // Contacts are created the next time step. + } + else + { + m_flags &= ~e_activeFlag; + + // Destroy all proxies. + b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; + for (b2Fixture* f = m_fixtureList; f; f = f->m_next) + { + f->DestroyProxy(broadPhase); + } + + // Destroy the attached contacts. + b2ContactEdge* ce = m_contactList; + while (ce) + { + b2ContactEdge* ce0 = ce; + ce = ce->next; + m_world->m_contactManager.Destroy(ce0->contact); + } + m_contactList = NULL; + } +} diff --git a/AndEngine/jni/Box2D/Dynamics/b2Body.h b/AndEngine/jni/Box2D/Dynamics/b2Body.h new file mode 100644 index 0000000..dce75a5 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2Body.h @@ -0,0 +1,802 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_BODY_H +#define B2_BODY_H + +#include "Box2D/Common/b2Math.h" +#include "Box2D/Collision/Shapes/b2Shape.h" +#include + +class b2Fixture; +class b2Joint; +class b2Contact; +class b2Controller; +class b2World; +struct b2FixtureDef; +struct b2JointEdge; +struct b2ContactEdge; + +/// The body type. +/// static: zero mass, zero velocity, may be manually moved +/// kinematic: zero mass, non-zero velocity set by user, moved by solver +/// dynamic: positive mass, non-zero velocity determined by forces, moved by solver +enum b2BodyType +{ + b2_staticBody = 0, + b2_kinematicBody, + b2_dynamicBody, +}; + +/// A body definition holds all the data needed to construct a rigid body. +/// You can safely re-use body definitions. Shapes are added to a body after construction. +struct b2BodyDef +{ + /// This constructor sets the body definition default values. + b2BodyDef() + { + userData = NULL; + position.Set(0.0f, 0.0f); + angle = 0.0f; + linearVelocity.Set(0.0f, 0.0f); + angularVelocity = 0.0f; + linearDamping = 0.0f; + angularDamping = 0.0f; + allowSleep = true; + awake = true; + fixedRotation = false; + bullet = false; + type = b2_staticBody; + active = true; + inertiaScale = 1.0f; + } + + /// The body type: static, kinematic, or dynamic. + /// Note: if a dynamic body would have zero mass, the mass is set to one. + b2BodyType type; + + /// The world position of the body. Avoid creating bodies at the origin + /// since this can lead to many overlapping shapes. + b2Vec2 position; + + /// The world angle of the body in radians. + float32 angle; + + /// The linear velocity of the body's origin in world co-ordinates. + b2Vec2 linearVelocity; + + /// The angular velocity of the body. + float32 angularVelocity; + + /// Linear damping is use to reduce the linear velocity. The damping parameter + /// can be larger than 1.0f but the damping effect becomes sensitive to the + /// time step when the damping parameter is large. + float32 linearDamping; + + /// Angular damping is use to reduce the angular velocity. The damping parameter + /// can be larger than 1.0f but the damping effect becomes sensitive to the + /// time step when the damping parameter is large. + float32 angularDamping; + + /// Set this flag to false if this body should never fall asleep. Note that + /// this increases CPU usage. + bool allowSleep; + + /// Is this body initially awake or sleeping? + bool awake; + + /// Should this body be prevented from rotating? Useful for characters. + bool fixedRotation; + + /// Is this a fast moving body that should be prevented from tunneling through + /// other moving bodies? Note that all bodies are prevented from tunneling through + /// kinematic and static bodies. This setting is only considered on dynamic bodies. + /// @warning You should use this flag sparingly since it increases processing time. + bool bullet; + + /// Does this body start out active? + bool active; + + /// Use this to store application specific body data. + void* userData; + + /// Experimental: scales the inertia tensor. + float32 inertiaScale; +}; + +/// A rigid body. These are created via b2World::CreateBody. +class b2Body +{ +public: + /// Creates a fixture and attach it to this body. Use this function if you need + /// to set some fixture parameters, like friction. Otherwise you can create the + /// fixture directly from a shape. + /// If the density is non-zero, this function automatically updates the mass of the body. + /// Contacts are not created until the next time step. + /// @param def the fixture definition. + /// @warning This function is locked during callbacks. + b2Fixture* CreateFixture(const b2FixtureDef* def); + + /// Creates a fixture from a shape and attach it to this body. + /// This is a convenience function. Use b2FixtureDef if you need to set parameters + /// like friction, restitution, user data, or filtering. + /// If the density is non-zero, this function automatically updates the mass of the body. + /// @param shape the shape to be cloned. + /// @param density the shape density (set to zero for static bodies). + /// @warning This function is locked during callbacks. + b2Fixture* CreateFixture(const b2Shape* shape, float32 density); + + /// Destroy a fixture. This removes the fixture from the broad-phase and + /// destroys all contacts associated with this fixture. This will + /// automatically adjust the mass of the body if the body is dynamic and the + /// fixture has positive density. + /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. + /// @param fixture the fixture to be removed. + /// @warning This function is locked during callbacks. + void DestroyFixture(b2Fixture* fixture); + + /// Set the position of the body's origin and rotation. + /// This breaks any contacts and wakes the other bodies. + /// Manipulating a body's transform may cause non-physical behavior. + /// @param position the world position of the body's local origin. + /// @param angle the world rotation in radians. + void SetTransform(const b2Vec2& position, float32 angle); + + /// Get the body transform for the body's origin. + /// @return the world transform of the body's origin. + const b2Transform& GetTransform() const; + + /// Get the world body origin position. + /// @return the world position of the body's origin. + const b2Vec2& GetPosition() const; + + /// Get the angle in radians. + /// @return the current world rotation angle in radians. + float32 GetAngle() const; + + /// Get the world position of the center of mass. + const b2Vec2& GetWorldCenter() const; + + /// Get the local position of the center of mass. + const b2Vec2& GetLocalCenter() const; + + /// Set the linear velocity of the center of mass. + /// @param v the new linear velocity of the center of mass. + void SetLinearVelocity(const b2Vec2& v); + + /// Get the linear velocity of the center of mass. + /// @return the linear velocity of the center of mass. + b2Vec2 GetLinearVelocity() const; + + /// Set the angular velocity. + /// @param omega the new angular velocity in radians/second. + void SetAngularVelocity(float32 omega); + + /// Get the angular velocity. + /// @return the angular velocity in radians/second. + float32 GetAngularVelocity() const; + + /// Apply a force at a world point. If the force is not + /// applied at the center of mass, it will generate a torque and + /// affect the angular velocity. This wakes up the body. + /// @param force the world force vector, usually in Newtons (N). + /// @param point the world position of the point of application. + void ApplyForce(const b2Vec2& force, const b2Vec2& point); + + /// Apply a torque. This affects the angular velocity + /// without affecting the linear velocity of the center of mass. + /// This wakes up the body. + /// @param torque about the z-axis (out of the screen), usually in N-m. + void ApplyTorque(float32 torque); + + /// Apply an impulse at a point. This immediately modifies the velocity. + /// It also modifies the angular velocity if the point of application + /// is not at the center of mass. This wakes up the body. + /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. + /// @param point the world position of the point of application. + void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point); + + /// Apply an angular impulse. + /// @param impulse the angular impulse in units of kg*m*m/s + void ApplyAngularImpulse(float32 impulse); + + /// Get the total mass of the body. + /// @return the mass, usually in kilograms (kg). + float32 GetMass() const; + + /// Get the rotational inertia of the body about the local origin. + /// @return the rotational inertia, usually in kg-m^2. + float32 GetInertia() const; + + /// Get the mass data of the body. + /// @return a struct containing the mass, inertia and center of the body. + void GetMassData(b2MassData* data) const; + + /// Set the mass properties to override the mass properties of the fixtures. + /// Note that this changes the center of mass position. + /// Note that creating or destroying fixtures can also alter the mass. + /// This function has no effect if the body isn't dynamic. + /// @param massData the mass properties. + void SetMassData(const b2MassData* data); + + /// This resets the mass properties to the sum of the mass properties of the fixtures. + /// This normally does not need to be called unless you called SetMassData to override + /// the mass and you later want to reset the mass. + void ResetMassData(); + + /// Get the world coordinates of a point given the local coordinates. + /// @param localPoint a point on the body measured relative the the body's origin. + /// @return the same point expressed in world coordinates. + b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const; + + /// Get the world coordinates of a vector given the local coordinates. + /// @param localVector a vector fixed in the body. + /// @return the same vector expressed in world coordinates. + b2Vec2 GetWorldVector(const b2Vec2& localVector) const; + + /// Gets a local point relative to the body's origin given a world point. + /// @param a point in world coordinates. + /// @return the corresponding local point relative to the body's origin. + b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const; + + /// Gets a local vector given a world vector. + /// @param a vector in world coordinates. + /// @return the corresponding local vector. + b2Vec2 GetLocalVector(const b2Vec2& worldVector) const; + + /// Get the world linear velocity of a world point attached to this body. + /// @param a point in world coordinates. + /// @return the world velocity of a point. + b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const; + + /// Get the world velocity of a local point. + /// @param a point in local coordinates. + /// @return the world velocity of a point. + b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const; + + /// Get the linear damping of the body. + float32 GetLinearDamping() const; + + /// Set the linear damping of the body. + void SetLinearDamping(float32 linearDamping); + + /// Get the angular damping of the body. + float32 GetAngularDamping() const; + + /// Set the angular damping of the body. + void SetAngularDamping(float32 angularDamping); + + /// Set the type of this body. This may alter the mass and velocity. + void SetType(b2BodyType type); + + /// Get the type of this body. + b2BodyType GetType() const; + + /// Should this body be treated like a bullet for continuous collision detection? + void SetBullet(bool flag); + + /// Is this body treated like a bullet for continuous collision detection? + bool IsBullet() const; + + /// You can disable sleeping on this body. If you disable sleeping, the + /// body will be woken. + void SetSleepingAllowed(bool flag); + + /// Is this body allowed to sleep + bool IsSleepingAllowed() const; + + /// Set the sleep state of the body. A sleeping body has very + /// low CPU cost. + /// @param flag set to true to put body to sleep, false to wake it. + void SetAwake(bool flag); + + /// Get the sleeping state of this body. + /// @return true if the body is sleeping. + bool IsAwake() const; + + /// Set the active state of the body. An inactive body is not + /// simulated and cannot be collided with or woken up. + /// If you pass a flag of true, all fixtures will be added to the + /// broad-phase. + /// If you pass a flag of false, all fixtures will be removed from + /// the broad-phase and all contacts will be destroyed. + /// Fixtures and joints are otherwise unaffected. You may continue + /// to create/destroy fixtures and joints on inactive bodies. + /// Fixtures on an inactive body are implicitly inactive and will + /// not participate in collisions, ray-casts, or queries. + /// Joints connected to an inactive body are implicitly inactive. + /// An inactive body is still owned by a b2World object and remains + /// in the body list. + void SetActive(bool flag); + + /// Get the active state of the body. + bool IsActive() const; + + /// Set this body to have fixed rotation. This causes the mass + /// to be reset. + void SetFixedRotation(bool flag); + + /// Does this body have fixed rotation? + bool IsFixedRotation() const; + + /// Get the list of all fixtures attached to this body. + b2Fixture* GetFixtureList(); + const b2Fixture* GetFixtureList() const; + + /// Get the list of all joints attached to this body. + b2JointEdge* GetJointList(); + const b2JointEdge* GetJointList() const; + + /// Get the list of all contacts attached to this body. + /// @warning this list changes during the time step and you may + /// miss some collisions if you don't use b2ContactListener. + b2ContactEdge* GetContactList(); + const b2ContactEdge* GetContactList() const; + + /// Get the next body in the world's body list. + b2Body* GetNext(); + const b2Body* GetNext() const; + + /// Get the user data pointer that was provided in the body definition. + void* GetUserData() const; + + /// Set the user data. Use this to store your application specific data. + void SetUserData(void* data); + + /// Get the parent world of this body. + b2World* GetWorld(); + const b2World* GetWorld() const; + +private: + + friend class b2World; + friend class b2Island; + friend class b2ContactManager; + friend class b2ContactSolver; + friend class b2TOISolver; + + friend class b2DistanceJoint; + friend class b2GearJoint; + friend class b2LineJoint; + friend class b2MouseJoint; + friend class b2PrismaticJoint; + friend class b2PulleyJoint; + friend class b2RevoluteJoint; + friend class b2WeldJoint; + friend class b2FrictionJoint; + + // m_flags + enum + { + e_islandFlag = 0x0001, + e_awakeFlag = 0x0002, + e_autoSleepFlag = 0x0004, + e_bulletFlag = 0x0008, + e_fixedRotationFlag = 0x0010, + e_activeFlag = 0x0020, + e_toiFlag = 0x0040, + }; + + b2Body(const b2BodyDef* bd, b2World* world); + ~b2Body(); + + void SynchronizeFixtures(); + void SynchronizeTransform(); + + // This is used to prevent connected bodies from colliding. + // It may lie, depending on the collideConnected flag. + bool ShouldCollide(const b2Body* other) const; + + void Advance(float32 t); + + b2BodyType m_type; + + uint16 m_flags; + + int32 m_islandIndex; + + b2Transform m_xf; // the body origin transform + b2Sweep m_sweep; // the swept motion for CCD + + b2Vec2 m_linearVelocity; + float32 m_angularVelocity; + + b2Vec2 m_force; + float32 m_torque; + + b2World* m_world; + b2Body* m_prev; + b2Body* m_next; + + b2Fixture* m_fixtureList; + int32 m_fixtureCount; + + b2JointEdge* m_jointList; + b2ContactEdge* m_contactList; + + float32 m_mass, m_invMass; + + // Rotational inertia about the center of mass. + float32 m_I, m_invI; + + float32 m_linearDamping; + float32 m_angularDamping; + + float32 m_sleepTime; + + void* m_userData; +}; + +inline b2BodyType b2Body::GetType() const +{ + return m_type; +} + +inline const b2Transform& b2Body::GetTransform() const +{ + return m_xf; +} + +inline const b2Vec2& b2Body::GetPosition() const +{ + return m_xf.position; +} + +inline float32 b2Body::GetAngle() const +{ + return m_sweep.a; +} + +inline const b2Vec2& b2Body::GetWorldCenter() const +{ + return m_sweep.c; +} + +inline const b2Vec2& b2Body::GetLocalCenter() const +{ + return m_sweep.localCenter; +} + +inline void b2Body::SetLinearVelocity(const b2Vec2& v) +{ + if (m_type == b2_staticBody) + { + return; + } + + if (b2Dot(v,v) > 0.0f) + { + SetAwake(true); + } + + m_linearVelocity = v; +} + +inline b2Vec2 b2Body::GetLinearVelocity() const +{ + return m_linearVelocity; +} + +inline void b2Body::SetAngularVelocity(float32 w) +{ + if (m_type == b2_staticBody) + { + return; + } + + if (w * w > 0.0f) + { + SetAwake(true); + } + + m_angularVelocity = w; +} + +inline float32 b2Body::GetAngularVelocity() const +{ + return m_angularVelocity; +} + +inline float32 b2Body::GetMass() const +{ + return m_mass; +} + +inline float32 b2Body::GetInertia() const +{ + return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); +} + +inline void b2Body::GetMassData(b2MassData* data) const +{ + data->mass = m_mass; + data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); + data->center = m_sweep.localCenter; +} + +inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const +{ + return b2Mul(m_xf, localPoint); +} + +inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const +{ + return b2Mul(m_xf.R, localVector); +} + +inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const +{ + return b2MulT(m_xf, worldPoint); +} + +inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const +{ + return b2MulT(m_xf.R, worldVector); +} + +inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const +{ + return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c); +} + +inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const +{ + return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint)); +} + +inline float32 b2Body::GetLinearDamping() const +{ + return m_linearDamping; +} + +inline void b2Body::SetLinearDamping(float32 linearDamping) +{ + m_linearDamping = linearDamping; +} + +inline float32 b2Body::GetAngularDamping() const +{ + return m_angularDamping; +} + +inline void b2Body::SetAngularDamping(float32 angularDamping) +{ + m_angularDamping = angularDamping; +} + +inline void b2Body::SetBullet(bool flag) +{ + if (flag) + { + m_flags |= e_bulletFlag; + } + else + { + m_flags &= ~e_bulletFlag; + } +} + +inline bool b2Body::IsBullet() const +{ + return (m_flags & e_bulletFlag) == e_bulletFlag; +} + +inline void b2Body::SetAwake(bool flag) +{ + if (flag) + { + if ((m_flags & e_awakeFlag) == 0) + { + m_flags |= e_awakeFlag; + m_sleepTime = 0.0f; + } + } + else + { + m_flags &= ~e_awakeFlag; + m_sleepTime = 0.0f; + m_linearVelocity.SetZero(); + m_angularVelocity = 0.0f; + m_force.SetZero(); + m_torque = 0.0f; + } +} + +inline bool b2Body::IsAwake() const +{ + return (m_flags & e_awakeFlag) == e_awakeFlag; +} + +inline bool b2Body::IsActive() const +{ + return (m_flags & e_activeFlag) == e_activeFlag; +} + +inline void b2Body::SetFixedRotation(bool flag) +{ + if (flag) + { + m_flags |= e_fixedRotationFlag; + } + else + { + m_flags &= ~e_fixedRotationFlag; + } + + ResetMassData(); +} + +inline bool b2Body::IsFixedRotation() const +{ + return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; +} + +inline void b2Body::SetSleepingAllowed(bool flag) +{ + if (flag) + { + m_flags |= e_autoSleepFlag; + } + else + { + m_flags &= ~e_autoSleepFlag; + SetAwake(true); + } +} + +inline bool b2Body::IsSleepingAllowed() const +{ + return (m_flags & e_autoSleepFlag) == e_autoSleepFlag; +} + +inline b2Fixture* b2Body::GetFixtureList() +{ + return m_fixtureList; +} + +inline const b2Fixture* b2Body::GetFixtureList() const +{ + return m_fixtureList; +} + +inline b2JointEdge* b2Body::GetJointList() +{ + return m_jointList; +} + +inline const b2JointEdge* b2Body::GetJointList() const +{ + return m_jointList; +} + +inline b2ContactEdge* b2Body::GetContactList() +{ + return m_contactList; +} + +inline const b2ContactEdge* b2Body::GetContactList() const +{ + return m_contactList; +} + +inline b2Body* b2Body::GetNext() +{ + return m_next; +} + +inline const b2Body* b2Body::GetNext() const +{ + return m_next; +} + +inline void b2Body::SetUserData(void* data) +{ + m_userData = data; +} + +inline void* b2Body::GetUserData() const +{ + return m_userData; +} + +inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point) +{ + if (m_type != b2_dynamicBody) + { + return; + } + + if (IsAwake() == false) + { + SetAwake(true); + } + + m_force += force; + m_torque += b2Cross(point - m_sweep.c, force); +} + +inline void b2Body::ApplyTorque(float32 torque) +{ + if (m_type != b2_dynamicBody) + { + return; + } + + if (IsAwake() == false) + { + SetAwake(true); + } + + m_torque += torque; +} + +inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point) +{ + if (m_type != b2_dynamicBody) + { + return; + } + + if (IsAwake() == false) + { + SetAwake(true); + } + m_linearVelocity += m_invMass * impulse; + m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse); +} + +inline void b2Body::ApplyAngularImpulse(float32 impulse) +{ + if (m_type != b2_dynamicBody) + { + return; + } + + if (IsAwake() == false) + { + SetAwake(true); + } + m_angularVelocity += m_invI * impulse; +} + +inline void b2Body::SynchronizeTransform() +{ + m_xf.R.Set(m_sweep.a); + m_xf.position = m_sweep.c - b2Mul(m_xf.R, m_sweep.localCenter); +} + +inline void b2Body::Advance(float32 t) +{ + // Advance to the new safe time. + m_sweep.Advance(t); + m_sweep.c = m_sweep.c0; + m_sweep.a = m_sweep.a0; + SynchronizeTransform(); +} + +inline b2World* b2Body::GetWorld() +{ + return m_world; +} + +inline const b2World* b2Body::GetWorld() const +{ + return m_world; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2ContactManager.cpp b/AndEngine/jni/Box2D/Dynamics/b2ContactManager.cpp new file mode 100644 index 0000000..7ebe11e --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2ContactManager.cpp @@ -0,0 +1,266 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/b2ContactManager.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2WorldCallbacks.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" + +b2ContactFilter b2_defaultFilter; +b2ContactListener b2_defaultListener; + +b2ContactManager::b2ContactManager() +{ + m_contactList = NULL; + m_contactCount = 0; + m_contactFilter = &b2_defaultFilter; + m_contactListener = &b2_defaultListener; + m_allocator = NULL; +} + +void b2ContactManager::Destroy(b2Contact* c) +{ + b2Fixture* fixtureA = c->GetFixtureA(); + b2Fixture* fixtureB = c->GetFixtureB(); + b2Body* bodyA = fixtureA->GetBody(); + b2Body* bodyB = fixtureB->GetBody(); + + if (m_contactListener && c->IsTouching()) + { + m_contactListener->EndContact(c); + } + + // Remove from the world. + if (c->m_prev) + { + c->m_prev->m_next = c->m_next; + } + + if (c->m_next) + { + c->m_next->m_prev = c->m_prev; + } + + if (c == m_contactList) + { + m_contactList = c->m_next; + } + + // Remove from body 1 + if (c->m_nodeA.prev) + { + c->m_nodeA.prev->next = c->m_nodeA.next; + } + + if (c->m_nodeA.next) + { + c->m_nodeA.next->prev = c->m_nodeA.prev; + } + + if (&c->m_nodeA == bodyA->m_contactList) + { + bodyA->m_contactList = c->m_nodeA.next; + } + + // Remove from body 2 + if (c->m_nodeB.prev) + { + c->m_nodeB.prev->next = c->m_nodeB.next; + } + + if (c->m_nodeB.next) + { + c->m_nodeB.next->prev = c->m_nodeB.prev; + } + + if (&c->m_nodeB == bodyB->m_contactList) + { + bodyB->m_contactList = c->m_nodeB.next; + } + + // Call the factory. + b2Contact::Destroy(c, m_allocator); + --m_contactCount; +} + +// This is the top level collision call for the time step. Here +// all the narrow phase collision is processed for the world +// contact list. +void b2ContactManager::Collide() +{ + // Update awake contacts. + b2Contact* c = m_contactList; + while (c) + { + b2Fixture* fixtureA = c->GetFixtureA(); + b2Fixture* fixtureB = c->GetFixtureB(); + b2Body* bodyA = fixtureA->GetBody(); + b2Body* bodyB = fixtureB->GetBody(); + + if (bodyA->IsAwake() == false && bodyB->IsAwake() == false) + { + c = c->GetNext(); + continue; + } + + // Is this contact flagged for filtering? + if (c->m_flags & b2Contact::e_filterFlag) + { + // Should these bodies collide? + if (bodyB->ShouldCollide(bodyA) == false) + { + b2Contact* cNuke = c; + c = cNuke->GetNext(); + Destroy(cNuke); + continue; + } + + // Check user filtering. + if (m_contactFilter && m_contactFilter->ShouldCollide(fixtureA, fixtureB) == false) + { + b2Contact* cNuke = c; + c = cNuke->GetNext(); + Destroy(cNuke); + continue; + } + + // Clear the filtering flag. + c->m_flags &= ~b2Contact::e_filterFlag; + } + + int32 proxyIdA = fixtureA->m_proxyId; + int32 proxyIdB = fixtureB->m_proxyId; + bool overlap = m_broadPhase.TestOverlap(proxyIdA, proxyIdB); + + // Here we destroy contacts that cease to overlap in the broad-phase. + if (overlap == false) + { + b2Contact* cNuke = c; + c = cNuke->GetNext(); + Destroy(cNuke); + continue; + } + + // The contact persists. + c->Update(m_contactListener); + c = c->GetNext(); + } +} + +void b2ContactManager::FindNewContacts() +{ + m_broadPhase.UpdatePairs(this); +} + +void b2ContactManager::AddPair(void* proxyUserDataA, void* proxyUserDataB) +{ + b2Fixture* fixtureA = (b2Fixture*)proxyUserDataA; + b2Fixture* fixtureB = (b2Fixture*)proxyUserDataB; + + b2Body* bodyA = fixtureA->GetBody(); + b2Body* bodyB = fixtureB->GetBody(); + + // Are the fixtures on the same body? + if (bodyA == bodyB) + { + return; + } + + // Does a contact already exist? + b2ContactEdge* edge = bodyB->GetContactList(); + while (edge) + { + if (edge->other == bodyA) + { + b2Fixture* fA = edge->contact->GetFixtureA(); + b2Fixture* fB = edge->contact->GetFixtureB(); + if (fA == fixtureA && fB == fixtureB) + { + // A contact already exists. + return; + } + + if (fA == fixtureB && fB == fixtureA) + { + // A contact already exists. + return; + } + } + + edge = edge->next; + } + + // Does a joint override collision? Is at least one body dynamic? + if (bodyB->ShouldCollide(bodyA) == false) + { + return; + } + + // Check user filtering. + if (m_contactFilter && m_contactFilter->ShouldCollide(fixtureA, fixtureB) == false) + { + return; + } + + // Call the factory. + b2Contact* c = b2Contact::Create(fixtureA, fixtureB, m_allocator); + + // Contact creation may swap fixtures. + fixtureA = c->GetFixtureA(); + fixtureB = c->GetFixtureB(); + bodyA = fixtureA->GetBody(); + bodyB = fixtureB->GetBody(); + + // Insert into the world. + c->m_prev = NULL; + c->m_next = m_contactList; + if (m_contactList != NULL) + { + m_contactList->m_prev = c; + } + m_contactList = c; + + // Connect to island graph. + + // Connect to body A + c->m_nodeA.contact = c; + c->m_nodeA.other = bodyB; + + c->m_nodeA.prev = NULL; + c->m_nodeA.next = bodyA->m_contactList; + if (bodyA->m_contactList != NULL) + { + bodyA->m_contactList->prev = &c->m_nodeA; + } + bodyA->m_contactList = &c->m_nodeA; + + // Connect to body B + c->m_nodeB.contact = c; + c->m_nodeB.other = bodyA; + + c->m_nodeB.prev = NULL; + c->m_nodeB.next = bodyB->m_contactList; + if (bodyB->m_contactList != NULL) + { + bodyB->m_contactList->prev = &c->m_nodeB; + } + bodyB->m_contactList = &c->m_nodeB; + + ++m_contactCount; +} diff --git a/AndEngine/jni/Box2D/Dynamics/b2ContactManager.h b/AndEngine/jni/Box2D/Dynamics/b2ContactManager.h new file mode 100644 index 0000000..54ed85f --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2ContactManager.h @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_CONTACT_MANAGER_H +#define B2_CONTACT_MANAGER_H + +#include "Box2D/Collision/b2BroadPhase.h" + +class b2Contact; +class b2ContactFilter; +class b2ContactListener; +class b2BlockAllocator; + +// Delegate of b2World. +class b2ContactManager +{ +public: + b2ContactManager(); + + // Broad-phase callback. + void AddPair(void* proxyUserDataA, void* proxyUserDataB); + + void FindNewContacts(); + + void Destroy(b2Contact* c); + + void Collide(); + + b2BroadPhase m_broadPhase; + b2Contact* m_contactList; + int32 m_contactCount; + b2ContactFilter* m_contactFilter; + b2ContactListener* m_contactListener; + b2BlockAllocator* m_allocator; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2Fixture.cpp b/AndEngine/jni/Box2D/Dynamics/b2Fixture.cpp new file mode 100644 index 0000000..ec22469 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2Fixture.cpp @@ -0,0 +1,163 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" +#include "Box2D/Collision/b2BroadPhase.h" +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Common/b2BlockAllocator.h" + + +b2Fixture::b2Fixture() +{ + m_userData = NULL; + m_body = NULL; + m_next = NULL; + m_proxyId = b2BroadPhase::e_nullProxy; + m_shape = NULL; + m_density = 0.0f; +} + +b2Fixture::~b2Fixture() +{ + b2Assert(m_shape == NULL); + b2Assert(m_proxyId == b2BroadPhase::e_nullProxy); +} + +void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def) +{ + m_userData = def->userData; + m_friction = def->friction; + m_restitution = def->restitution; + + m_body = body; + m_next = NULL; + + m_filter = def->filter; + + m_isSensor = def->isSensor; + + m_shape = def->shape->Clone(allocator); + + m_density = def->density; +} + +void b2Fixture::Destroy(b2BlockAllocator* allocator) +{ + // The proxy must be destroyed before calling this. + b2Assert(m_proxyId == b2BroadPhase::e_nullProxy); + + // Free the child shape. + switch (m_shape->m_type) + { + case b2Shape::e_circle: + { + b2CircleShape* s = (b2CircleShape*)m_shape; + s->~b2CircleShape(); + allocator->Free(s, sizeof(b2CircleShape)); + } + break; + + case b2Shape::e_polygon: + { + b2PolygonShape* s = (b2PolygonShape*)m_shape; + s->~b2PolygonShape(); + allocator->Free(s, sizeof(b2PolygonShape)); + } + break; + + default: + b2Assert(false); + break; + } + + m_shape = NULL; +} + +void b2Fixture::CreateProxy(b2BroadPhase* broadPhase, const b2Transform& xf) +{ + b2Assert(m_proxyId == b2BroadPhase::e_nullProxy); + + // Create proxy in the broad-phase. + m_shape->ComputeAABB(&m_aabb, xf); + m_proxyId = broadPhase->CreateProxy(m_aabb, this); +} + +void b2Fixture::DestroyProxy(b2BroadPhase* broadPhase) +{ + if (m_proxyId == b2BroadPhase::e_nullProxy) + { + return; + } + + // Destroy proxy in the broad-phase. + broadPhase->DestroyProxy(m_proxyId); + m_proxyId = b2BroadPhase::e_nullProxy; +} + +void b2Fixture::Synchronize(b2BroadPhase* broadPhase, const b2Transform& transform1, const b2Transform& transform2) +{ + if (m_proxyId == b2BroadPhase::e_nullProxy) + { + return; + } + + // Compute an AABB that covers the swept shape (may miss some rotation effect). + b2AABB aabb1, aabb2; + m_shape->ComputeAABB(&aabb1, transform1); + m_shape->ComputeAABB(&aabb2, transform2); + + m_aabb.Combine(aabb1, aabb2); + + b2Vec2 displacement = transform2.position - transform1.position; + + broadPhase->MoveProxy(m_proxyId, m_aabb, displacement); +} + +void b2Fixture::SetFilterData(const b2Filter& filter) +{ + m_filter = filter; + + if (m_body == NULL) + { + return; + } + + // Flag associated contacts for filtering. + b2ContactEdge* edge = m_body->GetContactList(); + while (edge) + { + b2Contact* contact = edge->contact; + b2Fixture* fixtureA = contact->GetFixtureA(); + b2Fixture* fixtureB = contact->GetFixtureB(); + if (fixtureA == this || fixtureB == this) + { + contact->FlagForFiltering(); + } + + edge = edge->next; + } +} + +void b2Fixture::SetSensor(bool sensor) +{ + m_isSensor = sensor; +} + diff --git a/AndEngine/jni/Box2D/Dynamics/b2Fixture.h b/AndEngine/jni/Box2D/Dynamics/b2Fixture.h new file mode 100644 index 0000000..dc8ac4e --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2Fixture.h @@ -0,0 +1,326 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_FIXTURE_H +#define B2_FIXTURE_H + +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/Shapes/b2Shape.h" + +class b2BlockAllocator; +class b2Body; +class b2BroadPhase; + +/// This holds contact filtering data. +struct b2Filter +{ + /// The collision category bits. Normally you would just set one bit. + uint16 categoryBits; + + /// The collision mask bits. This states the categories that this + /// shape would accept for collision. + uint16 maskBits; + + /// Collision groups allow a certain group of objects to never collide (negative) + /// or always collide (positive). Zero means no collision group. Non-zero group + /// filtering always wins against the mask bits. + int16 groupIndex; +}; + +/// A fixture definition is used to create a fixture. This class defines an +/// abstract fixture definition. You can reuse fixture definitions safely. +struct b2FixtureDef +{ + /// The constructor sets the default fixture definition values. + b2FixtureDef() + { + shape = NULL; + userData = NULL; + friction = 0.2f; + restitution = 0.0f; + density = 0.0f; + filter.categoryBits = 0x0001; + filter.maskBits = 0xFFFF; + filter.groupIndex = 0; + isSensor = false; + } + + virtual ~b2FixtureDef() {} + + /// The shape, this must be set. The shape will be cloned, so you + /// can create the shape on the stack. + const b2Shape* shape; + + /// Use this to store application specific fixture data. + void* userData; + + /// The friction coefficient, usually in the range [0,1]. + float32 friction; + + /// The restitution (elasticity) usually in the range [0,1]. + float32 restitution; + + /// The density, usually in kg/m^2. + float32 density; + + /// A sensor shape collects contact information but never generates a collision + /// response. + bool isSensor; + + /// Contact filtering data. + b2Filter filter; +}; + + +/// A fixture is used to attach a shape to a body for collision detection. A fixture +/// inherits its transform from its parent. Fixtures hold additional non-geometric data +/// such as friction, collision filters, etc. +/// Fixtures are created via b2Body::CreateFixture. +/// @warning you cannot reuse fixtures. +class b2Fixture +{ +public: + /// Get the type of the child shape. You can use this to down cast to the concrete shape. + /// @return the shape type. + b2Shape::Type GetType() const; + + /// Get the child shape. You can modify the child shape, however you should not change the + /// number of vertices because this will crash some collision caching mechanisms. + /// Manipulating the shape may lead to non-physical behavior. + b2Shape* GetShape(); + const b2Shape* GetShape() const; + + /// Set if this fixture is a sensor. + void SetSensor(bool sensor); + + /// Is this fixture a sensor (non-solid)? + /// @return the true if the shape is a sensor. + bool IsSensor() const; + + /// Set the contact filtering data. This will not update contacts until the next time + /// step when either parent body is active and awake. + void SetFilterData(const b2Filter& filter); + + /// Get the contact filtering data. + const b2Filter& GetFilterData() const; + + /// Get the parent body of this fixture. This is NULL if the fixture is not attached. + /// @return the parent body. + b2Body* GetBody(); + const b2Body* GetBody() const; + + /// Get the next fixture in the parent body's fixture list. + /// @return the next shape. + b2Fixture* GetNext(); + const b2Fixture* GetNext() const; + + /// Get the user data that was assigned in the fixture definition. Use this to + /// store your application specific data. + void* GetUserData() const; + + /// Set the user data. Use this to store your application specific data. + void SetUserData(void* data); + + /// Test a point for containment in this fixture. + /// @param xf the shape world transform. + /// @param p a point in world coordinates. + bool TestPoint(const b2Vec2& p) const; + + /// Cast a ray against this shape. + /// @param output the ray-cast results. + /// @param input the ray-cast input parameters. + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; + + /// Get the mass data for this fixture. The mass data is based on the density and + /// the shape. The rotational inertia is about the shape's origin. This operation + /// may be expensive. + void GetMassData(b2MassData* massData) const; + + /// Set the density of this fixture. This will _not_ automatically adjust the mass + /// of the body. You must call b2Body::ResetMassData to update the body's mass. + void SetDensity(float32 density); + + /// Get the density of this fixture. + float32 GetDensity() const; + + /// Get the coefficient of friction. + float32 GetFriction() const; + + /// Set the coefficient of friction. + void SetFriction(float32 friction); + + /// Get the coefficient of restitution. + float32 GetRestitution() const; + + /// Set the coefficient of restitution. + void SetRestitution(float32 restitution); + + /// Get the fixture's AABB. This AABB may be enlarge and/or stale. + /// If you need a more accurate AABB, compute it using the shape and + /// the body transform. + const b2AABB& GetAABB() const; + +protected: + + friend class b2Body; + friend class b2World; + friend class b2Contact; + friend class b2ContactManager; + + b2Fixture(); + ~b2Fixture(); + + // We need separation create/destroy functions from the constructor/destructor because + // the destructor cannot access the allocator (no destructor arguments allowed by C++). + void Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def); + void Destroy(b2BlockAllocator* allocator); + + // These support body activation/deactivation. + void CreateProxy(b2BroadPhase* broadPhase, const b2Transform& xf); + void DestroyProxy(b2BroadPhase* broadPhase); + + void Synchronize(b2BroadPhase* broadPhase, const b2Transform& xf1, const b2Transform& xf2); + + b2AABB m_aabb; + + float32 m_density; + + b2Fixture* m_next; + b2Body* m_body; + + b2Shape* m_shape; + + float32 m_friction; + float32 m_restitution; + + int32 m_proxyId; + b2Filter m_filter; + + bool m_isSensor; + + void* m_userData; +}; + +inline b2Shape::Type b2Fixture::GetType() const +{ + return m_shape->GetType(); +} + +inline b2Shape* b2Fixture::GetShape() +{ + return m_shape; +} + +inline const b2Shape* b2Fixture::GetShape() const +{ + return m_shape; +} + +inline bool b2Fixture::IsSensor() const +{ + return m_isSensor; +} + +inline const b2Filter& b2Fixture::GetFilterData() const +{ + return m_filter; +} + +inline void* b2Fixture::GetUserData() const +{ + return m_userData; +} + +inline void b2Fixture::SetUserData(void* data) +{ + m_userData = data; +} + +inline b2Body* b2Fixture::GetBody() +{ + return m_body; +} + +inline const b2Body* b2Fixture::GetBody() const +{ + return m_body; +} + +inline b2Fixture* b2Fixture::GetNext() +{ + return m_next; +} + +inline const b2Fixture* b2Fixture::GetNext() const +{ + return m_next; +} + +inline void b2Fixture::SetDensity(float32 density) +{ + b2Assert(b2IsValid(density) && density >= 0.0f); + m_density = density; +} + +inline float32 b2Fixture::GetDensity() const +{ + return m_density; +} + +inline float32 b2Fixture::GetFriction() const +{ + return m_friction; +} + +inline void b2Fixture::SetFriction(float32 friction) +{ + m_friction = friction; +} + +inline float32 b2Fixture::GetRestitution() const +{ + return m_restitution; +} + +inline void b2Fixture::SetRestitution(float32 restitution) +{ + m_restitution = restitution; +} + +inline bool b2Fixture::TestPoint(const b2Vec2& p) const +{ + return m_shape->TestPoint(m_body->GetTransform(), p); +} + +inline bool b2Fixture::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const +{ + return m_shape->RayCast(output, input, m_body->GetTransform()); +} + +inline void b2Fixture::GetMassData(b2MassData* massData) const +{ + m_shape->ComputeMass(massData, m_density); +} + +inline const b2AABB& b2Fixture::GetAABB() const +{ + return m_aabb; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2Island.cpp b/AndEngine/jni/Box2D/Dynamics/b2Island.cpp new file mode 100644 index 0000000..2d36510 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2Island.cpp @@ -0,0 +1,374 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/b2Island.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2World.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" +#include "Box2D/Dynamics/Joints/b2Joint.h" +#include "Box2D/Common/b2StackAllocator.h" + +/* +Position Correction Notes +========================= +I tried the several algorithms for position correction of the 2D revolute joint. +I looked at these systems: +- simple pendulum (1m diameter sphere on massless 5m stick) with initial angular velocity of 100 rad/s. +- suspension bridge with 30 1m long planks of length 1m. +- multi-link chain with 30 1m long links. + +Here are the algorithms: + +Baumgarte - A fraction of the position error is added to the velocity error. There is no +separate position solver. + +Pseudo Velocities - After the velocity solver and position integration, +the position error, Jacobian, and effective mass are recomputed. Then +the velocity constraints are solved with pseudo velocities and a fraction +of the position error is added to the pseudo velocity error. The pseudo +velocities are initialized to zero and there is no warm-starting. After +the position solver, the pseudo velocities are added to the positions. +This is also called the First Order World method or the Position LCP method. + +Modified Nonlinear Gauss-Seidel (NGS) - Like Pseudo Velocities except the +position error is re-computed for each constraint and the positions are updated +after the constraint is solved. The radius vectors (aka Jacobians) are +re-computed too (otherwise the algorithm has horrible instability). The pseudo +velocity states are not needed because they are effectively zero at the beginning +of each iteration. Since we have the current position error, we allow the +iterations to terminate early if the error becomes smaller than b2_linearSlop. + +Full NGS or just NGS - Like Modified NGS except the effective mass are re-computed +each time a constraint is solved. + +Here are the results: +Baumgarte - this is the cheapest algorithm but it has some stability problems, +especially with the bridge. The chain links separate easily close to the root +and they jitter as they struggle to pull together. This is one of the most common +methods in the field. The big drawback is that the position correction artificially +affects the momentum, thus leading to instabilities and false bounce. I used a +bias factor of 0.2. A larger bias factor makes the bridge less stable, a smaller +factor makes joints and contacts more spongy. + +Pseudo Velocities - the is more stable than the Baumgarte method. The bridge is +stable. However, joints still separate with large angular velocities. Drag the +simple pendulum in a circle quickly and the joint will separate. The chain separates +easily and does not recover. I used a bias factor of 0.2. A larger value lead to +the bridge collapsing when a heavy cube drops on it. + +Modified NGS - this algorithm is better in some ways than Baumgarte and Pseudo +Velocities, but in other ways it is worse. The bridge and chain are much more +stable, but the simple pendulum goes unstable at high angular velocities. + +Full NGS - stable in all tests. The joints display good stiffness. The bridge +still sags, but this is better than infinite forces. + +Recommendations +Pseudo Velocities are not really worthwhile because the bridge and chain cannot +recover from joint separation. In other cases the benefit over Baumgarte is small. + +Modified NGS is not a robust method for the revolute joint due to the violent +instability seen in the simple pendulum. Perhaps it is viable with other constraint +types, especially scalar constraints where the effective mass is a scalar. + +This leaves Baumgarte and Full NGS. Baumgarte has small, but manageable instabilities +and is very fast. I don't think we can escape Baumgarte, especially in highly +demanding cases where high constraint fidelity is not needed. + +Full NGS is robust and easy on the eyes. I recommend this as an option for +higher fidelity simulation and certainly for suspension bridges and long chains. +Full NGS might be a good choice for ragdolls, especially motorized ragdolls where +joint separation can be problematic. The number of NGS iterations can be reduced +for better performance without harming robustness much. + +Each joint in a can be handled differently in the position solver. So I recommend +a system where the user can select the algorithm on a per joint basis. I would +probably default to the slower Full NGS and let the user select the faster +Baumgarte method in performance critical scenarios. +*/ + +/* +Cache Performance + +The Box2D solvers are dominated by cache misses. Data structures are designed +to increase the number of cache hits. Much of misses are due to random access +to body data. The constraint structures are iterated over linearly, which leads +to few cache misses. + +The bodies are not accessed during iteration. Instead read only data, such as +the mass values are stored with the constraints. The mutable data are the constraint +impulses and the bodies velocities/positions. The impulses are held inside the +constraint structures. The body velocities/positions are held in compact, temporary +arrays to increase the number of cache hits. Linear and angular velocity are +stored in a single array since multiple arrays lead to multiple misses. +*/ + +/* +2D Rotation + +R = [cos(theta) -sin(theta)] + [sin(theta) cos(theta) ] + +thetaDot = omega + +Let q1 = cos(theta), q2 = sin(theta). +R = [q1 -q2] + [q2 q1] + +q1Dot = -thetaDot * q2 +q2Dot = thetaDot * q1 + +q1_new = q1_old - dt * w * q2 +q2_new = q2_old + dt * w * q1 +then normalize. + +This might be faster than computing sin+cos. +However, we can compute sin+cos of the same angle fast. +*/ + +b2Island::b2Island( + int32 bodyCapacity, + int32 contactCapacity, + int32 jointCapacity, + b2StackAllocator* allocator, + b2ContactListener* listener) +{ + m_bodyCapacity = bodyCapacity; + m_contactCapacity = contactCapacity; + m_jointCapacity = jointCapacity; + m_bodyCount = 0; + m_contactCount = 0; + m_jointCount = 0; + + m_allocator = allocator; + m_listener = listener; + + m_bodies = (b2Body**)m_allocator->Allocate(bodyCapacity * sizeof(b2Body*)); + m_contacts = (b2Contact**)m_allocator->Allocate(contactCapacity * sizeof(b2Contact*)); + m_joints = (b2Joint**)m_allocator->Allocate(jointCapacity * sizeof(b2Joint*)); + + m_velocities = (b2Velocity*)m_allocator->Allocate(m_bodyCapacity * sizeof(b2Velocity)); + m_positions = (b2Position*)m_allocator->Allocate(m_bodyCapacity * sizeof(b2Position)); +} + +b2Island::~b2Island() +{ + // Warning: the order should reverse the constructor order. + m_allocator->Free(m_positions); + m_allocator->Free(m_velocities); + m_allocator->Free(m_joints); + m_allocator->Free(m_contacts); + m_allocator->Free(m_bodies); +} + +void b2Island::Solve(const b2TimeStep& step, const b2Vec2& gravity, bool allowSleep) +{ + // Integrate velocities and apply damping. + for (int32 i = 0; i < m_bodyCount; ++i) + { + b2Body* b = m_bodies[i]; + + if (b->GetType() != b2_dynamicBody) + { + continue; + } + + // Integrate velocities. + b->m_linearVelocity += step.dt * (gravity + b->m_invMass * b->m_force); + b->m_angularVelocity += step.dt * b->m_invI * b->m_torque; + + // Apply damping. + // ODE: dv/dt + c * v = 0 + // Solution: v(t) = v0 * exp(-c * t) + // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt) + // v2 = exp(-c * dt) * v1 + // Taylor expansion: + // v2 = (1.0f - c * dt) * v1 + b->m_linearVelocity *= b2Clamp(1.0f - step.dt * b->m_linearDamping, 0.0f, 1.0f); + b->m_angularVelocity *= b2Clamp(1.0f - step.dt * b->m_angularDamping, 0.0f, 1.0f); + } + + // Partition contacts so that contacts with static bodies are solved last. + int32 i1 = -1; + for (int32 i2 = 0; i2 < m_contactCount; ++i2) + { + b2Fixture* fixtureA = m_contacts[i2]->GetFixtureA(); + b2Fixture* fixtureB = m_contacts[i2]->GetFixtureB(); + b2Body* bodyA = fixtureA->GetBody(); + b2Body* bodyB = fixtureB->GetBody(); + bool nonStatic = bodyA->GetType() != b2_staticBody && bodyB->GetType() != b2_staticBody; + if (nonStatic) + { + ++i1; + b2Swap(m_contacts[i1], m_contacts[i2]); + } + } + + // Initialize velocity constraints. + b2ContactSolver contactSolver(m_contacts, m_contactCount, m_allocator, step.dtRatio); + contactSolver.WarmStart(); + for (int32 i = 0; i < m_jointCount; ++i) + { + m_joints[i]->InitVelocityConstraints(step); + } + + // Solve velocity constraints. + for (int32 i = 0; i < step.velocityIterations; ++i) + { + for (int32 j = 0; j < m_jointCount; ++j) + { + m_joints[j]->SolveVelocityConstraints(step); + } + + contactSolver.SolveVelocityConstraints(); + } + + // Post-solve (store impulses for warm starting). + contactSolver.StoreImpulses(); + + // Integrate positions. + for (int32 i = 0; i < m_bodyCount; ++i) + { + b2Body* b = m_bodies[i]; + + if (b->GetType() == b2_staticBody) + { + continue; + } + + // Check for large velocities. + b2Vec2 translation = step.dt * b->m_linearVelocity; + if (b2Dot(translation, translation) > b2_maxTranslationSquared) + { + float32 ratio = b2_maxTranslation / translation.Length(); + b->m_linearVelocity *= ratio; + } + + float32 rotation = step.dt * b->m_angularVelocity; + if (rotation * rotation > b2_maxRotationSquared) + { + float32 ratio = b2_maxRotation / b2Abs(rotation); + b->m_angularVelocity *= ratio; + } + + // Store positions for continuous collision. + b->m_sweep.c0 = b->m_sweep.c; + b->m_sweep.a0 = b->m_sweep.a; + + // Integrate + b->m_sweep.c += step.dt * b->m_linearVelocity; + b->m_sweep.a += step.dt * b->m_angularVelocity; + + // Compute new transform + b->SynchronizeTransform(); + + // Note: shapes are synchronized later. + } + + // Iterate over constraints. + for (int32 i = 0; i < step.positionIterations; ++i) + { + bool contactsOkay = contactSolver.SolvePositionConstraints(b2_contactBaumgarte); + + bool jointsOkay = true; + for (int32 i = 0; i < m_jointCount; ++i) + { + bool jointOkay = m_joints[i]->SolvePositionConstraints(b2_contactBaumgarte); + jointsOkay = jointsOkay && jointOkay; + } + + if (contactsOkay && jointsOkay) + { + // Exit early if the position errors are small. + break; + } + } + + Report(contactSolver.m_constraints); + + if (allowSleep) + { + float32 minSleepTime = b2_maxFloat; + + const float32 linTolSqr = b2_linearSleepTolerance * b2_linearSleepTolerance; + const float32 angTolSqr = b2_angularSleepTolerance * b2_angularSleepTolerance; + + for (int32 i = 0; i < m_bodyCount; ++i) + { + b2Body* b = m_bodies[i]; + if (b->GetType() == b2_staticBody) + { + continue; + } + + if ((b->m_flags & b2Body::e_autoSleepFlag) == 0) + { + b->m_sleepTime = 0.0f; + minSleepTime = 0.0f; + } + + if ((b->m_flags & b2Body::e_autoSleepFlag) == 0 || + b->m_angularVelocity * b->m_angularVelocity > angTolSqr || + b2Dot(b->m_linearVelocity, b->m_linearVelocity) > linTolSqr) + { + b->m_sleepTime = 0.0f; + minSleepTime = 0.0f; + } + else + { + b->m_sleepTime += step.dt; + minSleepTime = b2Min(minSleepTime, b->m_sleepTime); + } + } + + if (minSleepTime >= b2_timeToSleep) + { + for (int32 i = 0; i < m_bodyCount; ++i) + { + b2Body* b = m_bodies[i]; + b->SetAwake(false); + } + } + } +} + +void b2Island::Report(const b2ContactConstraint* constraints) +{ + if (m_listener == NULL) + { + return; + } + + for (int32 i = 0; i < m_contactCount; ++i) + { + b2Contact* c = m_contacts[i]; + + const b2ContactConstraint* cc = constraints + i; + + b2ContactImpulse impulse; + for (int32 j = 0; j < cc->pointCount; ++j) + { + impulse.normalImpulses[j] = cc->points[j].normalImpulse; + impulse.tangentImpulses[j] = cc->points[j].tangentImpulse; + } + + m_listener->PostSolve(c, &impulse); + } +} diff --git a/AndEngine/jni/Box2D/Dynamics/b2Island.h b/AndEngine/jni/Box2D/Dynamics/b2Island.h new file mode 100644 index 0000000..6403af0 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2Island.h @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_ISLAND_H +#define B2_ISLAND_H + +#include "Box2D/Common/b2Math.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2TimeStep.h" + +class b2Contact; +class b2Joint; +class b2StackAllocator; +class b2ContactListener; +struct b2ContactConstraint; + +/// This is an internal structure. +struct b2Position +{ + b2Vec2 x; + float32 a; +}; + +/// This is an internal structure. +struct b2Velocity +{ + b2Vec2 v; + float32 w; +}; + +/// This is an internal class. +class b2Island +{ +public: + b2Island(int32 bodyCapacity, int32 contactCapacity, int32 jointCapacity, + b2StackAllocator* allocator, b2ContactListener* listener); + ~b2Island(); + + void Clear() + { + m_bodyCount = 0; + m_contactCount = 0; + m_jointCount = 0; + } + + void Solve(const b2TimeStep& step, const b2Vec2& gravity, bool allowSleep); + + void Add(b2Body* body) + { + b2Assert(m_bodyCount < m_bodyCapacity); + body->m_islandIndex = m_bodyCount; + m_bodies[m_bodyCount++] = body; + } + + void Add(b2Contact* contact) + { + b2Assert(m_contactCount < m_contactCapacity); + m_contacts[m_contactCount++] = contact; + } + + void Add(b2Joint* joint) + { + b2Assert(m_jointCount < m_jointCapacity); + m_joints[m_jointCount++] = joint; + } + + void Report(const b2ContactConstraint* constraints); + + b2StackAllocator* m_allocator; + b2ContactListener* m_listener; + + b2Body** m_bodies; + b2Contact** m_contacts; + b2Joint** m_joints; + + b2Position* m_positions; + b2Velocity* m_velocities; + + int32 m_bodyCount; + int32 m_jointCount; + int32 m_contactCount; + + int32 m_bodyCapacity; + int32 m_contactCapacity; + int32 m_jointCapacity; + + int32 m_positionIterationCount; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2TimeStep.h b/AndEngine/jni/Box2D/Dynamics/b2TimeStep.h new file mode 100644 index 0000000..0002de9 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2TimeStep.h @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_TIME_STEP_H +#define B2_TIME_STEP_H + +#include "Box2D/Common/b2Settings.h" + +/// This is an internal structure. +struct b2TimeStep +{ + float32 dt; // time step + float32 inv_dt; // inverse time step (0 if dt == 0). + float32 dtRatio; // dt * inv_dt0 + int32 velocityIterations; + int32 positionIterations; + bool warmStarting; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2World.cpp b/AndEngine/jni/Box2D/Dynamics/b2World.cpp new file mode 100644 index 0000000..ca76877 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2World.cpp @@ -0,0 +1,1076 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/b2World.h" +#include "Box2D/Dynamics/b2Body.h" +#include "Box2D/Dynamics/b2Fixture.h" +#include "Box2D/Dynamics/b2Island.h" +#include "Box2D/Dynamics/Joints/b2PulleyJoint.h" +#include "Box2D/Dynamics/Contacts/b2Contact.h" +#include "Box2D/Dynamics/Contacts/b2ContactSolver.h" +#include "Box2D/Dynamics/Contacts/b2TOISolver.h" +#include "Box2D/Collision/b2Collision.h" +#include "Box2D/Collision/b2BroadPhase.h" +#include "Box2D/Collision/Shapes/b2CircleShape.h" +#include "Box2D/Collision/Shapes/b2PolygonShape.h" +#include "Box2D/Collision/b2TimeOfImpact.h" +#include + +b2World::b2World(const b2Vec2& gravity, bool doSleep) +{ + m_destructionListener = NULL; + m_debugDraw = NULL; + + m_bodyList = NULL; + m_jointList = NULL; + + m_bodyCount = 0; + m_jointCount = 0; + + m_warmStarting = true; + m_continuousPhysics = true; + + m_allowSleep = doSleep; + m_gravity = gravity; + + m_flags = e_clearForces; + + m_inv_dt0 = 0.0f; + + m_contactManager.m_allocator = &m_blockAllocator; +} + +b2World::~b2World() +{ +} + +void b2World::SetDestructionListener(b2DestructionListener* listener) +{ + m_destructionListener = listener; +} + +void b2World::SetContactFilter(b2ContactFilter* filter) +{ + m_contactManager.m_contactFilter = filter; +} + +void b2World::SetContactListener(b2ContactListener* listener) +{ + m_contactManager.m_contactListener = listener; +} + +void b2World::SetDebugDraw(b2DebugDraw* debugDraw) +{ + m_debugDraw = debugDraw; +} + +b2Body* b2World::CreateBody(const b2BodyDef* def) +{ + b2Assert(IsLocked() == false); + if (IsLocked()) + { + return NULL; + } + + void* mem = m_blockAllocator.Allocate(sizeof(b2Body)); + b2Body* b = new (mem) b2Body(def, this); + + // Add to world doubly linked list. + b->m_prev = NULL; + b->m_next = m_bodyList; + if (m_bodyList) + { + m_bodyList->m_prev = b; + } + m_bodyList = b; + ++m_bodyCount; + + return b; +} + +void b2World::DestroyBody(b2Body* b) +{ + b2Assert(m_bodyCount > 0); + b2Assert(IsLocked() == false); + if (IsLocked()) + { + return; + } + + // Delete the attached joints. + b2JointEdge* je = b->m_jointList; + while (je) + { + b2JointEdge* je0 = je; + je = je->next; + + if (m_destructionListener) + { + m_destructionListener->SayGoodbye(je0->joint); + } + + DestroyJoint(je0->joint); + } + b->m_jointList = NULL; + + // Delete the attached contacts. + b2ContactEdge* ce = b->m_contactList; + while (ce) + { + b2ContactEdge* ce0 = ce; + ce = ce->next; + m_contactManager.Destroy(ce0->contact); + } + b->m_contactList = NULL; + + // Delete the attached fixtures. This destroys broad-phase proxies. + b2Fixture* f = b->m_fixtureList; + while (f) + { + b2Fixture* f0 = f; + f = f->m_next; + + if (m_destructionListener) + { + m_destructionListener->SayGoodbye(f0); + } + + f0->DestroyProxy(&m_contactManager.m_broadPhase); + f0->Destroy(&m_blockAllocator); + f0->~b2Fixture(); + m_blockAllocator.Free(f0, sizeof(b2Fixture)); + } + b->m_fixtureList = NULL; + b->m_fixtureCount = 0; + + // Remove world body list. + if (b->m_prev) + { + b->m_prev->m_next = b->m_next; + } + + if (b->m_next) + { + b->m_next->m_prev = b->m_prev; + } + + if (b == m_bodyList) + { + m_bodyList = b->m_next; + } + + --m_bodyCount; + b->~b2Body(); + m_blockAllocator.Free(b, sizeof(b2Body)); +} + +b2Joint* b2World::CreateJoint(const b2JointDef* def) +{ + b2Assert(IsLocked() == false); + if (IsLocked()) + { + return NULL; + } + + b2Joint* j = b2Joint::Create(def, &m_blockAllocator); + + // Connect to the world list. + j->m_prev = NULL; + j->m_next = m_jointList; + if (m_jointList) + { + m_jointList->m_prev = j; + } + m_jointList = j; + ++m_jointCount; + + // Connect to the bodies' doubly linked lists. + j->m_edgeA.joint = j; + j->m_edgeA.other = j->m_bodyB; + j->m_edgeA.prev = NULL; + j->m_edgeA.next = j->m_bodyA->m_jointList; + if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA; + j->m_bodyA->m_jointList = &j->m_edgeA; + + j->m_edgeB.joint = j; + j->m_edgeB.other = j->m_bodyA; + j->m_edgeB.prev = NULL; + j->m_edgeB.next = j->m_bodyB->m_jointList; + if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB; + j->m_bodyB->m_jointList = &j->m_edgeB; + + b2Body* bodyA = def->bodyA; + b2Body* bodyB = def->bodyB; + + // If the joint prevents collisions, then flag any contacts for filtering. + if (def->collideConnected == false) + { + b2ContactEdge* edge = bodyB->GetContactList(); + while (edge) + { + if (edge->other == bodyA) + { + // Flag the contact for filtering at the next time step (where either + // body is awake). + edge->contact->FlagForFiltering(); + } + + edge = edge->next; + } + } + + // Note: creating a joint doesn't wake the bodies. + + return j; +} + +void b2World::DestroyJoint(b2Joint* j) +{ + b2Assert(IsLocked() == false); + if (IsLocked()) + { + return; + } + + bool collideConnected = j->m_collideConnected; + + // Remove from the doubly linked list. + if (j->m_prev) + { + j->m_prev->m_next = j->m_next; + } + + if (j->m_next) + { + j->m_next->m_prev = j->m_prev; + } + + if (j == m_jointList) + { + m_jointList = j->m_next; + } + + // Disconnect from island graph. + b2Body* bodyA = j->m_bodyA; + b2Body* bodyB = j->m_bodyB; + + // Wake up connected bodies. + bodyA->SetAwake(true); + bodyB->SetAwake(true); + + // Remove from body 1. + if (j->m_edgeA.prev) + { + j->m_edgeA.prev->next = j->m_edgeA.next; + } + + if (j->m_edgeA.next) + { + j->m_edgeA.next->prev = j->m_edgeA.prev; + } + + if (&j->m_edgeA == bodyA->m_jointList) + { + bodyA->m_jointList = j->m_edgeA.next; + } + + j->m_edgeA.prev = NULL; + j->m_edgeA.next = NULL; + + // Remove from body 2 + if (j->m_edgeB.prev) + { + j->m_edgeB.prev->next = j->m_edgeB.next; + } + + if (j->m_edgeB.next) + { + j->m_edgeB.next->prev = j->m_edgeB.prev; + } + + if (&j->m_edgeB == bodyB->m_jointList) + { + bodyB->m_jointList = j->m_edgeB.next; + } + + j->m_edgeB.prev = NULL; + j->m_edgeB.next = NULL; + + b2Joint::Destroy(j, &m_blockAllocator); + + b2Assert(m_jointCount > 0); + --m_jointCount; + + // If the joint prevents collisions, then flag any contacts for filtering. + if (collideConnected == false) + { + b2ContactEdge* edge = bodyB->GetContactList(); + while (edge) + { + if (edge->other == bodyA) + { + // Flag the contact for filtering at the next time step (where either + // body is awake). + edge->contact->FlagForFiltering(); + } + + edge = edge->next; + } + } +} + +// Find islands, integrate and solve constraints, solve position constraints +void b2World::Solve(const b2TimeStep& step) +{ + // Size the island for the worst case. + b2Island island(m_bodyCount, + m_contactManager.m_contactCount, + m_jointCount, + &m_stackAllocator, + m_contactManager.m_contactListener); + + // Clear all the island flags. + for (b2Body* b = m_bodyList; b; b = b->m_next) + { + b->m_flags &= ~b2Body::e_islandFlag; + } + for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) + { + c->m_flags &= ~b2Contact::e_islandFlag; + } + for (b2Joint* j = m_jointList; j; j = j->m_next) + { + j->m_islandFlag = false; + } + + // Build and simulate all awake islands. + int32 stackSize = m_bodyCount; + b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*)); + for (b2Body* seed = m_bodyList; seed; seed = seed->m_next) + { + if (seed->m_flags & b2Body::e_islandFlag) + { + continue; + } + + if (seed->IsAwake() == false || seed->IsActive() == false) + { + continue; + } + + // The seed can be dynamic or kinematic. + if (seed->GetType() == b2_staticBody) + { + continue; + } + + // Reset island and stack. + island.Clear(); + int32 stackCount = 0; + stack[stackCount++] = seed; + seed->m_flags |= b2Body::e_islandFlag; + + // Perform a depth first search (DFS) on the constraint graph. + while (stackCount > 0) + { + // Grab the next body off the stack and add it to the island. + b2Body* b = stack[--stackCount]; + b2Assert(b->IsActive() == true); + island.Add(b); + + // Make sure the body is awake. + b->SetAwake(true); + + // To keep islands as small as possible, we don't + // propagate islands across static bodies. + if (b->GetType() == b2_staticBody) + { + continue; + } + + // Search all contacts connected to this body. + for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next) + { + b2Contact* contact = ce->contact; + + // Has this contact already been added to an island? + if (contact->m_flags & b2Contact::e_islandFlag) + { + continue; + } + + // Is this contact solid and touching? + if (contact->IsEnabled() == false || + contact->IsTouching() == false) + { + continue; + } + + // Skip sensors. + bool sensorA = contact->m_fixtureA->m_isSensor; + bool sensorB = contact->m_fixtureB->m_isSensor; + if (sensorA || sensorB) + { + continue; + } + + island.Add(contact); + contact->m_flags |= b2Contact::e_islandFlag; + + b2Body* other = ce->other; + + // Was the other body already added to this island? + if (other->m_flags & b2Body::e_islandFlag) + { + continue; + } + + b2Assert(stackCount < stackSize); + stack[stackCount++] = other; + other->m_flags |= b2Body::e_islandFlag; + } + + // Search all joints connect to this body. + for (b2JointEdge* je = b->m_jointList; je; je = je->next) + { + if (je->joint->m_islandFlag == true) + { + continue; + } + + b2Body* other = je->other; + + // Don't simulate joints connected to inactive bodies. + if (other->IsActive() == false) + { + continue; + } + + island.Add(je->joint); + je->joint->m_islandFlag = true; + + if (other->m_flags & b2Body::e_islandFlag) + { + continue; + } + + b2Assert(stackCount < stackSize); + stack[stackCount++] = other; + other->m_flags |= b2Body::e_islandFlag; + } + } + + island.Solve(step, m_gravity, m_allowSleep); + + // Post solve cleanup. + for (int32 i = 0; i < island.m_bodyCount; ++i) + { + // Allow static bodies to participate in other islands. + b2Body* b = island.m_bodies[i]; + if (b->GetType() == b2_staticBody) + { + b->m_flags &= ~b2Body::e_islandFlag; + } + } + } + + m_stackAllocator.Free(stack); + + // Synchronize fixtures, check for out of range bodies. + for (b2Body* b = m_bodyList; b; b = b->GetNext()) + { + // If a body was not in an island then it did not move. + if ((b->m_flags & b2Body::e_islandFlag) == 0) + { + continue; + } + + if (b->GetType() == b2_staticBody) + { + continue; + } + + // Update fixtures (for broad-phase). + b->SynchronizeFixtures(); + } + + // Look for new contacts. + m_contactManager.FindNewContacts(); +} + +// Advance a dynamic body to its first time of contact +// and adjust the position to ensure clearance. +void b2World::SolveTOI(b2Body* body) +{ + // Find the minimum contact. + b2Contact* toiContact = NULL; + float32 toi = 1.0f; + b2Body* toiOther = NULL; + bool found; + int32 count; + int32 iter = 0; + + bool bullet = body->IsBullet(); + + // Iterate until all contacts agree on the minimum TOI. We have + // to iterate because the TOI algorithm may skip some intermediate + // collisions when objects rotate through each other. + do + { + count = 0; + found = false; + for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next) + { + if (ce->contact == toiContact) + { + continue; + } + + b2Body* other = ce->other; + b2BodyType type = other->GetType(); + + // Only bullets perform TOI with dynamic bodies. + if (bullet == true) + { + // Bullets only perform TOI with bodies that have their TOI resolved. + if ((other->m_flags & b2Body::e_toiFlag) == 0) + { + continue; + } + + // No repeated hits on non-static bodies + if (type != b2_staticBody && (ce->contact->m_flags & b2Contact::e_bulletHitFlag) != 0) + { + continue; + } + } + else if (type == b2_dynamicBody) + { + continue; + } + + // Check for a disabled contact. + b2Contact* contact = ce->contact; + if (contact->IsEnabled() == false) + { + continue; + } + + // Prevent infinite looping. + if (contact->m_toiCount > 10) + { + continue; + } + + b2Fixture* fixtureA = contact->m_fixtureA; + b2Fixture* fixtureB = contact->m_fixtureB; + + // Cull sensors. + if (fixtureA->IsSensor() || fixtureB->IsSensor()) + { + continue; + } + + b2Body* bodyA = fixtureA->m_body; + b2Body* bodyB = fixtureB->m_body; + + // Compute the time of impact in interval [0, minTOI] + b2TOIInput input; + input.proxyA.Set(fixtureA->GetShape()); + input.proxyB.Set(fixtureB->GetShape()); + input.sweepA = bodyA->m_sweep; + input.sweepB = bodyB->m_sweep; + input.tMax = toi; + + b2TOIOutput output; + b2TimeOfImpact(&output, &input); + + if (output.state == b2TOIOutput::e_touching && output.t < toi) + { + toiContact = contact; + toi = output.t; + toiOther = other; + found = true; + } + + ++count; + } + + ++iter; + } while (found && count > 1 && iter < 50); + + if (toiContact == NULL) + { + body->Advance(1.0f); + return; + } + + b2Sweep backup = body->m_sweep; + body->Advance(toi); + toiContact->Update(m_contactManager.m_contactListener); + if (toiContact->IsEnabled() == false) + { + // Contact disabled. Backup and recurse. + body->m_sweep = backup; + SolveTOI(body); + } + + ++toiContact->m_toiCount; + + // Update all the valid contacts on this body and build a contact island. + b2Contact* contacts[b2_maxTOIContacts]; + count = 0; + for (b2ContactEdge* ce = body->m_contactList; ce && count < b2_maxTOIContacts; ce = ce->next) + { + b2Body* other = ce->other; + b2BodyType type = other->GetType(); + + // Only perform correction with static bodies, so the + // body won't get pushed out of the world. + if (type == b2_dynamicBody) + { + continue; + } + + // Check for a disabled contact. + b2Contact* contact = ce->contact; + if (contact->IsEnabled() == false) + { + continue; + } + + b2Fixture* fixtureA = contact->m_fixtureA; + b2Fixture* fixtureB = contact->m_fixtureB; + + // Cull sensors. + if (fixtureA->IsSensor() || fixtureB->IsSensor()) + { + continue; + } + + // The contact likely has some new contact points. The listener + // gives the user a chance to disable the contact. + if (contact != toiContact) + { + contact->Update(m_contactManager.m_contactListener); + } + + // Did the user disable the contact? + if (contact->IsEnabled() == false) + { + // Skip this contact. + continue; + } + + if (contact->IsTouching() == false) + { + continue; + } + + contacts[count] = contact; + ++count; + } + + // Reduce the TOI body's overlap with the contact island. + b2TOISolver solver(&m_stackAllocator); + solver.Initialize(contacts, count, body); + + const float32 k_toiBaumgarte = 0.75f; + bool solved = false; + for (int32 i = 0; i < 20; ++i) + { + bool contactsOkay = solver.Solve(k_toiBaumgarte); + if (contactsOkay) + { + solved = true; + break; + } + } + + if (toiOther->GetType() != b2_staticBody) + { + toiContact->m_flags |= b2Contact::e_bulletHitFlag; + } +} + +// Sequentially solve TOIs for each body. We bring each +// body to the time of contact and perform some position correction. +// Time is not conserved. +void b2World::SolveTOI() +{ + // Prepare all contacts. + for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) + { + // Enable the contact + c->m_flags |= b2Contact::e_enabledFlag; + + // Set the number of TOI events for this contact to zero. + c->m_toiCount = 0; + } + + // Initialize the TOI flag. + for (b2Body* body = m_bodyList; body; body = body->m_next) + { + // Kinematic, and static bodies will not be affected by the TOI event. + // If a body was not in an island then it did not move. + if ((body->m_flags & b2Body::e_islandFlag) == 0 || body->GetType() == b2_kinematicBody || body->GetType() == b2_staticBody) + { + body->m_flags |= b2Body::e_toiFlag; + } + else + { + body->m_flags &= ~b2Body::e_toiFlag; + } + } + + // Collide non-bullets. + for (b2Body* body = m_bodyList; body; body = body->m_next) + { + if (body->m_flags & b2Body::e_toiFlag) + { + continue; + } + + if (body->IsBullet() == true) + { + continue; + } + + SolveTOI(body); + + body->m_flags |= b2Body::e_toiFlag; + } + + // Collide bullets. + for (b2Body* body = m_bodyList; body; body = body->m_next) + { + if (body->m_flags & b2Body::e_toiFlag) + { + continue; + } + + if (body->IsBullet() == false) + { + continue; + } + + SolveTOI(body); + + body->m_flags |= b2Body::e_toiFlag; + } +} + +void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations) +{ + // If new fixtures were added, we need to find the new contacts. + if (m_flags & e_newFixture) + { + m_contactManager.FindNewContacts(); + m_flags &= ~e_newFixture; + } + + m_flags |= e_locked; + + b2TimeStep step; + step.dt = dt; + step.velocityIterations = velocityIterations; + step.positionIterations = positionIterations; + if (dt > 0.0f) + { + step.inv_dt = 1.0f / dt; + } + else + { + step.inv_dt = 0.0f; + } + + step.dtRatio = m_inv_dt0 * dt; + + step.warmStarting = m_warmStarting; + + // Update contacts. This is where some contacts are destroyed. + m_contactManager.Collide(); + + // Integrate velocities, solve velocity constraints, and integrate positions. + if (step.dt > 0.0f) + { + Solve(step); + } + + // Handle TOI events. + if (m_continuousPhysics && step.dt > 0.0f) + { + SolveTOI(); + } + + if (step.dt > 0.0f) + { + m_inv_dt0 = step.inv_dt; + } + + if (m_flags & e_clearForces) + { + ClearForces(); + } + + m_flags &= ~e_locked; +} + +void b2World::ClearForces() +{ + for (b2Body* body = m_bodyList; body; body = body->GetNext()) + { + body->m_force.SetZero(); + body->m_torque = 0.0f; + } +} + +struct b2WorldQueryWrapper +{ + bool QueryCallback(int32 proxyId) + { + b2Fixture* fixture = (b2Fixture*)broadPhase->GetUserData(proxyId); + return callback->ReportFixture(fixture); + } + + const b2BroadPhase* broadPhase; + b2QueryCallback* callback; +}; + +void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const +{ + b2WorldQueryWrapper wrapper; + wrapper.broadPhase = &m_contactManager.m_broadPhase; + wrapper.callback = callback; + m_contactManager.m_broadPhase.Query(&wrapper, aabb); +} + +struct b2WorldRayCastWrapper +{ + float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId) + { + void* userData = broadPhase->GetUserData(proxyId); + b2Fixture* fixture = (b2Fixture*)userData; + b2RayCastOutput output; + bool hit = fixture->RayCast(&output, input); + + if (hit) + { + float32 fraction = output.fraction; + b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2; + return callback->ReportFixture(fixture, point, output.normal, fraction); + } + + return input.maxFraction; + } + + const b2BroadPhase* broadPhase; + b2RayCastCallback* callback; +}; + +void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const +{ + b2WorldRayCastWrapper wrapper; + wrapper.broadPhase = &m_contactManager.m_broadPhase; + wrapper.callback = callback; + b2RayCastInput input; + input.maxFraction = 1.0f; + input.p1 = point1; + input.p2 = point2; + m_contactManager.m_broadPhase.RayCast(&wrapper, input); +} + +void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color) +{ + switch (fixture->GetType()) + { + case b2Shape::e_circle: + { + b2CircleShape* circle = (b2CircleShape*)fixture->GetShape(); + + b2Vec2 center = b2Mul(xf, circle->m_p); + float32 radius = circle->m_radius; + b2Vec2 axis = xf.R.col1; + + m_debugDraw->DrawSolidCircle(center, radius, axis, color); + } + break; + + case b2Shape::e_polygon: + { + b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape(); + int32 vertexCount = poly->m_vertexCount; + b2Assert(vertexCount <= b2_maxPolygonVertices); + b2Vec2 vertices[b2_maxPolygonVertices]; + + for (int32 i = 0; i < vertexCount; ++i) + { + vertices[i] = b2Mul(xf, poly->m_vertices[i]); + } + + m_debugDraw->DrawSolidPolygon(vertices, vertexCount, color); + } + break; + } +} + +void b2World::DrawJoint(b2Joint* joint) +{ + b2Body* bodyA = joint->GetBodyA(); + b2Body* bodyB = joint->GetBodyB(); + const b2Transform& xf1 = bodyA->GetTransform(); + const b2Transform& xf2 = bodyB->GetTransform(); + b2Vec2 x1 = xf1.position; + b2Vec2 x2 = xf2.position; + b2Vec2 p1 = joint->GetAnchorA(); + b2Vec2 p2 = joint->GetAnchorB(); + + b2Color color(0.5f, 0.8f, 0.8f); + + switch (joint->GetType()) + { + case e_distanceJoint: + m_debugDraw->DrawSegment(p1, p2, color); + break; + + case e_pulleyJoint: + { + b2PulleyJoint* pulley = (b2PulleyJoint*)joint; + b2Vec2 s1 = pulley->GetGroundAnchorA(); + b2Vec2 s2 = pulley->GetGroundAnchorB(); + m_debugDraw->DrawSegment(s1, p1, color); + m_debugDraw->DrawSegment(s2, p2, color); + m_debugDraw->DrawSegment(s1, s2, color); + } + break; + + case e_mouseJoint: + // don't draw this + break; + + default: + m_debugDraw->DrawSegment(x1, p1, color); + m_debugDraw->DrawSegment(p1, p2, color); + m_debugDraw->DrawSegment(x2, p2, color); + } +} + +void b2World::DrawDebugData() +{ + if (m_debugDraw == NULL) + { + return; + } + + uint32 flags = m_debugDraw->GetFlags(); + + if (flags & b2DebugDraw::e_shapeBit) + { + for (b2Body* b = m_bodyList; b; b = b->GetNext()) + { + const b2Transform& xf = b->GetTransform(); + for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) + { + if (b->IsActive() == false) + { + DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f)); + } + else if (b->GetType() == b2_staticBody) + { + DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f)); + } + else if (b->GetType() == b2_kinematicBody) + { + DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f)); + } + else if (b->IsAwake() == false) + { + DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f)); + } + else + { + DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f)); + } + } + } + } + + if (flags & b2DebugDraw::e_jointBit) + { + for (b2Joint* j = m_jointList; j; j = j->GetNext()) + { + DrawJoint(j); + } + } + + if (flags & b2DebugDraw::e_pairBit) + { + b2Color color(0.3f, 0.9f, 0.9f); + for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext()) + { + b2Fixture* fixtureA = c->GetFixtureA(); + b2Fixture* fixtureB = c->GetFixtureB(); + + b2Vec2 cA = fixtureA->GetAABB().GetCenter(); + b2Vec2 cB = fixtureB->GetAABB().GetCenter(); + + m_debugDraw->DrawSegment(cA, cB, color); + } + } + + if (flags & b2DebugDraw::e_aabbBit) + { + b2Color color(0.9f, 0.3f, 0.9f); + b2BroadPhase* bp = &m_contactManager.m_broadPhase; + + for (b2Body* b = m_bodyList; b; b = b->GetNext()) + { + if (b->IsActive() == false) + { + continue; + } + + for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) + { + b2AABB aabb = bp->GetFatAABB(f->m_proxyId); + b2Vec2 vs[4]; + vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); + vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); + vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); + vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); + + m_debugDraw->DrawPolygon(vs, 4, color); + } + } + } + + if (flags & b2DebugDraw::e_centerOfMassBit) + { + for (b2Body* b = m_bodyList; b; b = b->GetNext()) + { + b2Transform xf = b->GetTransform(); + xf.position = b->GetWorldCenter(); + m_debugDraw->DrawTransform(xf); + } + } +} + +int32 b2World::GetProxyCount() const +{ + return m_contactManager.m_broadPhase.GetProxyCount(); +} diff --git a/AndEngine/jni/Box2D/Dynamics/b2World.h b/AndEngine/jni/Box2D/Dynamics/b2World.h new file mode 100644 index 0000000..1cadff7 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2World.h @@ -0,0 +1,285 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_WORLD_H +#define B2_WORLD_H + +#include "Box2D/Common/b2Math.h" +#include "Box2D/Common/b2BlockAllocator.h" +#include "Box2D/Common/b2StackAllocator.h" +#include "Box2D/Dynamics/b2ContactManager.h" +#include "Box2D/Dynamics/b2WorldCallbacks.h" + +struct b2AABB; +struct b2BodyDef; +struct b2JointDef; +struct b2TimeStep; +class b2Body; +class b2Fixture; +class b2Joint; + +/// The world class manages all physics entities, dynamic simulation, +/// and asynchronous queries. The world also contains efficient memory +/// management facilities. +class b2World +{ +public: + /// Construct a world object. + /// @param gravity the world gravity vector. + /// @param doSleep improve performance by not simulating inactive bodies. + b2World(const b2Vec2& gravity, bool doSleep); + + /// Destruct the world. All physics entities are destroyed and all heap memory is released. + ~b2World(); + + /// Register a destruction listener. The listener is owned by you and must + /// remain in scope. + void SetDestructionListener(b2DestructionListener* listener); + + /// Register a contact filter to provide specific control over collision. + /// Otherwise the default filter is used (b2_defaultFilter). The listener is + /// owned by you and must remain in scope. + void SetContactFilter(b2ContactFilter* filter); + + /// Register a contact event listener. The listener is owned by you and must + /// remain in scope. + void SetContactListener(b2ContactListener* listener); + + /// Register a routine for debug drawing. The debug draw functions are called + /// inside with b2World::DrawDebugData method. The debug draw object is owned + /// by you and must remain in scope. + void SetDebugDraw(b2DebugDraw* debugDraw); + + /// Create a rigid body given a definition. No reference to the definition + /// is retained. + /// @warning This function is locked during callbacks. + b2Body* CreateBody(const b2BodyDef* def); + + /// Destroy a rigid body given a definition. No reference to the definition + /// is retained. This function is locked during callbacks. + /// @warning This automatically deletes all associated shapes and joints. + /// @warning This function is locked during callbacks. + void DestroyBody(b2Body* body); + + /// Create a joint to constrain bodies together. No reference to the definition + /// is retained. This may cause the connected bodies to cease colliding. + /// @warning This function is locked during callbacks. + b2Joint* CreateJoint(const b2JointDef* def); + + /// Destroy a joint. This may cause the connected bodies to begin colliding. + /// @warning This function is locked during callbacks. + void DestroyJoint(b2Joint* joint); + + /// Take a time step. This performs collision detection, integration, + /// and constraint solution. + /// @param timeStep the amount of time to simulate, this should not vary. + /// @param velocityIterations for the velocity constraint solver. + /// @param positionIterations for the position constraint solver. + void Step( float32 timeStep, + int32 velocityIterations, + int32 positionIterations); + + /// Call this after you are done with time steps to clear the forces. You normally + /// call this after each call to Step, unless you are performing sub-steps. By default, + /// forces will be automatically cleared, so you don't need to call this function. + /// @see SetAutoClearForces + void ClearForces(); + + /// Call this to draw shapes and other debug draw data. + void DrawDebugData(); + + /// Query the world for all fixtures that potentially overlap the + /// provided AABB. + /// @param callback a user implemented callback class. + /// @param aabb the query box. + void QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const; + + /// Ray-cast the world for all fixtures in the path of the ray. Your callback + /// controls whether you get the closest point, any point, or n-points. + /// The ray-cast ignores shapes that contain the starting point. + /// @param callback a user implemented callback class. + /// @param point1 the ray starting point + /// @param point2 the ray ending point + void RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const; + + /// Get the world body list. With the returned body, use b2Body::GetNext to get + /// the next body in the world list. A NULL body indicates the end of the list. + /// @return the head of the world body list. + b2Body* GetBodyList(); + + /// Get the world joint list. With the returned joint, use b2Joint::GetNext to get + /// the next joint in the world list. A NULL joint indicates the end of the list. + /// @return the head of the world joint list. + b2Joint* GetJointList(); + + /// Get the world contact list. With the returned contact, use b2Contact::GetNext to get + /// the next contact in the world list. A NULL contact indicates the end of the list. + /// @return the head of the world contact list. + /// @warning contacts are + b2Contact* GetContactList(); + + /// Enable/disable warm starting. For testing. + void SetWarmStarting(bool flag) { m_warmStarting = flag; } + + /// Enable/disable continuous physics. For testing. + void SetContinuousPhysics(bool flag) { m_continuousPhysics = flag; } + + /// Get the number of broad-phase proxies. + int32 GetProxyCount() const; + + /// Get the number of bodies. + int32 GetBodyCount() const; + + /// Get the number of joints. + int32 GetJointCount() const; + + /// Get the number of contacts (each may have 0 or more contact points). + int32 GetContactCount() const; + + /// Change the global gravity vector. + void SetGravity(const b2Vec2& gravity); + + /// Get the global gravity vector. + b2Vec2 GetGravity() const; + + /// Is the world locked (in the middle of a time step). + bool IsLocked() const; + + /// Set flag to control automatic clearing of forces after each time step. + void SetAutoClearForces(bool flag); + + /// Get the flag that controls automatic clearing of forces after each time step. + bool GetAutoClearForces() const; + +private: + + // m_flags + enum + { + e_newFixture = 0x0001, + e_locked = 0x0002, + e_clearForces = 0x0004, + }; + + friend class b2Body; + friend class b2ContactManager; + friend class b2Controller; + + void Solve(const b2TimeStep& step); + void SolveTOI(); + void SolveTOI(b2Body* body); + + void DrawJoint(b2Joint* joint); + void DrawShape(b2Fixture* shape, const b2Transform& xf, const b2Color& color); + + b2BlockAllocator m_blockAllocator; + b2StackAllocator m_stackAllocator; + + int32 m_flags; + + b2ContactManager m_contactManager; + + b2Body* m_bodyList; + b2Joint* m_jointList; + + int32 m_bodyCount; + int32 m_jointCount; + + b2Vec2 m_gravity; + bool m_allowSleep; + + b2Body* m_groundBody; + + b2DestructionListener* m_destructionListener; + b2DebugDraw* m_debugDraw; + + // This is used to compute the time step ratio to + // support a variable time step. + float32 m_inv_dt0; + + // This is for debugging the solver. + bool m_warmStarting; + + // This is for debugging the solver. + bool m_continuousPhysics; +}; + +inline b2Body* b2World::GetBodyList() +{ + return m_bodyList; +} + +inline b2Joint* b2World::GetJointList() +{ + return m_jointList; +} + +inline b2Contact* b2World::GetContactList() +{ + return m_contactManager.m_contactList; +} + +inline int32 b2World::GetBodyCount() const +{ + return m_bodyCount; +} + +inline int32 b2World::GetJointCount() const +{ + return m_jointCount; +} + +inline int32 b2World::GetContactCount() const +{ + return m_contactManager.m_contactCount; +} + +inline void b2World::SetGravity(const b2Vec2& gravity) +{ + m_gravity = gravity; +} + +inline b2Vec2 b2World::GetGravity() const +{ + return m_gravity; +} + +inline bool b2World::IsLocked() const +{ + return (m_flags & e_locked) == e_locked; +} + +inline void b2World::SetAutoClearForces(bool flag) +{ + if (flag) + { + m_flags |= e_clearForces; + } + else + { + m_flags &= ~e_clearForces; + } +} + +/// Get the flag that controls automatic clearing of forces after each time step. +inline bool b2World::GetAutoClearForces() const +{ + return (m_flags & e_clearForces) == e_clearForces; +} + +#endif diff --git a/AndEngine/jni/Box2D/Dynamics/b2WorldCallbacks.cpp b/AndEngine/jni/Box2D/Dynamics/b2WorldCallbacks.cpp new file mode 100644 index 0000000..a1a1749 --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2WorldCallbacks.cpp @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "Box2D/Dynamics/b2WorldCallbacks.h" +#include "Box2D/Dynamics/b2Fixture.h" + +// Return true if contact calculations should be performed between these two shapes. +// If you implement your own collision filter you may want to build from this implementation. +bool b2ContactFilter::ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB) +{ + const b2Filter& filterA = fixtureA->GetFilterData(); + const b2Filter& filterB = fixtureB->GetFilterData(); + + if (filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0) + { + return filterA.groupIndex > 0; + } + + bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0; + return collide; +} + +b2DebugDraw::b2DebugDraw() +{ + m_drawFlags = 0; +} + +void b2DebugDraw::SetFlags(uint32 flags) +{ + m_drawFlags = flags; +} + +uint32 b2DebugDraw::GetFlags() const +{ + return m_drawFlags; +} + +void b2DebugDraw::AppendFlags(uint32 flags) +{ + m_drawFlags |= flags; +} + +void b2DebugDraw::ClearFlags(uint32 flags) +{ + m_drawFlags &= ~flags; +} diff --git a/AndEngine/jni/Box2D/Dynamics/b2WorldCallbacks.h b/AndEngine/jni/Box2D/Dynamics/b2WorldCallbacks.h new file mode 100644 index 0000000..75b8b2a --- /dev/null +++ b/AndEngine/jni/Box2D/Dynamics/b2WorldCallbacks.h @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B2_WORLD_CALLBACKS_H +#define B2_WORLD_CALLBACKS_H + +#include "Box2D/Common/b2Settings.h" + +struct b2Vec2; +struct b2Transform; +class b2Fixture; +class b2Body; +class b2Joint; +class b2Contact; +struct b2ContactPoint; +struct b2ContactResult; +struct b2Manifold; + +/// Joints and fixtures are destroyed when their associated +/// body is destroyed. Implement this listener so that you +/// may nullify references to these joints and shapes. +class b2DestructionListener +{ +public: + virtual ~b2DestructionListener() {} + + /// Called when any joint is about to be destroyed due + /// to the destruction of one of its attached bodies. + virtual void SayGoodbye(b2Joint* joint) = 0; + + /// Called when any fixture is about to be destroyed due + /// to the destruction of its parent body. + virtual void SayGoodbye(b2Fixture* fixture) = 0; +}; + +/// Implement this class to provide collision filtering. In other words, you can implement +/// this class if you want finer control over contact creation. +class b2ContactFilter +{ +public: + virtual ~b2ContactFilter() {} + + /// Return true if contact calculations should be performed between these two shapes. + /// @warning for performance reasons this is only called when the AABBs begin to overlap. + virtual bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB); +}; + +/// Contact impulses for reporting. Impulses are used instead of forces because +/// sub-step forces may approach infinity for rigid body collisions. These +/// match up one-to-one with the contact points in b2Manifold. +struct b2ContactImpulse +{ + float32 normalImpulses[b2_maxManifoldPoints]; + float32 tangentImpulses[b2_maxManifoldPoints]; +}; + +/// Implement this class to get contact information. You can use these results for +/// things like sounds and game logic. You can also get contact results by +/// traversing the contact lists after the time step. However, you might miss +/// some contacts because continuous physics leads to sub-stepping. +/// Additionally you may receive multiple callbacks for the same contact in a +/// single time step. +/// You should strive to make your callbacks efficient because there may be +/// many callbacks per time step. +/// @warning You cannot create/destroy Box2D entities inside these callbacks. +class b2ContactListener +{ +public: + virtual ~b2ContactListener() {} + + /// Called when two fixtures begin to touch. + virtual void BeginContact(b2Contact* contact) { B2_NOT_USED(contact); } + + /// Called when two fixtures cease to touch. + virtual void EndContact(b2Contact* contact) { B2_NOT_USED(contact); } + + /// This is called after a contact is updated. This allows you to inspect a + /// contact before it goes to the solver. If you are careful, you can modify the + /// contact manifold (e.g. disable contact). + /// A copy of the old manifold is provided so that you can detect changes. + /// Note: this is called only for awake bodies. + /// Note: this is called even when the number of contact points is zero. + /// Note: this is not called for sensors. + /// Note: if you set the number of contact points to zero, you will not + /// get an EndContact callback. However, you may get a BeginContact callback + /// the next step. + virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) + { + B2_NOT_USED(contact); + B2_NOT_USED(oldManifold); + } + + /// This lets you inspect a contact after the solver is finished. This is useful + /// for inspecting impulses. + /// Note: the contact manifold does not include time of impact impulses, which can be + /// arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly + /// in a separate data structure. + /// Note: this is only called for contacts that are touching, solid, and awake. + virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) + { + B2_NOT_USED(contact); + B2_NOT_USED(impulse); + } +}; + +/// Callback class for AABB queries. +/// See b2World::Query +class b2QueryCallback +{ +public: + virtual ~b2QueryCallback() {} + + /// Called for each fixture found in the query AABB. + /// @return false to terminate the query. + virtual bool ReportFixture(b2Fixture* fixture) = 0; +}; + +/// Callback class for ray casts. +/// See b2World::RayCast +class b2RayCastCallback +{ +public: + virtual ~b2RayCastCallback() {} + + /// Called for each fixture found in the query. You control how the ray cast + /// proceeds by returning a float: + /// return -1: ignore this fixture and continue + /// return 0: terminate the ray cast + /// return fraction: clip the ray to this point + /// return 1: don't clip the ray and continue + /// @param fixture the fixture hit by the ray + /// @param point the point of initial intersection + /// @param normal the normal vector at the point of intersection + /// @return -1 to filter, 0 to terminate, fraction to clip the ray for + /// closest hit, 1 to continue + virtual float32 ReportFixture( b2Fixture* fixture, const b2Vec2& point, + const b2Vec2& normal, float32 fraction) = 0; +}; + +/// Color for debug drawing. Each value has the range [0,1]. +struct b2Color +{ + b2Color() {} + b2Color(float32 r, float32 g, float32 b) : r(r), g(g), b(b) {} + void Set(float32 ri, float32 gi, float32 bi) { r = ri; g = gi; b = bi; } + float32 r, g, b; +}; + +/// Implement and register this class with a b2World to provide debug drawing of physics +/// entities in your game. +class b2DebugDraw +{ +public: + b2DebugDraw(); + + virtual ~b2DebugDraw() {} + + enum + { + e_shapeBit = 0x0001, ///< draw shapes + e_jointBit = 0x0002, ///< draw joint connections + e_aabbBit = 0x0004, ///< draw axis aligned bounding boxes + e_pairBit = 0x0008, ///< draw broad-phase pairs + e_centerOfMassBit = 0x0010, ///< draw center of mass frame + }; + + /// Set the drawing flags. + void SetFlags(uint32 flags); + + /// Get the drawing flags. + uint32 GetFlags() const; + + /// Append flags to the current flags. + void AppendFlags(uint32 flags); + + /// Clear flags from the current flags. + void ClearFlags(uint32 flags); + + /// Draw a closed polygon provided in CCW order. + virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0; + + /// Draw a solid closed polygon provided in CCW order. + virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0; + + /// Draw a circle. + virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0; + + /// Draw a solid circle. + virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0; + + /// Draw a line segment. + virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0; + + /// Draw a transform. Choose your own length scale. + /// @param xf a transform. + virtual void DrawTransform(const b2Transform& xf) = 0; + +protected: + uint32 m_drawFlags; +}; + +#endif diff --git a/AndEngine/jni/Box2D/Fixture.cpp b/AndEngine/jni/Box2D/Fixture.cpp new file mode 100644 index 0000000..56a2706 --- /dev/null +++ b/AndEngine/jni/Box2D/Fixture.cpp @@ -0,0 +1,185 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "Box2D.h" +#include "Fixture.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetType +(JNIEnv *, jobject, jlong addr) +{ + b2Fixture* fixture = (b2Fixture*)addr; + b2Shape::Type type = fixture->GetType(); + switch( type ) + { + case b2Shape::e_circle: return 0; + case b2Shape::e_polygon: return 1; + default: + return b2Shape::e_unknown; + } +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetSensor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetSensor +(JNIEnv *, jobject, jlong addr, jboolean sensor) +{ + b2Fixture* fixture = (b2Fixture*)addr; + fixture->SetSensor(sensor); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniIsSensor + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniIsSensor + (JNIEnv *, jobject, jlong addr) +{ + b2Fixture* fixture = (b2Fixture*)addr; + return fixture->IsSensor(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetFilterData + * Signature: (JSSS)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetFilterData + (JNIEnv *, jobject, jlong addr, jshort categoryBits, jshort maskBits, jshort groupIndex) +{ + b2Fixture* fixture = (b2Fixture*)addr; + b2Filter filter; + filter.categoryBits = categoryBits; + filter.maskBits = maskBits; + filter.groupIndex = groupIndex; + fixture->SetFilterData(filter); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetFilterData + * Signature: (J[S)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetFilterData + (JNIEnv *env, jobject, jlong addr, jshortArray filter) +{ + b2Fixture* fixture = (b2Fixture*)addr; + unsigned short* filterOut = (unsigned short*)env->GetPrimitiveArrayCritical(filter, 0); + b2Filter f = fixture->GetFilterData(); + filterOut[0] = f.maskBits; + filterOut[1] = f.categoryBits; + filterOut[2] = f.groupIndex; + env->ReleasePrimitiveArrayCritical(filter, filterOut, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetDensity + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetDensity + (JNIEnv *, jobject, jlong addr, jfloat density) +{ + b2Fixture* fixture = (b2Fixture*)addr; + fixture->SetDensity(density); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetDensity + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetDensity + (JNIEnv *, jobject, jlong addr) +{ + b2Fixture* fixture = (b2Fixture*)addr; + return fixture->GetDensity(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetFriction + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetFriction + (JNIEnv *, jobject, jlong addr) +{ + b2Fixture* fixture = (b2Fixture*)addr; + return fixture->GetFriction(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetFriction + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetFriction + (JNIEnv *, jobject, jlong addr, jfloat friction) +{ + b2Fixture* fixture = (b2Fixture*)addr; + fixture->SetFriction(friction); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetRestitution + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetRestitution + (JNIEnv *, jobject, jlong addr) +{ + b2Fixture* fixture = (b2Fixture*)addr; + return fixture->GetRestitution(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetRestitution + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetRestitution + (JNIEnv *, jobject, jlong addr, jfloat restitution) +{ + b2Fixture* fixture = (b2Fixture*)addr; + fixture->SetRestitution(restitution); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniTestPoint + * Signature: (JFF)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniTestPoint + (JNIEnv *, jobject, jlong addr, jfloat x, jfloat y) +{ + b2Fixture* fixture = (b2Fixture*)addr; + return fixture->TestPoint( b2Vec2( x, y ) ); +} + +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetShape + (JNIEnv *, jobject, jlong addr) +{ + b2Fixture* fixture = (b2Fixture*)addr; + return (jlong)fixture->GetShape(); +} diff --git a/AndEngine/jni/Box2D/Fixture.h b/AndEngine/jni/Box2D/Fixture.h new file mode 100644 index 0000000..5767f43 --- /dev/null +++ b/AndEngine/jni/Box2D/Fixture.h @@ -0,0 +1,117 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_Fixture */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_Fixture +#define _Included_com_badlogic_gdx_physics_box2d_Fixture +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetType + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetShape + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetShape + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetSensor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetSensor + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniIsSensor + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniIsSensor + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetFilterData + * Signature: (JSSS)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetFilterData + (JNIEnv *, jobject, jlong, jshort, jshort, jshort); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetFilterData + * Signature: (J[S)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetFilterData + (JNIEnv *, jobject, jlong, jshortArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniTestPoint + * Signature: (JFF)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniTestPoint + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetDensity + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetDensity + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetDensity + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetDensity + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetFriction + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetFriction + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetFriction + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetFriction + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniGetRestitution + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniGetRestitution + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Fixture + * Method: jniSetRestitution + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Fixture_jniSetRestitution + (JNIEnv *, jobject, jlong, jfloat); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/FrictionJoint.cpp b/AndEngine/jni/Box2D/FrictionJoint.cpp new file mode 100644 index 0000000..31b5375 --- /dev/null +++ b/AndEngine/jni/Box2D/FrictionJoint.cpp @@ -0,0 +1,65 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "FrictionJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniSetMaxForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniSetMaxForce + (JNIEnv *, jobject, jlong addr, jfloat maxForce) +{ + b2FrictionJoint* joint = (b2FrictionJoint*)addr; + joint->SetMaxForce( maxForce ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniGetMaxForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniGetMaxForce + (JNIEnv *, jobject, jlong addr) +{ + b2FrictionJoint* joint = (b2FrictionJoint*)addr; + return joint->GetMaxForce(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniSetMaxTorque + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniSetMaxTorque + (JNIEnv *, jobject, jlong addr, jfloat torque) +{ + b2FrictionJoint* joint = (b2FrictionJoint*)addr; + joint->SetMaxTorque( torque ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniGetMaxTorque + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniGetMaxTorque + (JNIEnv *, jobject, jlong addr) +{ + b2FrictionJoint* joint = (b2FrictionJoint*)addr; + return joint->GetMaxTorque(); +} diff --git a/AndEngine/jni/Box2D/FrictionJoint.h b/AndEngine/jni/Box2D/FrictionJoint.h new file mode 100644 index 0000000..69ccf69 --- /dev/null +++ b/AndEngine/jni/Box2D/FrictionJoint.h @@ -0,0 +1,60 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_FrictionJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_FrictionJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_FrictionJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniSetMaxForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniSetMaxForce + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniGetMaxForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniGetMaxForce + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniSetMaxTorque + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniSetMaxTorque + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_FrictionJoint + * Method: jniGetMaxTorque + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_FrictionJoint_jniGetMaxTorque + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/GearJoint.cpp b/AndEngine/jni/Box2D/GearJoint.cpp new file mode 100644 index 0000000..d46ce08 --- /dev/null +++ b/AndEngine/jni/Box2D/GearJoint.cpp @@ -0,0 +1,41 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "GearJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_GearJoint + * Method: jniSetRatio + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_GearJoint_jniSetRatio + (JNIEnv *, jobject, jlong addr, jfloat ratio) +{ + b2GearJoint* joint = (b2GearJoint*)addr; + joint->SetRatio( ratio ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_GearJoint + * Method: jniGetRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_GearJoint_jniGetRatio + (JNIEnv *, jobject, jlong addr) +{ + b2GearJoint* joint = (b2GearJoint*)addr; + return joint->GetRatio(); +} diff --git a/AndEngine/jni/Box2D/GearJoint.h b/AndEngine/jni/Box2D/GearJoint.h new file mode 100644 index 0000000..f5e9c7a --- /dev/null +++ b/AndEngine/jni/Box2D/GearJoint.h @@ -0,0 +1,44 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_GearJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_GearJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_GearJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_GearJoint + * Method: jniSetRatio + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_GearJoint_jniSetRatio + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_GearJoint + * Method: jniGetRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_GearJoint_jniGetRatio + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/Joint.cpp b/AndEngine/jni/Box2D/Joint.cpp new file mode 100644 index 0000000..67b15ff --- /dev/null +++ b/AndEngine/jni/Box2D/Joint.cpp @@ -0,0 +1,127 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "Joint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetType + (JNIEnv *, jobject, jlong addr) +{ + b2Joint* joint = (b2Joint*)addr; + return joint->GetType(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetBodyA + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetBodyA + (JNIEnv *, jobject, jlong addr) +{ + b2Joint* joint = (b2Joint*)addr; + return (jlong)joint->GetBodyA(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetBodyB + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetBodyB + (JNIEnv *, jobject, jlong addr) +{ + b2Joint* joint = (b2Joint*)addr; + return (jlong)joint->GetBodyB(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetAnchorA + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetAnchorA + (JNIEnv *env, jobject, jlong addr, jfloatArray anchorA) +{ + b2Joint* joint = (b2Joint*)addr; + float* anchorAOut = (float*)env->GetPrimitiveArrayCritical(anchorA, 0); + b2Vec2 a = joint->GetAnchorA(); + anchorAOut[0] = a.x; + anchorAOut[1] = a.y; + env->ReleasePrimitiveArrayCritical(anchorA, anchorAOut, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetAnchorB + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetAnchorB + (JNIEnv *env, jobject, jlong addr, jfloatArray anchorB) +{ + b2Joint* joint = (b2Joint*)addr; + float* anchorBOut = (float*)env->GetPrimitiveArrayCritical(anchorB, 0); + b2Vec2 a = joint->GetAnchorB(); + anchorBOut[0] = a.x; + anchorBOut[1] = a.y; + env->ReleasePrimitiveArrayCritical(anchorB, anchorBOut, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetReactionForce + * Signature: (JF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetReactionForce + (JNIEnv *env, jobject, jlong addr, jfloat inv_dt, jfloatArray reactionForce) +{ + b2Joint* joint = (b2Joint*)addr; + float* reactionForceOut = (float*)env->GetPrimitiveArrayCritical(reactionForce, 0); + + b2Vec2 f = joint->GetReactionForce(inv_dt); + reactionForceOut[0] = f.x; + reactionForceOut[1] = f.y; + + env->ReleasePrimitiveArrayCritical(reactionForce, reactionForceOut, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetReactionTorque + * Signature: (JF)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetReactionTorque + (JNIEnv *, jobject, jlong addr, jfloat inv_dt) +{ + b2Joint* joint = (b2Joint*)addr; + return joint->GetReactionTorque(inv_dt); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniIsActive + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniIsActive + (JNIEnv *, jobject, jlong addr) +{ + b2Joint* joint = (b2Joint*)addr; + return joint->IsActive(); +} diff --git a/AndEngine/jni/Box2D/Joint.h b/AndEngine/jni/Box2D/Joint.h new file mode 100644 index 0000000..0792325 --- /dev/null +++ b/AndEngine/jni/Box2D/Joint.h @@ -0,0 +1,92 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_Joint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_Joint +#define _Included_com_badlogic_gdx_physics_box2d_Joint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetType + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetBodyA + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetBodyA + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetBodyB + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetBodyB + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetAnchorA + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetAnchorA + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetAnchorB + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetAnchorB + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetReactionForce + * Signature: (JF[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetReactionForce + (JNIEnv *, jobject, jlong, jfloat, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniGetReactionTorque + * Signature: (JF)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniGetReactionTorque + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Joint + * Method: jniIsActive + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_Joint_jniIsActive + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/LineJoint.cpp b/AndEngine/jni/Box2D/LineJoint.cpp new file mode 100644 index 0000000..2a63696 --- /dev/null +++ b/AndEngine/jni/Box2D/LineJoint.cpp @@ -0,0 +1,185 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "LineJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetJointTranslation + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetJointTranslation + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->GetJointTranslation(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetJointSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetJointSpeed + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->GetJointSpeed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniIsLimitEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniIsLimitEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->IsLimitEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniEnableLimit + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniEnableLimit + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + joint->EnableLimit( flag ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetLowerLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetLowerLimit + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->GetLowerLimit(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetUpperLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetUpperLimit + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->GetUpperLimit(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniSetLimits + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniSetLimits + (JNIEnv *, jobject, jlong addr, jfloat lowerLimit, jfloat upperLimit) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + joint->SetLimits( lowerLimit, upperLimit ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniIsMotorEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniIsMotorEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->IsMotorEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniEnableMotor + * Signature: (JZ)Z + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniEnableMotor + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + joint->EnableMotor(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniSetMotorEnabled + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniSetMotorSpeed + (JNIEnv *, jobject, jlong addr, jfloat speed) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + joint->SetMotorSpeed( speed ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetMotorSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetMotorSpeed + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->GetMotorSpeed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniSetMaxMotorForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniSetMaxMotorForce + (JNIEnv *, jobject, jlong addr, jfloat force) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + joint->SetMaxMotorForce( force ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetMaxMotorForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetMaxMotorForce + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return 0; // FIXME this is not a bug, the method just isn't defined in b2LineJoint. strange shit +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetMotorForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetMotorForce + (JNIEnv *, jobject, jlong addr) +{ + b2LineJoint* joint = (b2LineJoint*)addr; + return joint->GetMotorForce(); +} diff --git a/AndEngine/jni/Box2D/LineJoint.h b/AndEngine/jni/Box2D/LineJoint.h new file mode 100644 index 0000000..1224242 --- /dev/null +++ b/AndEngine/jni/Box2D/LineJoint.h @@ -0,0 +1,125 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_LineJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_LineJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_LineJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetJointTranslation + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetJointTranslation + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetJointSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetJointSpeed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniIsLimitEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniIsLimitEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniEnableLimit + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniEnableLimit + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetLowerLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetLowerLimit + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetUpperLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetUpperLimit + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniSetLimits + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniSetLimits + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniIsMotorEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniIsMotorEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniEnableMotor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniEnableMotor + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniSetMotorSpeed + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniSetMotorSpeed + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetMotorSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetMotorSpeed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniSetMaxMotorForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniSetMaxMotorForce + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetMaxMotorForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetMaxMotorForce + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_LineJoint + * Method: jniGetMotorForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_LineJoint_jniGetMotorForce + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/MouseJoint.cpp b/AndEngine/jni/Box2D/MouseJoint.cpp new file mode 100644 index 0000000..aa8e6ca --- /dev/null +++ b/AndEngine/jni/Box2D/MouseJoint.cpp @@ -0,0 +1,116 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "MouseJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetTarget + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetTarget + (JNIEnv *, jobject, jlong addr, jfloat x, jfloat y) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + joint->SetTarget( b2Vec2(x, y ) ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetTarget + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetTarget + (JNIEnv *env, jobject, jlong addr, jfloatArray target) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + float* tmp = (float*)env->GetPrimitiveArrayCritical(target, 0); + tmp[0] = joint->GetTarget().x; + tmp[1] = joint->GetTarget().y; + env->ReleasePrimitiveArrayCritical( target, tmp, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetMaxForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetMaxForce + (JNIEnv *, jobject, jlong addr, jfloat force ) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + joint->SetMaxForce( force ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetMaxForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetMaxForce + (JNIEnv *, jobject, jlong addr) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + return joint->GetMaxForce(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetFrequency + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetFrequency + (JNIEnv *, jobject, jlong addr, jfloat hz) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + joint->SetFrequency(hz); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetFrequency + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetFrequency + (JNIEnv *, jobject, jlong addr) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + return joint->GetFrequency(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetDampingRatio + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetDampingRatio + (JNIEnv *, jobject, jlong addr, jfloat ratio) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + joint->SetDampingRatio( ratio ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetDampingRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetDampingRatio + (JNIEnv *, jobject, jlong addr) +{ + b2MouseJoint* joint = (b2MouseJoint*)addr; + return joint->GetDampingRatio(); +} diff --git a/AndEngine/jni/Box2D/MouseJoint.h b/AndEngine/jni/Box2D/MouseJoint.h new file mode 100644 index 0000000..c9eeecd --- /dev/null +++ b/AndEngine/jni/Box2D/MouseJoint.h @@ -0,0 +1,92 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_MouseJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_MouseJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_MouseJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetTarget + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetTarget + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetTarget + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetTarget + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetMaxForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetMaxForce + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetMaxForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetMaxForce + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetFrequency + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetFrequency + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetFrequency + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetFrequency + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniSetDampingRatio + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniSetDampingRatio + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_MouseJoint + * Method: jniGetDampingRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_MouseJoint_jniGetDampingRatio + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/PolygonShape.cpp b/AndEngine/jni/Box2D/PolygonShape.cpp new file mode 100644 index 0000000..9a82c0c --- /dev/null +++ b/AndEngine/jni/Box2D/PolygonShape.cpp @@ -0,0 +1,113 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "PolygonShape.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: newPolygonShape + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_newPolygonShape +(JNIEnv *, jobject) +{ + b2PolygonShape* poly = new b2PolygonShape(); + return (jlong)poly; +} + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSet + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSet +(JNIEnv *env, jobject, jlong addr, jfloatArray verticesIn) +{ + b2PolygonShape* poly = (b2PolygonShape*)addr; + int numVertices = env->GetArrayLength(verticesIn) / 2; + float* vertices = (float*)env->GetPrimitiveArrayCritical(verticesIn, 0); + b2Vec2* verticesOut = new b2Vec2[numVertices]; + for( int i = 0; i < numVertices; i++ ) + verticesOut[i] = b2Vec2(vertices[i<<1], vertices[(i<<1)+1]); + poly->Set( verticesOut, numVertices ); + delete verticesOut; + env->ReleasePrimitiveArrayCritical(verticesIn, vertices, 0 ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSetAsBox + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSetAsBox__JFF +(JNIEnv *, jobject, jlong addr, jfloat hx, jfloat hy) +{ + b2PolygonShape* poly = (b2PolygonShape*)addr; + poly->SetAsBox(hx, hy); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSetAsBox + * Signature: (JFFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSetAsBox__JFFFFF +(JNIEnv *, jobject, jlong addr, jfloat hx, jfloat hy, jfloat centerX, jfloat centerY, jfloat angle) +{ + b2PolygonShape* poly = (b2PolygonShape*)addr; + poly->SetAsBox( hx, hy, b2Vec2( centerX, centerY ), angle ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSetAsEdge + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSetAsEdge +(JNIEnv *, jobject, jlong addr, jfloat v1x, jfloat v1y, jfloat v2x, jfloat v2y) +{ + b2PolygonShape* poly = (b2PolygonShape*)addr; + poly->SetAsEdge(b2Vec2(v1x, v1y), b2Vec2(v2x,v2y)); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniGetVertexCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniGetVertexCount + (JNIEnv *, jobject, jlong addr) +{ + b2PolygonShape* poly = (b2PolygonShape*)addr; + return poly->GetVertexCount(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniGetVertex + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniGetVertex + (JNIEnv *env, jobject, jlong addr, jint index, jfloatArray verts) +{ + b2PolygonShape* poly = (b2PolygonShape*)addr; + const b2Vec2 v = poly->GetVertex( index ); + float* vertices = (float*)env->GetPrimitiveArrayCritical(verts, 0); + vertices[0] = v.x; + vertices[1] = v.y; + env->ReleasePrimitiveArrayCritical(verts, vertices, 0 ); +} + diff --git a/AndEngine/jni/Box2D/PolygonShape.h b/AndEngine/jni/Box2D/PolygonShape.h new file mode 100644 index 0000000..2d0f525 --- /dev/null +++ b/AndEngine/jni/Box2D/PolygonShape.h @@ -0,0 +1,69 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_PolygonShape */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_PolygonShape +#define _Included_com_badlogic_gdx_physics_box2d_PolygonShape +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: newPolygonShape + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_newPolygonShape + (JNIEnv *, jobject); + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSet + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSet + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSetAsBox + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSetAsBox__JFF + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSetAsBox + * Signature: (JFFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSetAsBox__JFFFFF + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniSetAsEdge + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniSetAsEdge + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniGetVertexCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniGetVertexCount + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_PolygonShape + * Method: jniGetVertex + * Signature: (JI[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_PolygonShape_jniGetVertex + (JNIEnv *, jobject, jlong, jint, jfloatArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/PrismaticJoint.cpp b/AndEngine/jni/Box2D/PrismaticJoint.cpp new file mode 100644 index 0000000..414a801 --- /dev/null +++ b/AndEngine/jni/Box2D/PrismaticJoint.cpp @@ -0,0 +1,173 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "PrismaticJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetJointTranslation + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetJointTranslation + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->GetJointTranslation(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetJointSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetJointSpeed + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->GetJointSpeed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniIsLimitEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniIsLimitEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->IsLimitEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniEnableLimit + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniEnableLimit + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + joint->EnableLimit(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetLowerLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetLowerLimit + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->GetLowerLimit(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetUpperLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetUpperLimit + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->GetUpperLimit(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniSetLimits + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniSetLimits + (JNIEnv *, jobject, jlong addr, jfloat lower, jfloat upper ) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + joint->SetLimits(lower, upper ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniIsMotorEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniIsMotorEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->IsMotorEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniEnableMotor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniEnableMotor + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + joint->EnableMotor(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniSetMotorSpeed + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniSetMotorSpeed + (JNIEnv *, jobject, jlong addr, jfloat speed) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + joint->SetMotorSpeed(speed); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetMotorSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetMotorSpeed + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->GetMotorSpeed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniSetMaxMotorForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniSetMaxMotorForce + (JNIEnv *, jobject, jlong addr, jfloat force) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + joint->SetMaxMotorForce(force); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetMotorForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetMotorForce + (JNIEnv *, jobject, jlong addr) +{ + b2PrismaticJoint* joint = (b2PrismaticJoint*)addr; + return joint->GetMotorForce(); +} diff --git a/AndEngine/jni/Box2D/PrismaticJoint.h b/AndEngine/jni/Box2D/PrismaticJoint.h new file mode 100644 index 0000000..5ef75ef --- /dev/null +++ b/AndEngine/jni/Box2D/PrismaticJoint.h @@ -0,0 +1,132 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_PrismaticJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetJointTranslation + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetJointTranslation + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetJointSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetJointSpeed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniIsLimitEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniIsLimitEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniEnableLimit + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniEnableLimit + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetLowerLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetLowerLimit + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetUpperLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetUpperLimit + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniSetLimits + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniSetLimits + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniIsMotorEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniIsMotorEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniEnableMotor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniEnableMotor + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniSetMotorSpeed + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniSetMotorSpeed + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetMotorSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetMotorSpeed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniSetMaxMotorForce + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniSetMaxMotorForce + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PrismaticJoint + * Method: jniGetMotorForce + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PrismaticJoint_jniGetMotorForce + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/PulleyJoint.cpp b/AndEngine/jni/Box2D/PulleyJoint.cpp new file mode 100644 index 0000000..790d6a2 --- /dev/null +++ b/AndEngine/jni/Box2D/PulleyJoint.cpp @@ -0,0 +1,83 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "PulleyJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetGroundAnchorA + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetGroundAnchorA + (JNIEnv *env, jobject, jlong addr, jfloatArray anchor) +{ + b2PulleyJoint* joint = (b2PulleyJoint*)addr; + float* tmp = (float*)env->GetPrimitiveArrayCritical(anchor, 0); + tmp[0] = joint->GetGroundAnchorA().x; + tmp[1] = joint->GetGroundAnchorA().y; + env->ReleasePrimitiveArrayCritical( anchor, tmp, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetGroundAnchorB + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetGroundAnchorB + (JNIEnv *env, jobject, jlong addr, jfloatArray anchor) +{ + b2PulleyJoint* joint = (b2PulleyJoint*)addr; + float* tmp = (float*)env->GetPrimitiveArrayCritical(anchor, 0); + tmp[0] = joint->GetGroundAnchorB().x; + tmp[1] = joint->GetGroundAnchorB().y; + env->ReleasePrimitiveArrayCritical( anchor, tmp, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetLength1 + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetLength1 + (JNIEnv *, jobject, jlong addr) +{ + b2PulleyJoint* joint = (b2PulleyJoint*)addr; + return joint->GetLength1(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetLength2 + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetLength2 + (JNIEnv *, jobject, jlong addr) +{ + b2PulleyJoint* joint = (b2PulleyJoint*)addr; + return joint->GetLength2(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetRatio + (JNIEnv *, jobject, jlong addr) +{ + b2PulleyJoint* joint = (b2PulleyJoint*)addr; + return joint->GetRatio(); +} diff --git a/AndEngine/jni/Box2D/PulleyJoint.h b/AndEngine/jni/Box2D/PulleyJoint.h new file mode 100644 index 0000000..44db0a6 --- /dev/null +++ b/AndEngine/jni/Box2D/PulleyJoint.h @@ -0,0 +1,68 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_PulleyJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_PulleyJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_PulleyJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetGroundAnchorA + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetGroundAnchorA + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetGroundAnchorB + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetGroundAnchorB + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetLength1 + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetLength1 + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetLength2 + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetLength2 + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_PulleyJoint + * Method: jniGetRatio + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_PulleyJoint_jniGetRatio + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/RevoluteJoint.cpp b/AndEngine/jni/Box2D/RevoluteJoint.cpp new file mode 100644 index 0000000..5942374 --- /dev/null +++ b/AndEngine/jni/Box2D/RevoluteJoint.cpp @@ -0,0 +1,173 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "RevoluteJoint.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetJointAngle + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetJointAngle + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->GetJointAngle(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetJointSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetJointSpeed + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->GetJointSpeed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniIsLimitEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniIsLimitEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->IsLimitEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniEnableLimit + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniEnableLimit + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + joint->EnableLimit(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetLowerLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetLowerLimit + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->GetLowerLimit(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetUpperLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetUpperLimit + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->GetUpperLimit(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniSetLimits + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniSetLimits + (JNIEnv *, jobject, jlong addr, jfloat lower, jfloat upper) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + joint->SetLimits(lower, upper ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniIsMotorEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniIsMotorEnabled + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->IsMotorEnabled(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniEnableMotor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniEnableMotor + (JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + joint->EnableMotor(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniSetMotorSpeed + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniSetMotorSpeed + (JNIEnv *, jobject, jlong addr, jfloat speed) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + joint->SetMotorSpeed(speed); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetMotorSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetMotorSpeed + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->GetMotorSpeed(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniSetMaxMotorTorque + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniSetMaxMotorTorque + (JNIEnv *, jobject, jlong addr, jfloat torque) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + joint->SetMaxMotorTorque(torque); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetMotorTorque + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetMotorTorque + (JNIEnv *, jobject, jlong addr) +{ + b2RevoluteJoint* joint = (b2RevoluteJoint*)addr; + return joint->GetMotorTorque(); +} diff --git a/AndEngine/jni/Box2D/RevoluteJoint.h b/AndEngine/jni/Box2D/RevoluteJoint.h new file mode 100644 index 0000000..5f92dd0 --- /dev/null +++ b/AndEngine/jni/Box2D/RevoluteJoint.h @@ -0,0 +1,132 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_joints_RevoluteJoint */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint +#define _Included_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetJointAngle + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetJointAngle + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetJointSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetJointSpeed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniIsLimitEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniIsLimitEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniEnableLimit + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniEnableLimit + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetLowerLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetLowerLimit + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetUpperLimit + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetUpperLimit + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniSetLimits + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniSetLimits + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniIsMotorEnabled + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniIsMotorEnabled + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniEnableMotor + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniEnableMotor + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniSetMotorSpeed + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniSetMotorSpeed + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetMotorSpeed + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetMotorSpeed + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniSetMaxMotorTorque + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniSetMaxMotorTorque + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_joints_RevoluteJoint + * Method: jniGetMotorTorque + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_joints_RevoluteJoint_jniGetMotorTorque + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/Shape.cpp b/AndEngine/jni/Box2D/Shape.cpp new file mode 100644 index 0000000..91b9d58 --- /dev/null +++ b/AndEngine/jni/Box2D/Shape.cpp @@ -0,0 +1,63 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "Shape.h" + +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniGetRadius + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniGetRadius + (JNIEnv *, jobject, jlong addr) +{ + b2Shape* shape = (b2Shape*)addr; + return shape->m_radius; +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniSetRadius + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniSetRadius + (JNIEnv *, jobject, jlong addr, jfloat radius) +{ + b2Shape* shape = (b2Shape*)addr; + shape->m_radius = radius; +} + +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniDispose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniDispose + (JNIEnv *, jobject, jlong addr) +{ + b2Shape* shape = (b2Shape*)addr; + delete shape; +} + +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniGetType + (JNIEnv *, jclass, jlong addr) +{ + b2Shape* shape = (b2Shape*)addr; + if( shape->m_type == b2Shape::e_circle ) + return 0; + else + return 1; +} diff --git a/AndEngine/jni/Box2D/Shape.h b/AndEngine/jni/Box2D/Shape.h new file mode 100644 index 0000000..dae94be --- /dev/null +++ b/AndEngine/jni/Box2D/Shape.h @@ -0,0 +1,56 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_Shape */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_Shape +#define _Included_com_badlogic_gdx_physics_box2d_Shape +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniGetRadius + * Signature: (J)F + */ +JNIEXPORT jfloat JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniGetRadius + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniSetRadius + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniSetRadius + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniDispose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniDispose + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_Shape + * Method: jniGetType + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_Shape_jniGetType + (JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif +/* Header for class com_badlogic_gdx_physics_box2d_Shape_Type */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_Shape_Type +#define _Included_com_badlogic_gdx_physics_box2d_Shape_Type +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/Box2D/World.cpp b/AndEngine/jni/Box2D/World.cpp new file mode 100644 index 0000000..7e566b4 --- /dev/null +++ b/AndEngine/jni/Box2D/World.cpp @@ -0,0 +1,659 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "Box2D.h" +#include "World.h" +#ifdef ANDROID +#include +#endif + +static jclass worldClass = 0; +static jmethodID shouldCollideID = 0; +static jmethodID beginContactID = 0; +static jmethodID endContactID = 0; +static jmethodID reportFixtureID = 0; + +class CustomContactFilter: public b2ContactFilter +{ +private: + JNIEnv* env; + jobject obj; + +public: + CustomContactFilter( JNIEnv* env, jobject obj ) + { + this->env = env; + this->obj = obj; + } + + virtual bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB) + { + if( shouldCollideID != 0 ) + return env->CallBooleanMethod( obj, shouldCollideID, (jlong)fixtureA, (jlong)fixtureB ); + else + return true; + } +}; + +class CustomContactListener: public b2ContactListener +{ +private: + JNIEnv* env; + jobject obj; + +public: + CustomContactListener( JNIEnv* env, jobject obj ) + { + this->env = env; + this->obj = obj; + } + + /// Called when two fixtures begin to touch. + virtual void BeginContact(b2Contact* contact) + { + if( beginContactID != 0 ) + env->CallVoidMethod(obj, beginContactID, (jlong)contact ); + } + + /// Called when two fixtures cease to touch. + virtual void EndContact(b2Contact* contact) + { + if( endContactID != 0 ) + env->CallVoidMethod(obj, endContactID, (jlong)contact); + } +}; + +class CustomQueryCallback: public b2QueryCallback +{ +private: + JNIEnv* env; + jobject obj; + +public: + CustomQueryCallback( JNIEnv* env, jobject obj ) + { + this->env = env; + this->obj = obj; + } + + virtual bool ReportFixture( b2Fixture* fixture ) + { + return env->CallBooleanMethod(obj, reportFixtureID, (jlong)fixture ); + } +}; + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: newWorld + * Signature: (FFZ)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_newWorld +(JNIEnv * env, jobject obj, jfloat gravityX, jfloat gravityY, jboolean doSleep) +{ + worldClass = env->GetObjectClass(obj); + beginContactID = env->GetMethodID(worldClass, "beginContact", "(J)V" ); + endContactID = env->GetMethodID( worldClass, "endContact", "(J)V" ); + reportFixtureID = env->GetMethodID(worldClass, "reportFixture", "(J)Z" ); + shouldCollideID = env->GetMethodID( worldClass, "contactFilter", "(JJ)Z"); + + b2World* world = new b2World( b2Vec2( gravityX, gravityY ), doSleep ); + return (jlong)world; +} + +inline b2BodyType getBodyType( int type ) +{ + switch( type ) + { + case 0: return b2_staticBody; + case 1: return b2_kinematicBody; + case 2: return b2_dynamicBody; + default: + return b2_staticBody; + } +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateBody + * Signature: (JIFFFFFFFFZZZZZF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateBody +(JNIEnv *, jobject, jlong addr, jint type, jfloat positionX, jfloat positionY, jfloat angle, jfloat linearVelocityX, jfloat linearVelocityY, jfloat angularVelocity, jfloat linearDamping, jfloat angularDamping, jboolean allowSleep, jboolean awake, jboolean fixedRotation, jboolean bullet, jboolean active, jfloat inertiaScale) +{ + b2BodyDef bodyDef; + bodyDef.type = getBodyType(type); + bodyDef.position.Set( positionX, positionY ); + bodyDef.angle = angle; + bodyDef.linearVelocity.Set( linearVelocityX, linearVelocityY ); + bodyDef.angularVelocity = angularVelocity; + bodyDef.linearDamping = linearDamping; + bodyDef.angularDamping = angularDamping; + bodyDef.allowSleep = allowSleep; + bodyDef.awake = awake; + bodyDef.fixedRotation = fixedRotation; + bodyDef.bullet = bullet; + bodyDef.active = active; + bodyDef.inertiaScale = inertiaScale; + + b2World* world = (b2World*)addr; + b2Body* body = world->CreateBody( &bodyDef ); +//#ifdef ANDROID +// __android_log_write(ANDROID_LOG_ERROR,"Tag","HIIII"); +//#endif + return (jlong)body; +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniDestroyBody + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniDestroyBody +(JNIEnv *, jobject, jlong addr, jlong bodyAddr) +{ + b2World* world = (b2World*)addr; + b2Body* body = (b2Body*)bodyAddr; + world->DestroyBody(body); +} + +inline b2JointType getJointType( int type ) +{ + switch( type ) + { + case 0: return e_revoluteJoint; + case 1: return e_prismaticJoint; + case 2: return e_distanceJoint; + case 3: return e_pulleyJoint; + case 4: return e_mouseJoint; + case 5: return e_gearJoint; + case 6: return e_lineJoint; + case 7: return e_weldJoint; + case 8: return e_frictionJoint; + default: + return e_unknownJoint; + } +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateJoint + * Signature: (JIJJZ)J + */ +/*JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateJoint +(JNIEnv *, jobject, jlong addr, jint type, jlong bodyAAddr, jlong bodyBAddr, jboolean collideConnected ) +{ + b2World* world = (b2World*)addr; + b2Body* bodyA = (b2Body*)bodyAAddr; + b2Body* bodyB = (b2Body*)bodyBAddr; + + b2JointDef jointDef; + jointDef.bodyA = bodyA; + jointDef.bodyB = bodyB; + jointDef.collideConnected = collideConnected; + jointDef.type = getJointType( type ); + + b2Joint* joint = world->CreateJoint( &jointDef ); + return (jlong)joint; +}*/ + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateDistanceJoint + * Signature: (JJJZFFFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateDistanceJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, + jfloat length, jfloat frequencyHz, jfloat dampingRatio) +{ + b2World* world = (b2World*)addr; + b2DistanceJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.length = length; + def.frequencyHz = frequencyHz; + def.dampingRatio = dampingRatio; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateFrictionJoint + * Signature: (JJJZFFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateFrictionJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, + jfloat maxForce, jfloat maxTorque) +{ + b2World* world = (b2World*)addr; + b2FrictionJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.maxForce = maxForce; + def.maxTorque = maxTorque; + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateGearJoint + * Signature: (JJJZJJF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateGearJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jlong joint1, jlong joint2, jfloat ratio) +{ + b2World* world = (b2World*)addr; + b2GearJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.joint1 = (b2Joint*)joint1; + def.joint2 = (b2Joint*)joint2; + def.ratio = ratio; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateLineJoint + * Signature: (JJJZFFFFFFZFFZFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateLineJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, + jfloat localAxisAX, jfloat localAxisAY, jboolean enableLimit, jfloat lowerTranslation, jfloat upperTranslation, + jboolean enableMotor, jfloat maxMotorForce, jfloat motorSpeed) +{ + b2World* world = (b2World*)addr; + b2LineJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.localAxisA = b2Vec2(localAxisAX, localAxisAY); + def.enableLimit = enableLimit; + def.lowerTranslation = lowerTranslation; + def.upperTranslation = upperTranslation; + def.enableMotor = enableMotor; + def.maxMotorForce = maxMotorForce; + def.motorSpeed = motorSpeed; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateMouseJoint + * Signature: (JJJZFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateMouseJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat targetX, jfloat targetY, jfloat maxForce, jfloat frequencyHz, jfloat dampingRatio) +{ + b2World* world = (b2World*)addr; + b2MouseJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.target = b2Vec2( targetX, targetY ); + def.maxForce = maxForce; + def.frequencyHz = frequencyHz; + def.dampingRatio = dampingRatio; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreatePrismaticJoint + * Signature: (JJJZFFFFFFFZFFZFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreatePrismaticJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, + jfloat localAxisAX, jfloat localAxisAY, jfloat referenceAngle, jboolean enableLimit, jfloat lowerTranslation, jfloat upperTranslation, + jboolean enableMotor, jfloat maxMotorForce, jfloat motorSpeed) +{ + b2World* world = (b2World*)addr; + b2PrismaticJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.localAxis1 = b2Vec2( localAxisAX, localAxisAY ); + def.referenceAngle = referenceAngle; + def.enableLimit = enableLimit; + def.lowerTranslation = lowerTranslation; + def.upperTranslation = upperTranslation; + def.enableMotor = enableMotor; + def.maxMotorForce = maxMotorForce; + def.motorSpeed = motorSpeed; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreatePulleyJoint + * Signature: (JJJZFFFFFFFFFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreatePulleyJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat groundAnchorAX, jfloat groundAnchorAY, jfloat groundAnchorBX, jfloat groundAnchorBY, + jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, jfloat lengthA, jfloat maxLengthA, + jfloat lengthB, jfloat maxLengthB, jfloat ratio) +{ + b2World* world = (b2World*)addr; + b2PulleyJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.groundAnchorA = b2Vec2( groundAnchorAX, groundAnchorAY ); + def.groundAnchorB = b2Vec2( groundAnchorBX, groundAnchorBY ); + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.lengthA = lengthA; + def.maxLengthA = maxLengthA; + def.lengthB = lengthB; + def.maxLengthB = maxLengthB; + def.ratio = ratio; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateRevoluteJoint + * Signature: (JJJZFFFFFZFFZFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateRevoluteJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, + jfloat referenceAngle, jboolean enableLimit, jfloat lowerAngle, jfloat upperAngle, jboolean enableMotor, jfloat motorSpeed, jfloat maxMotorTorque) +{ + b2World* world = (b2World*)addr; + b2RevoluteJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.referenceAngle = referenceAngle; + def.enableLimit = enableLimit; + def.lowerAngle = lowerAngle; + def.upperAngle = upperAngle; + def.enableMotor = enableMotor; + def.motorSpeed = motorSpeed; + def.maxMotorTorque = maxMotorTorque; + + return (jlong)world->CreateJoint(&def); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateWeldJoint + * Signature: (JJJZFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateWeldJoint + (JNIEnv *, jobject, jlong addr, jlong bodyA, jlong bodyB, jboolean collideConnected, jfloat localAnchorAX, jfloat localAnchorAY, jfloat localAnchorBX, jfloat localAnchorBY, + jfloat referenceAngle) +{ + b2World* world = (b2World*)addr; + b2WeldJointDef def; + def.bodyA = (b2Body*)bodyA; + def.bodyB = (b2Body*)bodyB; + def.collideConnected = collideConnected; + def.localAnchorA = b2Vec2(localAnchorAX, localAnchorAY); + def.localAnchorB = b2Vec2(localAnchorBX, localAnchorBY); + def.referenceAngle = referenceAngle; + + return (jlong)world->CreateJoint(&def); +} + + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniDestroyJoint + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniDestroyJoint +(JNIEnv *, jobject, jlong addr, jlong jointAddr) +{ + b2World* world = (b2World*)addr; + b2Joint* joint = (b2Joint*)jointAddr; + + world->DestroyJoint( joint ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniStep + * Signature: (JFII)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniStep + (JNIEnv *env, jobject obj, jlong addr, jfloat timeStep, jint velocityIterations, jint positionIterations) +{ + b2World* world = (b2World*)addr; + CustomContactFilter contactFilter(env, obj); + CustomContactListener contactListener(env,obj); + world->SetContactFilter(&contactFilter); + world->SetContactListener(&contactListener); + world->Step( timeStep, velocityIterations, positionIterations ); + world->SetContactFilter(0); + world->SetContactListener(0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniQueryAABB + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniQueryAABB + (JNIEnv *env, jobject obj, jlong addr, jfloat lowX, jfloat lowY, jfloat upX, jfloat upY) +{ + b2World* world = (b2World*)addr; + b2AABB aabb; + aabb.lowerBound = b2Vec2( lowX, lowY ); + aabb.upperBound = b2Vec2( upX, upY ); + + CustomQueryCallback callback( env, obj ); + world->QueryAABB( &callback, aabb ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniClearForces + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniClearForces +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + world->ClearForces(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetWarmStarting + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetWarmStarting +(JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2World* world = (b2World*)addr; + world->SetWarmStarting(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetContiousPhysics + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetContiousPhysics +(JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2World* world = (b2World*)addr; + world->SetContinuousPhysics(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetProxyCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetProxyCount +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + return world->GetProxyCount(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetBodyCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetBodyCount +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + return world->GetBodyCount(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetJointcount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetJointcount +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + return world->GetJointCount(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetContactCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetContactCount +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + return world->GetContactCount(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetGravity + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetGravity +(JNIEnv *, jobject, jlong addr, jfloat gravityX, jfloat gravityY) +{ + b2World* world = (b2World*)addr; + world->SetGravity( b2Vec2( gravityX, gravityY ) ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetGravity + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetGravity +(JNIEnv *env, jobject, jlong addr, jfloatArray gravity) +{ + b2World* world = (b2World*)addr; + float* tmp = (float*)env->GetPrimitiveArrayCritical(gravity, 0); + b2Vec2 g = world->GetGravity(); + tmp[0] = g.x; + tmp[1] = g.y; + env->ReleasePrimitiveArrayCritical( gravity, tmp, 0); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniIsLocked + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniIsLocked +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + return world->IsLocked(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetAutoClearForces + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetAutoClearForces +(JNIEnv *, jobject, jlong addr, jboolean flag) +{ + b2World* world = (b2World*)addr; + world->SetAutoClearForces(flag); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetAutoClearForces + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetAutoClearForces +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)addr; + return world->GetAutoClearForces(); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetContactList + * Signature: (J[J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetContactList + (JNIEnv *env, jobject, jlong addr, jlongArray contacts) +{ + b2World* world = (b2World*)addr; + jlong* tmp = (jlong*)env->GetPrimitiveArrayCritical( contacts, 0 ); + + b2Contact* contact = world->GetContactList(); + int i = 0; + while( contact != 0 ) + { + tmp[i++] = (jlong)contact; + contact = contact->GetNext(); + } + + env->ReleasePrimitiveArrayCritical( contacts, tmp, 0 ); +} + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniDispose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniDispose +(JNIEnv *, jobject, jlong addr) +{ + b2World* world = (b2World*)(addr); + delete world; +} diff --git a/AndEngine/jni/Box2D/World.h b/AndEngine/jni/Box2D/World.h new file mode 100644 index 0000000..d64af0e --- /dev/null +++ b/AndEngine/jni/Box2D/World.h @@ -0,0 +1,260 @@ +/** +* Copyright 2010 Mario Zechner (contact@badlogicgames.com) +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_badlogic_gdx_physics_box2d_World */ + +#ifndef _Included_com_badlogic_gdx_physics_box2d_World +#define _Included_com_badlogic_gdx_physics_box2d_World +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: newWorld + * Signature: (FFZ)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_newWorld + (JNIEnv *, jobject, jfloat, jfloat, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateBody + * Signature: (JIFFFFFFFFZZZZZF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateBody + (JNIEnv *, jobject, jlong, jint, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jboolean, jboolean, jboolean, jboolean, jboolean, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniDestroyBody + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniDestroyBody + (JNIEnv *, jobject, jlong, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateDistanceJoint + * Signature: (JJJZFFFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateDistanceJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateFrictionJoint + * Signature: (JJJZFFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateFrictionJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateGearJoint + * Signature: (JJJZJJF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateGearJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jlong, jlong, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateLineJoint + * Signature: (JJJZFFFFFFZFFZFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateLineJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jboolean, jfloat, jfloat, jboolean, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateMouseJoint + * Signature: (JJJZFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateMouseJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreatePrismaticJoint + * Signature: (JJJZFFFFFFFZFFZFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreatePrismaticJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jboolean, jfloat, jfloat, jboolean, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreatePulleyJoint + * Signature: (JJJZFFFFFFFFFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreatePulleyJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateRevoluteJoint + * Signature: (JJJZFFFFFZFFZFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateRevoluteJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat, jboolean, jfloat, jfloat, jboolean, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniCreateWeldJoint + * Signature: (JJJZFFFFF)J + */ +JNIEXPORT jlong JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniCreateWeldJoint + (JNIEnv *, jobject, jlong, jlong, jlong, jboolean, jfloat, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniDestroyJoint + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniDestroyJoint + (JNIEnv *, jobject, jlong, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniStep + * Signature: (JFII)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniStep + (JNIEnv *, jobject, jlong, jfloat, jint, jint); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniClearForces + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniClearForces + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetWarmStarting + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetWarmStarting + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetContiousPhysics + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetContiousPhysics + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetProxyCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetProxyCount + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetBodyCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetBodyCount + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetJointcount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetJointcount + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetContactCount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetContactCount + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetGravity + * Signature: (JFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetGravity + (JNIEnv *, jobject, jlong, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetGravity + * Signature: (J[F)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetGravity + (JNIEnv *, jobject, jlong, jfloatArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniIsLocked + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniIsLocked + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniSetAutoClearForces + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniSetAutoClearForces + (JNIEnv *, jobject, jlong, jboolean); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetAutoClearForces + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetAutoClearForces + (JNIEnv *, jobject, jlong); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniQueryAABB + * Signature: (JFFFF)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniQueryAABB + (JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniGetContactList + * Signature: (J[J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniGetContactList + (JNIEnv *, jobject, jlong, jlongArray); + +/* + * Class: com_badlogic_gdx_physics_box2d_World + * Method: jniDispose + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_badlogic_gdx_physics_box2d_World_jniDispose + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/AndEngine/jni/build.bat b/AndEngine/jni/build.bat new file mode 100644 index 0000000..bd73fdd --- /dev/null +++ b/AndEngine/jni/build.bat @@ -0,0 +1,6 @@ +set shdir=%~dp0 +set "shdir=%shdir:\=/%" +c: +cd C:\cygwin\bin +bash --login -i -c '%shdir%build.sh' +pause \ No newline at end of file diff --git a/AndEngine/jni/build.sh b/AndEngine/jni/build.sh new file mode 100644 index 0000000..ac85d0b --- /dev/null +++ b/AndEngine/jni/build.sh @@ -0,0 +1,2 @@ +cd /cygdrive/e/android/AndEnginePhysicsBox2DExtension/ +/cygdrive/e/sdk/android-ndk-r4/ndk-build \ No newline at end of file diff --git a/AndEngine/libs/armeabi/libandenginephysicsbox2dextension.so b/AndEngine/libs/armeabi/libandenginephysicsbox2dextension.so new file mode 100644 index 0000000..e4d0623 Binary files /dev/null and b/AndEngine/libs/armeabi/libandenginephysicsbox2dextension.so differ diff --git a/AndEngine/push_google_code.bat b/AndEngine/push_google_code.bat new file mode 100644 index 0000000..0c437d6 --- /dev/null +++ b/AndEngine/push_google_code.bat @@ -0,0 +1,2 @@ +hg push https://andengine.googlecode.com/hg/ +pause \ No newline at end of file diff --git a/AndEngine/src/com/badlogic/gdx/math/Vector2.java b/AndEngine/src/com/badlogic/gdx/math/Vector2.java new file mode 100644 index 0000000..0eccab8 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/math/Vector2.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.math; + +/** + * Encapsulates a 2D vector. Allows chaining methods by returning a reference to itself + * @author badlogicgames@gmail.com + * + */ +public final class Vector2 { + /** static temporary vector **/ + private final static Vector2 tmp = new Vector2(); + + /** the x-component of this vector **/ + public float x; + /** the y-component of this vector **/ + public float y; + + /** + * Constructs a new vector at (0,0) + */ + public Vector2 () { + + } + + /** + * Constructs a vector with the given components + * @param x The x-component + * @param y The y-component + */ + public Vector2 (float x, float y) { + this.x = x; + this.y = y; + } + + /** + * Constructs a vector from the given vector + * @param v The vector + */ + public Vector2 (Vector2 v) { + set(v); + } + + /** + * @return a copy of this vector + */ + public Vector2 cpy () { + return new Vector2(this); + } + + /** + * @return The euclidian length + */ + public float len () { + return (float)Math.sqrt(x * x + y * y); + } + + /** + * @return The squared euclidian length + */ + public float len2 () { + return x * x + y * y; + } + + /** + * Sets this vector from the given vector + * @param v The vector + * @return This vector for chaining + */ + public Vector2 set (Vector2 v) { + x = v.x; + y = v.y; + return this; + } + + /** + * Sets the components of this vector + * @param x The x-component + * @param y The y-component + * @return This vector for chaining + */ + public Vector2 set (float x, float y) { + this.x = x; + this.y = y; + return this; + } + + /** + * Substracts the given vector from this vector. + * @param v The vector + * @return This vector for chaining + */ + public Vector2 sub (Vector2 v) { + x -= v.x; + y -= v.y; + return this; + } + + /** + * Normalizes this vector + * @return This vector for chaining + */ + public Vector2 nor () { + float len = len(); + if (len != 0) { + x /= len; + y /= len; + } + return this; + } + + /** + * Adds the given vector to this vector + * @param v The vector + * @return This vector for chaining + */ + public Vector2 add (Vector2 v) { + x += v.x; + y += v.y; + return this; + } + + /** + * Adds the given components to this vector + * @param x The x-component + * @param y The y-component + * @return This vector for chaining + */ + public Vector2 add (float x, float y) { + this.x += x; + this.y += y; + return this; + } + + /** + * @param v The other vector + * @return The dot product between this and the other vector + */ + public float dot (Vector2 v) { + return x * v.x + y * v.y; + } + + /** + * Multiplies this vector by a scalar + * @param scalar The scalar + * @return This vector for chaining + */ + public Vector2 mul (float scalar) { + x *= scalar; + y *= scalar; + return this; + } + + /** + * @param v The other vector + * @return the distance between this and the other vector + */ + public float dst (Vector2 v) { + float x_d = v.x - x; + float y_d = v.y - y; + return (float)Math.sqrt(x_d * x_d + y_d * y_d); + } + + /** + * @param x The x-component of the other vector + * @param y The y-component of the other vector + * @return the distance between this and the other vector + */ + public float dst (float x, float y) { + float x_d = x - this.x; + float y_d = y - this.y; + return (float)Math.sqrt(x_d * x_d + y_d * y_d); + } + + /** + * @param v The other vector + * @return the squared distance between this and the other vector + */ + public float dst2 (Vector2 v) { + float x_d = v.x - x; + float y_d = v.y - y; + return x_d * x_d + y_d * y_d; + } + + public String toString () { + return "[" + x + ":" + y + "]"; + } + + /** + * Substracts the other vector from this vector. + * @param x The x-component of the other vector + * @param y The y-component of the other vector + * @return This vector for chaining + */ + public Vector2 sub (float x, float y) { + this.x -= x; + this.y -= y; + return this; + } + + /** + * @return a temporary copy of this vector. Use with care as this is backed by a single static Vector2 instance. v1.tmp().add( + * v2.tmp() ) will not work! + */ + public Vector2 tmp () { + return tmp.set(this); + } + + /** + * @param v the other vector + * @return The cross product between this and the other vector + */ + public float cross(final Vector2 v) { + return this.x * v.y - v.x * this.y; + } + /** + * @return The manhattan length + */ + public float lenManhattan() { + return Math.abs(this.x) + Math.abs(this.y); + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Body.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Body.java new file mode 100644 index 0000000..bb95c31 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Body.java @@ -0,0 +1,613 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import java.util.ArrayList; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; + +/** + * A rigid body. These are created via World.CreateBody. + * @author mzechner + * + */ +public class Body { + /** the address of the body **/ + protected final long addr; + + /** temporary float array **/ + private final float[] tmp = new float[4]; + + /** World **/ + private final World world; + + /** Fixtures of this body **/ + private ArrayList fixtures = new ArrayList(2); + + /** Joints of this body **/ + protected ArrayList joints = new ArrayList(2); + + /** user data **/ + private Object userData; + + /** + * Constructs a new body with the given address + * @param world the world + * @param addr the address + */ + protected Body (World world, long addr) { + this.world = world; + this.addr = addr; + } + + /** + * Creates a fixture and attach it to this body. Use this function if you need to set some fixture parameters, like friction. + * Otherwise you can create the fixture directly from a shape. If the density is non-zero, this function automatically updates + * the mass of the body. Contacts are not created until the next time step. + * @param def the fixture definition. + * @warning This function is locked during callbacks. + */ + public Fixture createFixture (FixtureDef def) { + Fixture fixture = new Fixture(this, jniCreateFixture(addr, def.shape.addr, def.friction, def.restitution, def.density, + def.isSensor, def.filter.categoryBits, def.filter.maskBits, def.filter.groupIndex)); + this.world.fixtures.put(fixture.addr, fixture); + this.fixtures.add(fixture); + return fixture; + } + + private native long jniCreateFixture (long addr, long shapeAddr, float friction, float restitution, float density, + boolean isSensor, short filterCategoryBits, short filterMaskBits, short filterGroupIndex); + + /** + * Creates a fixture from a shape and attach it to this body. This is a convenience function. Use b2FixtureDef if you need to + * set parameters like friction, restitution, user data, or filtering. If the density is non-zero, this function automatically + * updates the mass of the body. + * @param shape the shape to be cloned. + * @param density the shape density (set to zero for static bodies). + * @warning This function is locked during callbacks. + */ + public Fixture createFixture (Shape shape, float density) { + Fixture fixture = new Fixture(this, jniCreateFixture(addr, shape.addr, density)); + this.world.fixtures.put(fixture.addr, fixture); + this.fixtures.add(fixture); + return fixture; + } + + private native long jniCreateFixture (long addr, long shapeAddr, float density); + + /** + * Destroy a fixture. This removes the fixture from the broad-phase and destroys all contacts associated with this fixture. + * This will automatically adjust the mass of the body if the body is dynamic and the fixture has positive density. All + * fixtures attached to a body are implicitly destroyed when the body is destroyed. + * @param fixture the fixture to be removed. + * @warning This function is locked during callbacks. + */ + public void destroyFixture (Fixture fixture) { + jniDestroyFixture(addr, fixture.addr); + this.world.fixtures.remove(fixture.addr); + this.fixtures.remove(fixture); + } + + private native void jniDestroyFixture (long addr, long fixtureAddr); + + /** + * Set the position of the body's origin and rotation. This breaks any contacts and wakes the other bodies. Manipulating a + * body's transform may cause non-physical behavior. + * @param position the world position of the body's local origin. + * @param angle the world rotation in radians. + */ + public void setTransform (Vector2 position, float angle) { + jniSetTransform(addr, position.x, position.y, angle); + } + + private native void jniSetTransform (long addr, float positionX, float positionY, float angle); + + /** + * Get the body transform for the body's origin. FIXME + */ + private final Transform transform = new Transform(); + + public Transform getTransform () { + jniGetTransform(addr, transform.vals); + return transform; + } + + private native void jniGetTransform (long addr, float[] vals); + + private final Vector2 position = new Vector2(); + /** + * Get the world body origin position. + * @return the world position of the body's origin. + */ + public Vector2 getPosition () { + jniGetPosition(addr, tmp); + position.x = tmp[0]; + position.y = tmp[1]; + return position; + } + + private native void jniGetPosition (long addr, float[] position); + + /** + * Get the angle in radians. + * @return the current world rotation angle in radians. + */ + public float getAngle () { + return jniGetAngle(addr); + } + + private native float jniGetAngle (long addr); + + /** + * Get the world position of the center of mass. + */ + private final Vector2 worldCenter = new Vector2(); + + public Vector2 getWorldCenter () { + jniGetWorldCenter(addr, tmp); + worldCenter.x = tmp[0]; + worldCenter.y = tmp[1]; + return worldCenter; + } + + private native void jniGetWorldCenter (long addr, float[] worldCenter); + + /** + * Get the local position of the center of mass. + */ + private final Vector2 localCenter = new Vector2(); + + public Vector2 getLocalCenter () { + jniGetLocalCenter(addr, tmp); + localCenter.x = tmp[0]; + localCenter.y = tmp[1]; + return localCenter; + } + + private native void jniGetLocalCenter (long addr, float[] localCenter); + + /** + * Set the linear velocity of the center of mass. + */ + public void setLinearVelocity (Vector2 v) { + jniSetLinearVelocity(addr, v.x, v.y); + } + + private native void jniSetLinearVelocity (long addr, float x, float y); + + /** + * Get the linear velocity of the center of mass. + */ + private final Vector2 linearVelocity = new Vector2(); + + public Vector2 getLinearVelocity () { + jniGetLinearVelocity(addr, tmp); + linearVelocity.x = tmp[0]; + linearVelocity.y = tmp[1]; + return linearVelocity; + } + + private native void jniGetLinearVelocity (long addr, float[] tmpLinearVelocity); + + /** + * Set the angular velocity. + */ + public void setAngularVelocity (float omega) { + jniSetAngularVelocity(addr, omega); + } + + private native void jniSetAngularVelocity (long addr, float omega); + + /** + * Get the angular velocity. + */ + public float getAngularVelocity () { + return jniGetAngularVelocity(addr); + } + + private native float jniGetAngularVelocity (long addr); + + /** + * Apply a force at a world point. If the force is not applied at the center of mass, it will generate a torque and affect the + * angular velocity. This wakes up the body. + * @param force the world force vector, usually in Newtons (N). + * @param point the world position of the point of application. + */ + public void applyForce (Vector2 force, Vector2 point) { + jniApplyForce(addr, force.x, force.y, point.x, point.y); + } + + private native void jniApplyForce (long addr, float forceX, float forceY, float pointX, float pointY); + + /** + * Apply a torque. This affects the angular velocity without affecting the linear velocity of the center of mass. This wakes up + * the body. + * @param torque about the z-axis (out of the screen), usually in N-m. + */ + public void applyTorque (float torque) { + jniApplyTorque(addr, torque); + } + + private native void jniApplyTorque (long addr, float torque); + + /** + * Apply an impulse at a point. This immediately modifies the velocity. It also modifies the angular velocity if the point of + * application is not at the center of mass. This wakes up the body. + * @param impulse the world impulse vector, usually in N-seconds or kg-m/s. + * @param point the world position of the point of application. + */ + public void applyLinearImpulse (Vector2 impulse, Vector2 point) { + jniApplyLinearImpulse(addr, impulse.x, impulse.y, point.x, point.y); + } + + private native void jniApplyLinearImpulse (long addr, float impulseX, float impulseY, float pointX, float pointY); + + /** + * Apply an angular impulse. + * @param impulse the angular impulse in units of kg*m*m/s + */ + public void applyAngularImpulse (float impulse) { + jniApplyAngularImpulse(addr, impulse); + } + + private native void jniApplyAngularImpulse (long addr, float impulse); + + /** + * Get the total mass of the body. + * @return the mass, usually in kilograms (kg). + */ + public float getMass () { + return jniGetMass(addr); + } + + private native float jniGetMass (long addr); + + /** + * Get the rotational inertia of the body about the local origin. + * @return the rotational inertia, usually in kg-m^2. + */ + public float getInertia () { + return jniGetInertia(addr); + } + + private native float jniGetInertia (long addr); + + private final MassData massData = new MassData(); + /** + * Get the mass data of the body. + * @return a struct containing the mass, inertia and center of the body. + */ + public MassData getMassData () { + jniGetMassData(addr, tmp); + massData.mass = tmp[0]; + massData.center.x = tmp[1]; + massData.center.y = tmp[2]; + massData.I = tmp[3]; + return massData; + } + + private native void jniGetMassData (long addr, float[] massData); + + /** + * Set the mass properties to override the mass properties of the fixtures. Note that this changes the center of mass position. + * Note that creating or destroying fixtures can also alter the mass. This function has no effect if the body isn't dynamic. + * @param data the mass properties. + */ + public void setMassData (MassData data) { + jniSetMassData(addr, data.mass, data.center.x, data.center.y, data.I); + } + + private native void jniSetMassData (long addr, float mass, float centerX, float centerY, float I); + + /** + * This resets the mass properties to the sum of the mass properties of the fixtures. This normally does not need to be called + * unless you called SetMassData to override the mass and you later want to reset the mass. + */ + public void resetMassData () { + jniResetMassData(addr); + } + + private native void jniResetMassData (long addr); + + private final Vector2 localPoint = new Vector2(); + /** + * Get the world coordinates of a point given the local coordinates. + * @param localPoint a point on the body measured relative the the body's origin. + * @return the same point expressed in world coordinates. + */ + public Vector2 getWorldPoint (Vector2 localPoint) { + jniGetWorldPoint(addr, localPoint.x, localPoint.y, tmp); + this.localPoint.x = tmp[0]; + this.localPoint.y = tmp[1]; + return this.localPoint; + } + + private native void jniGetWorldPoint (long addr, float localPointX, float localPointY, float[] worldPoint); + + private final Vector2 worldVector = new Vector2(); + /** + * Get the world coordinates of a vector given the local coordinates. + * @param localVector a vector fixed in the body. + * @return the same vector expressed in world coordinates. + */ + public Vector2 getWorldVector (Vector2 localVector) { + jniGetWorldVector(addr, localVector.x, localVector.y, tmp); + worldVector.x = tmp[0]; + worldVector.y = tmp[1]; + return worldVector; + } + + private native void jniGetWorldVector (long addr, float localVectorX, float localVectorY, float[] worldVector); + + public final Vector2 localPoint2 = new Vector2(); + /** + * Gets a local point relative to the body's origin given a world point. + * @param worldPoint a point in world coordinates. + * @return the corresponding local point relative to the body's origin. + */ + public Vector2 getLocalPoint (Vector2 worldPoint) { + jniGetLocalPoint(addr, worldPoint.x, worldPoint.y, tmp); + localPoint2.x = tmp[0]; + localPoint2.y = tmp[1]; + return localPoint2; + } + + private native void jniGetLocalPoint (long addr, float worldPointX, float worldPointY, float[] localPoint); + + public final Vector2 localVector = new Vector2(); + /** + * Gets a local vector given a world vector. + * @param worldVector a vector in world coordinates. + * @return the corresponding local vector. + */ + public Vector2 getLocalVector (Vector2 worldVector) { + jniGetLocalVector(addr, worldVector.x, worldVector.y, tmp); + localVector.x = tmp[0]; + localVector.y = tmp[1]; + return localVector; + } + + private native void jniGetLocalVector (long addr, float worldVectorX, float worldVectorY, float[] worldVector); + + public final Vector2 linVelWorld = new Vector2(); + /** + * Get the world linear velocity of a world point attached to this body. + * @param worldPoint a point in world coordinates. + * @return the world velocity of a point. + */ + public Vector2 getLinearVelocityFromWorldPoint (Vector2 worldPoint) { + jniGetLinearVelocityFromWorldPoint(addr, worldPoint.x, worldPoint.y, tmp); + linVelWorld.x = tmp[0]; + linVelWorld.y = tmp[1]; + return linVelWorld; + } + + private native void jniGetLinearVelocityFromWorldPoint (long addr, float worldPointX, float worldPointY, float[] linVelWorld); + + public final Vector2 linVelLoc = new Vector2(); + /** + * Get the world velocity of a local point. + * @param localPoint a point in local coordinates. + * @return the world velocity of a point. + */ + public Vector2 getLinearVelocityFromLocalPoint (Vector2 localPoint) { + jniGetLinearVelocityFromLocalPoint(addr, localPoint.x, localPoint.y, tmp); + linVelLoc.x = tmp[0]; + linVelLoc.y = tmp[1]; + return linVelLoc; + } + + private native void jniGetLinearVelocityFromLocalPoint (long addr, float localPointX, float localPointY, float[] linVelLoc); + + /** + * Get the linear damping of the body. + */ + public float getLinearDamping () { + return jniGetLinearDamping(addr); + } + + private native float jniGetLinearDamping (long add); + + /** + * Set the linear damping of the body. + */ + public void setLinearDamping (float linearDamping) { + jniSetLinearDamping(addr, linearDamping); + } + + private native void jniSetLinearDamping (long addr, float linearDamping); + + /** + * Get the angular damping of the body. + */ + public float getAngularDamping () { + return jniGetAngularDamping(addr); + } + + private native float jniGetAngularDamping (long addr); + + /** + * Set the angular damping of the body. + */ + public void setAngularDamping (float angularDamping) { + jniSetAngularDamping(addr, angularDamping); + } + + private native void jniSetAngularDamping (long addr, float angularDamping); + + /** + * Set the type of this body. This may alter the mass and velocity. + */ + public void setType (BodyType type) { + jniSetType(addr, type.getValue()); + } + + private native void jniSetType (long addr, int type); + + /** + * Get the type of this body. + */ + public BodyType getType () { + int type = jniGetType(addr); + if (type == 0) return BodyType.StaticBody; + if (type == 1) return BodyType.KinematicBody; + if (type == 2) return BodyType.DynamicBody; + return BodyType.StaticBody; + } + + private native int jniGetType (long addr); + + /** + * Should this body be treated like a bullet for continuous collision detection? + */ + public void setBullet (boolean flag) { + jniSetBullet(addr, flag); + } + + private native void jniSetBullet (long addr, boolean flag); + + /** + * Is this body treated like a bullet for continuous collision detection? + */ + public boolean isBullet () { + return jniIsBullet(addr); + } + + private native boolean jniIsBullet (long addr); + + /** + * You can disable sleeping on this body. If you disable sleeping, the + */ + public void setSleepingAllowed (boolean flag) { + jniSetSleepingAllowed(addr, flag); + } + + private native void jniSetSleepingAllowed (long addr, boolean flag); + + /** + * Is this body allowed to sleep + */ + public boolean isSleepingAllowed () { + return jniIsSleepingAllowed(addr); + } + + private native boolean jniIsSleepingAllowed (long addr); + + /** + * Set the sleep state of the body. A sleeping body has very low CPU cost. + * @param flag set to true to put body to sleep, false to wake it. + */ + public void setAwake (boolean flag) { + jniSetAwake(addr, flag); + } + + private native void jniSetAwake (long addr, boolean flag); + + /** + * Get the sleeping state of this body. + * @return true if the body is sleeping. + */ + public boolean isAwake () { + return jniIsAwake(addr); + } + + private native boolean jniIsAwake (long addr); + + /** + * Set the active state of the body. An inactive body is not simulated and cannot be collided with or woken up. If you pass a + * flag of true, all fixtures will be added to the broad-phase. If you pass a flag of false, all fixtures will be removed from + * the broad-phase and all contacts will be destroyed. Fixtures and joints are otherwise unaffected. You may continue to + * create/destroy fixtures and joints on inactive bodies. Fixtures on an inactive body are implicitly inactive and will not + * participate in collisions, ray-casts, or queries. Joints connected to an inactive body are implicitly inactive. An inactive + * body is still owned by a b2World object and remains in the body list. + */ + public void setActive (boolean flag) { + jniSetActive(addr, flag); + } + + private native void jniSetActive (long addr, boolean flag); + + /** + * Get the active state of the body. + */ + public boolean isActive () { + return jniIsActive(addr); + } + + private native boolean jniIsActive (long addr); + + /** + * Set this body to have fixed rotation. This causes the mass to be reset. + */ + public void setFixedRotation (boolean flag) { + jniSetFixedRotation(addr, flag); + } + + private native void jniSetFixedRotation (long addr, boolean flag); + + /** + * Does this body have fixed rotation? + */ + public boolean isFixedRotation () { + return jniIsFixedRotation(addr); + } + + private native boolean jniIsFixedRotation (long addr); + + /** + * Get the list of all fixtures attached to this body. Do not modify the list! + */ + public ArrayList getFixtureList () { + return fixtures; + } + + /** + * Get the list of all joints attached to this body. Do not modify the list! + */ + public ArrayList getJointList () { + return joints; + } + + /** + * Get the list of all contacts attached to this body. + * @warning this list changes during the time step and you may miss some collisions if you don't use b2ContactListener. Do not + * modify the returned list! + */ +// ArrayList getContactList() +// { +// return contacts; +// } + + /** + * Get the parent world of this body. + */ + public World getWorld () { + return world; + } + + /** + * Get the user data + */ + public Object getUserData () { + return userData; + } + + /** + * Set the user data + */ + public void setUserData (Object userData) { + this.userData = userData; + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/BodyDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/BodyDef.java new file mode 100644 index 0000000..431c2b3 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/BodyDef.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +/** + * A body definition holds all the data needed to construct a rigid body. You can safely re-use body definitions. Shapes are added + * to a body after construction. + * + * @author mzechner + * + */ +public class BodyDef { + /** + * The body type. static: zero mass, zero velocity, may be manually moved kinematic: zero mass, non-zero velocity set by user, + * moved by solver dynamic: positive mass, non-zero velocity determined by forces, moved by solver + */ + public enum BodyType { + StaticBody(0), KinematicBody(1), DynamicBody(2); + + private int value; + + private BodyType (int value) { + this.value = value; + } + + public int getValue () { + return value; + } + }; + + /** + * The body type: static, kinematic, or dynamic. Note: if a dynamic body would have zero mass, the mass is set to one. + **/ + public BodyType type = BodyType.StaticBody; + + /** + * The world position of the body. Avoid creating bodies at the origin since this can lead to many overlapping shapes. + **/ + public final Vector2 position = new Vector2(); + + /** The world angle of the body in radians. **/ + public float angle = 0; + + /** The linear velocity of the body's origin in world co-ordinates. **/ + public final Vector2 linearVelocity = new Vector2(); + + /** The angular velocity of the body. **/ + public float angularVelocity = 0; + + /** + * Linear damping is use to reduce the linear velocity. The damping parameter can be larger than 1.0f but the damping effect + * becomes sensitive to the time step when the damping parameter is large. + **/ + public float linearDamping = 0; + + /** + * Angular damping is use to reduce the angular velocity. The damping parameter can be larger than 1.0f but the damping effect + * becomes sensitive to the time step when the damping parameter is large. + **/ + public float angularDamping = 0; + + /** + * Set this flag to false if this body should never fall asleep. Note that this increases CPU usage. + **/ + public boolean allowSleep = true; + + /** Is this body initially awake or sleeping? **/ + public boolean awake = true; + + /** Should this body be prevented from rotating? Useful for characters. **/ + public boolean fixedRotation = false; + + /** + * Is this a fast moving body that should be prevented from tunneling through other moving bodies? Note that all bodies are + * prevented from tunneling through kinematic and static bodies. This setting is only considered on dynamic bodies. + * @warning You should use this flag sparingly since it increases processing time. + **/ + public boolean bullet = false; + + /** Does this body start out active? **/ + public boolean active = true; + + /** Experimental: scales the inertia tensor. **/ + public float inertiaScale = 1; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/CircleShape.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/CircleShape.java new file mode 100644 index 0000000..0384c90 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/CircleShape.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +/** + * A circle shape. + * @author mzechner + * + */ +public class CircleShape extends Shape { + public CircleShape () { + addr = newCircleShape(); + } + + private native long newCircleShape (); + + protected CircleShape (long addr) { + this.addr = addr; + } + + /** + * {@inheritDoc} + */ + @Override public Type getType () { + return Type.Circle; + } + + /** + * Returns the position of the shape + */ + private final float[] tmp = new float[2]; + private final Vector2 position = new Vector2(); + + public Vector2 getPosition () { + jniGetPosition(addr, tmp); + position.x = tmp[0]; + position.y = tmp[1]; + return position; + } + + private native void jniGetPosition (long addr, float[] position); + + /** + * Sets the position of the shape + */ + public void setPosition (Vector2 position) { + jniSetPosition(addr, position.x, position.y); + } + + private native void jniSetPosition (long addr, float positionX, float positionY); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Contact.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Contact.java new file mode 100644 index 0000000..a0d8892 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Contact.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +/** + * The class manages contact between two shapes. A contact exists for each overlapping AABB in the broad-phase (except if + * filtered). Therefore a contact object may exist that has no contact points. + * @author mzechner + * + */ +public class Contact { + /** the address **/ + protected long addr; + + /** the world **/ + protected World world; + + /** the world manifold **/ + protected final WorldManifold worldManifold = new WorldManifold(); + + protected Contact (World world, long addr) { + this.addr = addr; + this.world = world; + } + + /** + * Get the world manifold. + */ + private final float[] tmp = new float[6]; + + public WorldManifold GetWorldManifold () { + int numContactPoints = jniGetWorldManifold(addr, tmp); + + worldManifold.numContactPoints = numContactPoints; + worldManifold.normal.set(tmp[0], tmp[1]); + for (int i = 0; i < numContactPoints; i++) { + Vector2 point = worldManifold.points[i]; + point.x = tmp[2 + i * 2]; + point.y = tmp[2 + i * 2 + 1]; + } + + return worldManifold; + } + + private native int jniGetWorldManifold (long addr, float[] manifold); + + public boolean isTouching () { + return jniIsTouching(addr); + } + + private native boolean jniIsTouching (long addr); + + /** + * Enable/disable this contact. This can be used inside the pre-solve contact listener. The contact is only disabled for the + * current time step (or sub-step in continuous collisions). + */ + public void setEnabled (boolean flag) { + jniSetEnabled(addr, flag); + } + + private native void jniSetEnabled (long addr, boolean flag); + + /** + * Has this contact been disabled? + */ + public boolean isEnabled () { + return jniIsEnabled(addr); + } + + private native boolean jniIsEnabled (long addr); + + /** + * Get the first fixture in this contact. + */ + public Fixture getFixtureA () { + return world.fixtures.get(jniGetFixtureA(addr)); + } + + private native long jniGetFixtureA (long addr); + + /** + * Get the second fixture in this contact. + */ + public Fixture getFixtureB () { + return world.fixtures.get(jniGetFixtureB(addr)); + } + + private native long jniGetFixtureB (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/ContactFilter.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/ContactFilter.java new file mode 100644 index 0000000..78b6dd7 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/ContactFilter.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +/** + * Implement this class to provide collision filtering. In other words, you can implement this class if you want finer control + * over contact creation. + * @author mzechner + * + */ +public interface ContactFilter { + boolean shouldCollide (Fixture fixtureA, Fixture fixtureB); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/ContactListener.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/ContactListener.java new file mode 100644 index 0000000..47c271f --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/ContactListener.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +public interface ContactListener { + /** + * Called when two fixtures begin to touch. + */ + public void beginContact (Contact contact); + + /** + * Called when two fixtures cease to touch. + */ + public void endContact (Contact contact); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/DestructionListener.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/DestructionListener.java new file mode 100644 index 0000000..1e42480 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/DestructionListener.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +public interface DestructionListener { + +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Filter.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Filter.java new file mode 100644 index 0000000..59e6221 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Filter.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +/** + * This holds contact filtering data. + * @author mzechner + * + */ +public class Filter { + /** + * The collision category bits. Normally you would just set one bit. + */ + public short categoryBits = 0x0001; + + /** + * The collision mask bits. This states the categories that this shape would accept for collision. + */ + public short maskBits = -1; + + /** + * Collision groups allow a certain group of objects to never collide (negative) or always collide (positive). Zero means no + * collision group. Non-zero group filtering always wins against the mask bits. + */ + public short groupIndex = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Fixture.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Fixture.java new file mode 100644 index 0000000..abeb656 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Fixture.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Shape.Type; + +public class Fixture { + /** body **/ + private final Body body; + + /** the address of the fixture **/ + protected final long addr; + + /** the shape, initialized lazy **/ + protected Shape shape; + + /** + * Constructs a new fixture + * @param addr the address of the fixture + */ + protected Fixture (Body body, long addr) { + this.body = body; + this.addr = addr; + } + + /** + * Get the type of the child shape. You can use this to down cast to the concrete shape. + * @return the shape type. + */ + public Type getType () { + int type = jniGetType(addr); + if (type == 0) + return Type.Circle; + else + return Type.Polygon; + } + + private native int jniGetType (long addr); + + /** + * Returns the shape of this fixture + */ + public Shape getShape () { + if (shape == null) { + long shapeAddr = jniGetShape(addr); + int type = Shape.jniGetType(shapeAddr); + + if (type == 0) + shape = new CircleShape(shapeAddr); + else + shape = new PolygonShape(shapeAddr); + } + + return shape; + } + + private native long jniGetShape (long addr); + + /** + * Set if this fixture is a sensor. + */ + public void setSensor (boolean sensor) { + jniSetSensor(addr, sensor); + } + + private native void jniSetSensor (long addr, boolean sensor); + + /** + * Is this fixture a sensor (non-solid)? + * @return the true if the shape is a sensor. + */ + public boolean isSensor () { + return jniIsSensor(addr); + } + + private native boolean jniIsSensor (long addr); + + /** + * Set the contact filtering data. This will not update contacts until the next time step when either parent body is active and + * awake. + */ + public void setFilterData (Filter filter) { + jniSetFilterData(addr, filter.categoryBits, filter.maskBits, filter.groupIndex); + } + + private native void jniSetFilterData (long addr, short categoryBits, short maskBits, short groupIndex); + + /** + * Get the contact filtering data. + */ + private final short[] tmp = new short[3]; + private final Filter filter = new Filter(); + + public Filter getFilterData () { + jniGetFilterData(addr, tmp); + filter.maskBits = tmp[0]; + filter.categoryBits = tmp[1]; + filter.groupIndex = tmp[2]; + return filter; + } + + private native void jniGetFilterData (long addr, short[] filter); + + /** + * Get the parent body of this fixture. This is NULL if the fixture is not attached. + */ + public Body getBody () { + return body; + } + + /** + * Test a point for containment in this fixture. + * @param p a point in world coordinates. + */ + public boolean testPoint (Vector2 p) { + return jniTestPoint(addr, p.x, p.y); + } + + private native boolean jniTestPoint (long addr, float x, float y); + +// const b2Body* GetBody() const; +// +// /// Get the next fixture in the parent body's fixture list. +// /// @return the next shape. +// b2Fixture* GetNext(); +// const b2Fixture* GetNext() const; +// +// /// Get the user data that was assigned in the fixture definition. Use this to +// /// store your application specific data. +// void* GetUserData() const; +// +// /// Set the user data. Use this to store your application specific data. +// void SetUserData(void* data); +// +// /// Cast a ray against this shape. +// /// @param output the ray-cast results. +// /// @param input the ray-cast input parameters. +// bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; +// +// /// Get the mass data for this fixture. The mass data is based on the density and +// /// the shape. The rotational inertia is about the shape's origin. This operation +// /// may be expensive. +// void GetMassData(b2MassData* massData) const; + + /** + * Set the density of this fixture. This will _not_ automatically adjust the mass of the body. You must call + * b2Body::ResetMassData to update the body's mass. + */ + public void setDensity (float density) { + jniSetDensity(addr, density); + } + + private native void jniSetDensity (long addr, float density); + + /** + * Get the density of this fixture. + */ + public float getDensity () { + return jniGetDensity(addr); + } + + private native float jniGetDensity (long addr); + + /** + * Get the coefficient of friction. + */ + public float getFriction () { + return jniGetFriction(addr); + } + + private native float jniGetFriction (long addr); + + /** + * Set the coefficient of friction. + */ + public void setFriction (float friction) { + jniSetFriction(addr, friction); + } + + private native void jniSetFriction (long addr, float friction); + + /** + * Get the coefficient of restitution. + */ + public float getRestitution () { + return jniGetRestitution(addr); + } + + private native float jniGetRestitution (long addr); + + /** + * Set the coefficient of restitution. + */ + public void setRestitution (float restitution) { + jniSetRestitution(addr, restitution); + } + + private native void jniSetRestitution (long addr, float restitution); + +// /// Get the fixture's AABB. This AABB may be enlarge and/or stale. +// /// If you need a more accurate AABB, compute it using the shape and +// /// the body transform. +// const b2AABB& GetAABB() const; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/FixtureDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/FixtureDef.java new file mode 100644 index 0000000..17f3e6a --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/FixtureDef.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +/** + * A fixture definition is used to create a fixture. This class defines an abstract fixture definition. You can reuse fixture + * definitions safely. + * @author mzechner + * + */ +public class FixtureDef { + /** + * The shape, this must be set. The shape will be cloned, so you can create the shape on the stack. + */ + public Shape shape; + + /** The friction coefficient, usually in the range [0,1]. **/ + public float friction = 0.2f; + + /** The restitution (elasticity) usually in the range [0,1]. **/ + public float restitution = 0; + + /** The density, usually in kg/m^2. **/ + public float density = 0; + + /** + * A sensor shape collects contact information but never generates a collision response. + */ + public boolean isSensor = false; + + /** Contact filtering data. **/ + public final Filter filter = new Filter(); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Joint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Joint.java new file mode 100644 index 0000000..3f1ee2b --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Joint.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.JointDef.JointType; + +public abstract class Joint { + /** the address of the joint **/ + protected long addr; + + /** world **/ + private final World world; + + /** temporary float array **/ + private final float[] tmp = new float[2]; + + /** joint edge a **/ + protected JointEdge jointEdgeA; + + /** joint edge b **/ + protected JointEdge jointEdgeB; + + /** + * Constructs a new joint + * @param addr the address of the joint + */ + protected Joint (World world, long addr) { + this.world = world; + this.addr = addr; + } + + /** + * Get the type of the concrete joint. + */ + public JointType getType () { + int type = jniGetType(addr); + if (type > 0 && type < JointType.valueTypes.length) + return JointType.valueTypes[type]; + else + return JointType.Unknown; + } + + private native int jniGetType (long addr); + + /** + * Get the first body attached to this joint. + */ + public Body getBodyA () { + return world.bodies.get(jniGetBodyA(addr)); + } + + private native long jniGetBodyA (long addr); + + /** + * Get the second body attached to this joint. + */ + public Body getBodyB () { + return world.bodies.get(jniGetBodyB(addr)); + } + + private native long jniGetBodyB (long addr); + + /** + * Get the anchor point on bodyA in world coordinates. + */ + private final Vector2 anchorA = new Vector2(); + + public Vector2 getAnchorA () { + jniGetAnchorA(addr, tmp); + anchorA.x = tmp[0]; + anchorA.y = tmp[1]; + return anchorA; + } + + private native void jniGetAnchorA (long addr, float[] anchorA); + + /** + * Get the anchor point on bodyB in world coordinates. + */ + private final Vector2 anchorB = new Vector2(); + + public Vector2 getAnchorB () { + jniGetAnchorB(addr, tmp); + anchorB.x = tmp[0]; + anchorB.y = tmp[1]; + return anchorB; + } + + private native void jniGetAnchorB (long addr, float[] anchorB); + + /** + * Get the reaction force on body2 at the joint anchor in Newtons. + */ + private final Vector2 reactionForce = new Vector2(); + + public Vector2 getReactionForce (float inv_dt) { + jniGetReactionForce(addr, inv_dt, tmp); + reactionForce.x = tmp[0]; + reactionForce.y = tmp[1]; + return reactionForce; + } + + private native void jniGetReactionForce (long addr, float inv_dt, float[] reactionForce); + + /** + * Get the reaction torque on body2 in N*m. + */ + public float getReactionTorque (float inv_dt) { + return jniGetReactionTorque(addr, inv_dt); + } + + private native float jniGetReactionTorque (long addr, float inv_dt); + +// /// Get the next joint the world joint list. +// b2Joint* GetNext(); +// +// /// Get the user data pointer. +// void* GetUserData() const; +// +// /// Set the user data pointer. +// void SetUserData(void* data); + + /** + * Short-cut function to determine if either body is inactive. + */ + public boolean isActive () { + return jniIsActive(addr); + } + + private native boolean jniIsActive (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/JointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/JointDef.java new file mode 100644 index 0000000..7321a03 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/JointDef.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +public class JointDef { + public enum JointType { + Unknown(0), RevoluteJoint(1), PrismaticJoint(2), DistanceJoint(3), PulleyJoint(4), MouseJoint(5), GearJoint(6), LineJoint(7), WeldJoint( + 8), FrictionJoint(9); + + public static JointType[] valueTypes = new JointType[] {Unknown, RevoluteJoint, PrismaticJoint, DistanceJoint, PulleyJoint, + MouseJoint, GearJoint, LineJoint, WeldJoint, FrictionJoint}; + private int value; + + JointType (int value) { + this.value = value; + } + + public int getValue () { + return value; + } + } + + /** The joint type is set automatically for concrete joint types. **/ + public JointType type = JointType.Unknown; + + /** The first attached body. **/ + public Body bodyA = null; + + /** The second attached body **/ + public Body bodyB = null; + + /** Set this flag to true if the attached bodies should collide. **/ + public boolean collideConnected = false; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/JointEdge.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/JointEdge.java new file mode 100644 index 0000000..b370aac --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/JointEdge.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +/** + * A joint edge is used to connect bodies and joints together in a joint graph where each body is a node and each joint is an + * edge. A joint edge belongs to a doubly linked list maintained in each attached body. Each joint has two joint nodes, one for + * each attached body. + */ +public class JointEdge { + public final Body other; + public final Joint joint; + + protected JointEdge (Body other, Joint joint) { + this.other = other; + this.joint = joint; + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/MassData.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/MassData.java new file mode 100644 index 0000000..5bcdf5d --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/MassData.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +/** + * This holds the mass data computed for a shape. + * @author mzechner + * + */ +public class MassData { + /** The mass of the shape, usually in kilograms. **/ + public float mass; + + /** The position of the shape's centroid relative to the shape's origin. **/ + public final Vector2 center = new Vector2(); + + /** The rotational inertia of the shape about the local origin. **/ + public float I; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/PolygonShape.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/PolygonShape.java new file mode 100644 index 0000000..4846dfe --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/PolygonShape.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +public class PolygonShape extends Shape { + /** + * Constructs a new polygon + */ + public PolygonShape () { + addr = newPolygonShape(); + } + + protected PolygonShape (long addr) { + this.addr = addr; + } + + private native long newPolygonShape (); + + /** + * {@inheritDoc} + */ + @Override public Type getType () { + return Type.Polygon; + } + + /** + * Copy vertices. This assumes the vertices define a convex polygon. It is assumed that the exterior is the the right of each + * edge. + */ + public void set (Vector2[] vertices) { + float[] verts = new float[vertices.length * 2]; + for (int i = 0, j = 0; i < vertices.length * 2; i += 2, j++) { + verts[i] = vertices[j].x; + verts[i + 1] = vertices[j].y; + } + jniSet(addr, verts); + } + + private native void jniSet (long addr, float[] verts); + + /** + * Build vertices to represent an axis-aligned box. + * @param hx the half-width. + * @param hy the half-height. + */ + public void setAsBox (float hx, float hy) { + jniSetAsBox(addr, hx, hy); + } + + private native void jniSetAsBox (long addr, float hx, float hy); + + /** + * Build vertices to represent an oriented box. + * @param hx the half-width. + * @param hy the half-height. + * @param center the center of the box in local coordinates. + * @param angle the rotation of the box in local coordinates. + */ + public void setAsBox (float hx, float hy, Vector2 center, float angle) { + jniSetAsBox(addr, hx, hy, center.x, center.y, angle); + } + + private native void jniSetAsBox (long addr, float hx, float hy, float centerX, float centerY, float angle); + + /** + * Set this as a single edge. + */ + public void setAsEdge (Vector2 v1, Vector2 v2) { + jniSetAsEdge(addr, v1.x, v1.y, v2.x, v2.y); + } + + private native void jniSetAsEdge (long addr, float v1x, float v1y, float v2x, float v2y); + + /** + * @return the number of vertices + */ + public int getVertexCount () { + return jniGetVertexCount(addr); + } + + private native int jniGetVertexCount (long addr); + + private static float[] verts = new float[2]; + /** + * Returns the vertex at the given position. + * @param index the index of the vertex 0 <= index < getVertexCount( ) + * @param vertex vertex + */ + public void getVertex (int index, Vector2 vertex) { + jniGetVertex(addr, index, verts); + vertex.x = verts[0]; + vertex.y = verts[1]; + } + + private native void jniGetVertex (long addr, int index, float[] verts); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/QueryCallback.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/QueryCallback.java new file mode 100644 index 0000000..efe3490 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/QueryCallback.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +/** + * Callback class for AABB queries. + */ +public interface QueryCallback { + /** + * Called for each fixture found in the query AABB. + * @return false to terminate the query. + */ + public boolean reportFixture (Fixture fixture); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Shape.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Shape.java new file mode 100644 index 0000000..a234f46 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Shape.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +/** + * A shape is used for collision detection. You can create a shape however you like. Shapes used for simulation in b2World are + * created automatically when a b2Fixture is created. + * + * NOTE: YOU NEED TO DISPOSE SHAPES AFTER YOU NO LONGER USE THEM! E.g. after calling body.createFixture(); + * @author mzechner + * + */ +public abstract class Shape { + /** + * Enum describing the type of a shape + * @author mzechner + * + */ + public enum Type { + Circle, Polygon, + }; + + /** the address of the shape **/ + protected long addr; + + /** + * Get the type of this shape. You can use this to down cast to the concrete shape. + * @return the shape type. + */ + public abstract Type getType (); + + /** + * Returns the radius of this shape + */ + public float getRadius () { + return jniGetRadius(addr); + } + + private native float jniGetRadius (long addr); + + /** + * Sets the radius of this shape + */ + public void setRadius (float radius) { + jniSetRadius(addr, radius); + } + + private native void jniSetRadius (long addr, float radius); + + /** + * Needs to be called when the shape is no longer used, e.g. after a fixture was created based on the shape. + */ + public void dispose () { + jniDispose(addr); + } + + private native void jniDispose (long addr); + + protected static native int jniGetType (long addr); + +// /// Test a point for containment in this shape. This only works for convex shapes. +// /// @param xf the shape world transform. +// /// @param p a point in world coordinates. +// virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0; +// +// /// Cast a ray against this shape. +// /// @param output the ray-cast results. +// /// @param input the ray-cast input parameters. +// /// @param transform the transform to be applied to the shape. +// virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const = 0; +// +// /// Given a transform, compute the associated axis aligned bounding box for this shape. +// /// @param aabb returns the axis aligned box. +// /// @param xf the world transform of the shape. +// virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf) const = 0; +// +// /// Compute the mass properties of this shape using its dimensions and density. +// /// The inertia tensor is computed about the local origin. +// /// @param massData returns the mass data for this shape. +// /// @param density the density in kilograms per meter squared. +// virtual void ComputeMass(b2MassData* massData, float32 density) const = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/Transform.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/Transform.java new file mode 100644 index 0000000..53d2549 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/Transform.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +/** + * Encodes a Box2D transform. We are lazy so we only store a 6 float wide array. First two floats are the position of the + * b2Transform struct. Next two floats are the b2Transform.R.col1 x and y coordinates. Final 2 floats are the b2Transform.R.col2 x + * and y coordinates; + * @author mzechner + * + */ +public class Transform { + public static final int POS_X = 0; + public static final int POS_Y = 1; + public static final int COL1_X = 2; + public static final int COL1_Y = 3; + public static final int COL2_X = 4; + public static final int COL2_Y = 5; + + public float[] vals = new float[6]; + + private Vector2 position = new Vector2(); + + public Transform () { + + } + + /** + * Constructs a new Transform instance with the given position and angle + * @param position the position + * @param angle the angle in radians + */ + public Transform (Vector2 position, float angle) { + setPosition(position); + setRotation(angle); + } + + /** + * Transforms the given vector by this transform + * @param v the vector + */ + public Vector2 mul (Vector2 v) { + float x = vals[POS_X] + vals[COL1_X] * v.x + vals[COL2_X] * v.y; + float y = vals[POS_Y] + vals[COL1_Y] * v.x + vals[COL2_Y] * v.y; + + v.x = x; + v.y = y; + return v; + } + + /** + * @return the position, modification of the vector has no effect on the Transform + */ + public Vector2 getPosition () { + return position.set(vals[0], vals[1]); + } + + /** + * Sets the rotation of this transform + * @param angle angle in radians + */ + public void setRotation (float angle) { + float c = (float)Math.cos(angle), s = (float)Math.sin(angle); + vals[COL1_X] = c; + vals[COL2_X] = -s; + vals[COL1_Y] = s; + vals[COL2_Y] = c; + } + + /** + * Sets the position of this transform + * @param pos the position + */ + public void setPosition (Vector2 pos) { + this.vals[POS_X] = pos.x; + this.vals[POS_Y] = pos.y; + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/World.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/World.java new file mode 100644 index 0000000..cc1fa2d --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/World.java @@ -0,0 +1,508 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import java.util.ArrayList; +import java.util.List; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.JointDef.JointType; +import com.badlogic.gdx.physics.box2d.joints.DistanceJoint; +import com.badlogic.gdx.physics.box2d.joints.DistanceJointDef; +import com.badlogic.gdx.physics.box2d.joints.FrictionJoint; +import com.badlogic.gdx.physics.box2d.joints.FrictionJointDef; +import com.badlogic.gdx.physics.box2d.joints.GearJoint; +import com.badlogic.gdx.physics.box2d.joints.GearJointDef; +import com.badlogic.gdx.physics.box2d.joints.LineJoint; +import com.badlogic.gdx.physics.box2d.joints.LineJointDef; +import com.badlogic.gdx.physics.box2d.joints.MouseJoint; +import com.badlogic.gdx.physics.box2d.joints.MouseJointDef; +import com.badlogic.gdx.physics.box2d.joints.PrismaticJoint; +import com.badlogic.gdx.physics.box2d.joints.PrismaticJointDef; +import com.badlogic.gdx.physics.box2d.joints.PulleyJoint; +import com.badlogic.gdx.physics.box2d.joints.PulleyJointDef; +import com.badlogic.gdx.physics.box2d.joints.RevoluteJoint; +import com.badlogic.gdx.physics.box2d.joints.RevoluteJointDef; +import com.badlogic.gdx.physics.box2d.joints.WeldJoint; +import com.badlogic.gdx.physics.box2d.joints.WeldJointDef; +import com.badlogic.gdx.utils.LongHashMap; + +/** + * The world class manages all physics entities, dynamic simulation, and asynchronous queries. The world also contains efficient + * memory management facilities. + * @author mzechner + */ +public class World { + /** the address of the world instance **/ + private final long addr; + + /** all known bodies **/ + protected final LongHashMap bodies = new LongHashMap(100); + + /** all known fixtures **/ + protected final LongHashMap fixtures = new LongHashMap(100); + + /** all known joints **/ + protected final LongHashMap joints = new LongHashMap(100); + + /** Contact filter **/ + protected ContactFilter contactFilter = null; + + /** Contact listener **/ + protected ContactListener contactListener = null; + + /** + * Construct a world object. + * @param gravity the world gravity vector. + * @param doSleep improve performance by not simulating inactive bodies. + */ + public World (Vector2 gravity, boolean doSleep) { + addr = newWorld(gravity.x, gravity.y, doSleep); + + for (int i = 0; i < 200; i++) + freeContacts.add(new Contact(this, 0)); + } + + private native long newWorld (float gravityX, float gravityY, boolean doSleep); + + /** + * Register a destruction listener. The listener is owned by you and must remain in scope. + */ + public void setDestructionListener (DestructionListener listener) { + + } + + /** + * Register a contact filter to provide specific control over collision. Otherwise the default filter is used + * (b2_defaultFilter). The listener is owned by you and must remain in scope. + */ + public void setContactFilter (ContactFilter filter) { + this.contactFilter = filter; + } + + /** + * Register a contact event listener. The listener is owned by you and must remain in scope. + */ + public void setContactListener (ContactListener listener) { + this.contactListener = listener; + } + + /** + * Create a rigid body given a definition. No reference to the definition is retained. + * @warning This function is locked during callbacks. + */ + public Body createBody (BodyDef def) { + Body body = new Body(this, jniCreateBody(addr, def.type.getValue(), def.position.x, def.position.y, def.angle, + def.linearVelocity.x, def.linearVelocity.y, def.angularVelocity, def.linearDamping, def.angularDamping, def.allowSleep, + def.awake, def.fixedRotation, def.bullet, def.active, def.inertiaScale)); + this.bodies.put(body.addr, body); + return body; + } + + private native long jniCreateBody (long addr, int type, float positionX, float positionY, float angle, float linearVelocityX, + float linearVelocityY, float angularVelocity, float linearDamping, float angularDamping, boolean allowSleep, boolean awake, + boolean fixedRotation, boolean bullet, boolean active, float intertiaScale); + + /** + * Destroy a rigid body given a definition. No reference to the definition is retained. This function is locked during + * callbacks. + * @warning This automatically deletes all associated shapes and joints. + * @warning This function is locked during callbacks. + */ + public void destroyBody (Body body) { + this.bodies.remove(body.addr); + for (int i = 0; i < body.getFixtureList().size(); i++) + this.fixtures.remove(body.getFixtureList().get(i).addr); + for (int i = 0; i < body.getJointList().size(); i++) + this.joints.remove(body.getJointList().get(i).joint.addr); + jniDestroyBody(addr, body.addr); + } + + private native void jniDestroyBody (long addr, long bodyAddr); + + /** + * Create a joint to constrain bodies together. No reference to the definition is retained. This may cause the connected bodies + * to cease colliding. + * @warning This function is locked during callbacks. + */ + public Joint createJoint (JointDef def) { + long jointAddr = createProperJoint(def); + Joint joint = null; + if (def.type == JointType.DistanceJoint) joint = new DistanceJoint(this, jointAddr); + if (def.type == JointType.FrictionJoint) joint = new FrictionJoint(this, jointAddr); + if (def.type == JointType.GearJoint) joint = new GearJoint(this, jointAddr); + if (def.type == JointType.LineJoint) joint = new LineJoint(this, jointAddr); + if (def.type == JointType.MouseJoint) joint = new MouseJoint(this, jointAddr); + if (def.type == JointType.PrismaticJoint) joint = new PrismaticJoint(this, jointAddr); + if (def.type == JointType.PulleyJoint) joint = new PulleyJoint(this, jointAddr); + if (def.type == JointType.RevoluteJoint) joint = new RevoluteJoint(this, jointAddr); + if (def.type == JointType.WeldJoint) joint = new WeldJoint(this, jointAddr); + if (joint != null) joints.put(joint.addr, joint); + JointEdge jointEdgeA = new JointEdge(def.bodyB, joint); + JointEdge jointEdgeB = new JointEdge(def.bodyA, joint); + joint.jointEdgeA = jointEdgeA; + joint.jointEdgeB = jointEdgeB; + def.bodyA.joints.add(jointEdgeA); + def.bodyB.joints.add(jointEdgeB); + return joint; + } + + private long createProperJoint (JointDef def) { + if (def.type == JointType.DistanceJoint) { + DistanceJointDef d = (DistanceJointDef)def; + return jniCreateDistanceJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.localAnchorA.x, d.localAnchorA.y, + d.localAnchorB.x, d.localAnchorB.y, d.length, d.frequencyHz, d.dampingRatio); + } + if (def.type == JointType.FrictionJoint) { + FrictionJointDef d = (FrictionJointDef)def; + return jniCreateFrictionJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.localAnchorA.x, d.localAnchorA.y, + d.localAnchorB.x, d.localAnchorB.y, d.maxForce, d.maxTorque); + } + if (def.type == JointType.GearJoint) { + GearJointDef d = (GearJointDef)def; + return jniCreateGearJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.joint1.addr, d.joint2.addr, d.ratio); + } + if (def.type == JointType.LineJoint) { + LineJointDef d = (LineJointDef)def; + return jniCreateLineJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.localAnchorA.x, d.localAnchorA.y, + d.localAnchorB.x, d.localAnchorB.y, d.localAxisA.x, d.localAxisA.y, d.enableLimit, d.lowerTranslation, + d.upperTranslation, d.enableMotor, d.maxMotorForce, d.motorSpeed); + + } + if (def.type == JointType.MouseJoint) { + MouseJointDef d = (MouseJointDef)def; + return jniCreateMouseJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.target.x, d.target.y, d.maxForce, + d.frequencyHz, d.dampingRatio); + } + if (def.type == JointType.PrismaticJoint) { + PrismaticJointDef d = (PrismaticJointDef)def; + return jniCreatePrismaticJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.localAnchorA.x, d.localAnchorA.y, + d.localAnchorB.x, d.localAnchorB.y, d.localAxis1.x, d.localAxis1.y, d.referenceAngle, d.enableLimit, + d.lowerTranslation, d.upperTranslation, d.enableMotor, d.maxMotorForce, d.motorSpeed); + } + if (def.type == JointType.PulleyJoint) { + PulleyJointDef d = (PulleyJointDef)def; + return jniCreatePulleyJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.groundAnchorA.x, d.groundAnchorA.y, + d.groundAnchorB.x, d.groundAnchorB.y, d.localAnchorA.x, d.localAnchorA.y, d.localAnchorB.x, d.localAnchorB.y, + d.lengthA, d.maxLengthA, d.lengthB, d.maxLengthB, d.ratio); + + } + if (def.type == JointType.RevoluteJoint) { + RevoluteJointDef d = (RevoluteJointDef)def; + return jniCreateRevoluteJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.localAnchorA.x, d.localAnchorA.y, + d.localAnchorB.x, d.localAnchorB.y, d.referenceAngle, d.enableLimit, d.lowerAngle, d.upperAngle, d.enableMotor, + d.motorSpeed, d.maxMotorTorque); + } + if (def.type == JointType.WeldJoint) { + WeldJointDef d = (WeldJointDef)def; + return jniCreateWeldJoint(addr, d.bodyA.addr, d.bodyB.addr, d.collideConnected, d.localAnchorA.x, d.localAnchorA.y, + d.localAnchorB.x, d.localAnchorB.y, d.referenceAngle); + } + + return 0; + } + + private native long jniCreateDistanceJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float localAnchorAX, + float localAnchorAY, float localAnchorBX, float localAnchorBY, float length, float frequencyHz, float dampingRatio); + + private native long jniCreateFrictionJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float localAnchorAX, + float localAnchorAY, float localAnchorBX, float localAnchorBY, float maxForce, float maxTorque); + + private native long jniCreateGearJoint (long addr, long bodyA, long bodyB, boolean collideConnected, long joint1, long joint2, + float ratio); + + private native long jniCreateLineJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float localAnchorAX, + float localAnchorAY, float localAnchorBX, float localAnchorBY, float localAxisAX, float localAxisAY, boolean enableLimit, + float lowerTranslation, float upperTranslation, boolean enableMotor, float maxMotorForce, float motorSpeed); + + private native long jniCreateMouseJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float targetX, + float targetY, float maxForce, float frequencyHz, float dampingRatio); + + private native long jniCreatePrismaticJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float localAnchorAX, + float localAnchorAY, float localAnchorBX, float localAnchorBY, float localAxisAX, float localAxisAY, float referenceAngle, + boolean enableLimit, float lowerTranslation, float upperTranslation, boolean enableMotor, float maxMotorForce, + float motorSpeed); + + private native long jniCreatePulleyJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float groundAnchorAX, + float groundAnchorAY, float groundAnchorBX, float groundAnchorBY, float localAnchorAX, float localAnchorAY, + float localAnchorBX, float localAnchorBY, float lengthA, float maxLengthA, float lengthB, float maxLengthB, float ratio); + + private native long jniCreateRevoluteJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float localAnchorAX, + float localAnchorAY, float localAnchorBX, float localAnchorBY, float referenceAngle, boolean enableLimit, float lowerAngle, + float upperAngle, boolean enableMotor, float motorSpeed, float maxMotorTorque); + + private native long jniCreateWeldJoint (long addr, long bodyA, long bodyB, boolean collideConnected, float localAnchorAX, + float localAnchorAY, float localAnchorBX, float localAnchorBY, float referenceAngle); + + /** + * Destroy a joint. This may cause the connected bodies to begin colliding. + * @warning This function is locked during callbacks. + */ + public void destroyJoint (Joint joint) { + joints.remove(joint.addr); + joint.jointEdgeA.other.joints.remove(joint.jointEdgeB); + joint.jointEdgeB.other.joints.remove(joint.jointEdgeA); + jniDestroyJoint(addr, joint.addr); + } + + private native void jniDestroyJoint (long addr, long jointAddr); + + /** + * Take a time step. This performs collision detection, integration, and constraint solution. + * @param timeStep the amount of time to simulate, this should not vary. + * @param velocityIterations for the velocity constraint solver. + * @param positionIterations for the position constraint solver. + */ + public void step (float timeStep, int velocityIterations, int positionIterations) { + jniStep(addr, timeStep, velocityIterations, positionIterations); + } + + private native void jniStep (long addr, float timeStep, int velocityIterations, int positionIterations); + + /** + * Call this after you are done with time steps to clear the forces. You normally call this after each call to Step, unless you + * are performing sub-steps. By default, forces will be automatically cleared, so you don't need to call this function. + * See {@link #setAutoClearForces(boolean)} + */ + public void clearForces () { + jniClearForces(addr); + } + + private native void jniClearForces (long addr); + + /** + * Enable/disable warm starting. For testing. + */ + public void setWarmStarting (boolean flag) { + jniSetWarmStarting(addr, flag); + } + + private native void jniSetWarmStarting (long addr, boolean flag); + + /** + * Enable/disable continuous physics. For testing. + */ + public void setContinuousPhysics (boolean flag) { + jniSetContiousPhysics(addr, flag); + } + + private native void jniSetContiousPhysics (long addr, boolean flag); + + /** + * Get the number of broad-phase proxies. + */ + public int getProxyCount () { + return jniGetProxyCount(addr); + } + + private native int jniGetProxyCount (long addr); + + /** + * Get the number of bodies. + */ + public int getBodyCount () { + return jniGetBodyCount(addr); + } + + private native int jniGetBodyCount (long addr); + + /** + * Get the number of joints. + */ + public int getJointCount () { + return jniGetJointcount(addr); + } + + private native int jniGetJointcount (long addr); + + /** + * Get the number of contacts (each may have 0 or more contact points). + */ + public int getContactCount () { + return jniGetContactCount(addr); + } + + private native int jniGetContactCount (long addr); + + /** + * Change the global gravity vector. + */ + public void setGravity (Vector2 gravity) { + jniSetGravity(addr, gravity.x, gravity.y); + } + + private native void jniSetGravity (long addr, float gravityX, float gravityY); + + /** + * Get the global gravity vector. + */ + final float[] tmpGravity = new float[2]; + final Vector2 gravity = new Vector2(); + + public Vector2 getGravity () { + jniGetGravity(addr, tmpGravity); + gravity.x = tmpGravity[0]; + gravity.y = tmpGravity[1]; + return gravity; + } + + private native void jniGetGravity (long addr, float[] gravity); + + /** + * Is the world locked (in the middle of a time step). + */ + public boolean isLocked () { + return jniIsLocked(addr); + } + + private native boolean jniIsLocked (long addr); + + /** + * Set flag to control automatic clearing of forces after each time step. + */ + public void setAutoClearForces (boolean flag) { + jniSetAutoClearForces(addr, flag); + } + + private native void jniSetAutoClearForces (long addr, boolean flag); + + /** + * Get the flag that controls automatic clearing of forces after each time step. + */ + public boolean getAutoClearForces () { + return jniGetAutoClearForces(addr); + } + + private native boolean jniGetAutoClearForces (long addr); + + /** + * Query the world for all fixtures that potentially overlap the provided AABB. + * @param callback a user implemented callback class. + * @param lowerX the x coordinate of the lower left corner + * @param lowerY the y coordinate of the lower left corner + * @param upperX the x coordinate of the upper right corner + * @param upperY the y coordinate of the upper right corner + */ + public void QueryAABB (QueryCallback callback, float lowerX, float lowerY, float upperX, float upperY) { + queryCallback = callback; + jniQueryAABB(addr, lowerX, lowerY, upperX, upperY); + } + + private QueryCallback queryCallback = null;; + + private native void jniQueryAABB (long addr, float lowX, float lowY, float upX, float upY); + +// +// /// Ray-cast the world for all fixtures in the path of the ray. Your callback +// /// controls whether you get the closest point, any point, or n-points. +// /// The ray-cast ignores shapes that contain the starting point. +// /// @param callback a user implemented callback class. +// /// @param point1 the ray starting point +// /// @param point2 the ray ending point +// void RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const; +// +// /// Get the world contact list. With the returned contact, use b2Contact::GetNext to get +// /// the next contact in the world list. A NULL contact indicates the end of the list. +// /// @return the head of the world contact list. +// /// @warning contacts are +// b2Contact* GetContactList(); + + private long[] contactAddrs = new long[200]; + private final ArrayList contacts = new ArrayList(); + private final ArrayList freeContacts = new ArrayList(); + + public List getContactList () { + int numContacts = getContactCount(); + if (numContacts > contactAddrs.length) contactAddrs = new long[numContacts]; + if (numContacts > freeContacts.size()) { + int freeConts = freeContacts.size(); + for (int i = 0; i < numContacts - freeConts; i++) + freeContacts.add(new Contact(this, 0)); + } + jniGetContactList(addr, contactAddrs); + + contacts.clear(); + for (int i = 0; i < numContacts; i++) { + Contact contact = freeContacts.get(i); + contact.addr = contactAddrs[i]; + contacts.add(contact); + } + + return contacts; + } + + /** + * @return all bodies currently in the simulation + */ + public Iterable getBodies () { + return bodies.values(); + } + + /** + * @return all joints currently in the simulation + */ + public Iterable getJoints () { + return joints.values(); + } + + private native void jniGetContactList (long addr, long[] contacts); + + public void dispose () { + jniDispose(addr); + } + + private native void jniDispose (long addr); + + /** + * Internal method called from JNI in case a contact happens + * @param fixtureA + * @param fixtureB + * @return whether the things collided + */ + private boolean contactFilter (long fixtureA, long fixtureB) { + if (contactFilter != null) + return contactFilter.shouldCollide(fixtures.get(fixtureA), fixtures.get(fixtureB)); + else { + Filter filterA = fixtures.get(fixtureA).getFilterData(); + Filter filterB = fixtures.get(fixtureB).getFilterData(); + + if (filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0) { + return filterA.groupIndex > 0; + } + + boolean collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0; + return collide; + } + } + + private final Contact contact = new Contact(this, 0); + + private void beginContact (long contactAddr) { + contact.addr = contactAddr; + if (contactListener != null) contactListener.beginContact(contact); + } + + private void endContact (long contactAddr) { + contact.addr = contactAddr; + contact.GetWorldManifold(); + if (contactListener != null) contactListener.endContact(contact); + } + + private boolean reportFixture (long addr) { + if (queryCallback != null) + return queryCallback.reportFixture(fixtures.get(addr)); + else + return false; + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/WorldManifold.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/WorldManifold.java new file mode 100644 index 0000000..f63b4cb --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/WorldManifold.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d; + +import com.badlogic.gdx.math.Vector2; + +/** + * This is used to compute the current state of a contact manifold. + */ +public class WorldManifold { + protected final Vector2 normal = new Vector2(); + protected final Vector2[] points = {new Vector2(), new Vector2()}; + protected int numContactPoints; + + protected WorldManifold () { + } + + /** + * Returns the normal of this manifold + */ + public Vector2 getNormal () { + return normal; + } + + /** + * Returns the contact points of this manifold. Use getNumberOfContactPoints to determine how many contact points there are + * (0,1 or 2) + */ + public Vector2[] getPoints () { + return points; + } + + /** + * @return the number of contact points + */ + public int getNumberOfContactPoints () { + return numContactPoints; + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/DistanceJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/DistanceJoint.java new file mode 100644 index 0000000..1ab4951 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/DistanceJoint.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A distance joint constrains two points on two bodies to remain at a fixed distance from each other. You can view this as a + * massless, rigid rod. + */ +public class DistanceJoint extends Joint { + public DistanceJoint (World world, long addr) { + super(world, addr); + } + + /** + * Set/get the natural length. Manipulating the length can lead to non-physical behavior when the frequency is zero. + */ + public void setLength (float length) { + jniSetLength(addr, length); + } + + private native void jniSetLength (long addr, float length); + + /** + * Set/get the natural length. Manipulating the length can lead to non-physical behavior when the frequency is zero. + */ + public float getLength () { + return jniGetLength(addr); + } + + private native float jniGetLength (long addr); + + /** + * Set/get frequency in Hz. + */ + public void setFrequency (float hz) { + jniSetFrequency(addr, hz); + } + + private native void jniSetFrequency (long addr, float hz); + + /** + * Set/get frequency in Hz. + */ + public float getFrequency () { + return jniGetFrequency(addr); + } + + private native float jniGetFrequency (long addr); + + /** + * Set/get damping ratio. + */ + public void setDampingRatio (float ratio) { + jniSetDampingRatio(addr, ratio); + } + + private native void jniSetDampingRatio (long addr, float ratio); + + /** + * Set/get damping ratio. + */ + public float getDampingRatio () { + return jniGetDampingRatio(addr); + } + + private native float jniGetDampingRatio (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/DistanceJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/DistanceJointDef.java new file mode 100644 index 0000000..274e5cb --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/DistanceJointDef.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Distance joint definition. This requires defining an anchor point on both bodies and the non-zero length of the distance joint. + * The definition uses local anchor points so that the initial configuration can violate the constraint slightly. This helps when + * saving and loading a game. + * @warning Do not use a zero or short length. + */ +public class DistanceJointDef extends JointDef { + public DistanceJointDef () { + type = JointType.DistanceJoint; + } + + /** + * Initialize the bodies, anchors, and length using the world anchors. + */ + public void initialize (Body bodyA, Body bodyB, Vector2 anchorA, Vector2 anchorB) { + this.bodyA = bodyA; + this.bodyB = bodyB; + this.localAnchorA.set(bodyA.getLocalPoint(anchorA)); + this.localAnchorB.set(bodyB.getLocalPoint(anchorB)); + this.length = anchorA.dst(anchorB); + } + + /** + * The local anchor point relative to body1's origin. + */ + public final Vector2 localAnchorA = new Vector2(); + + /** + * The local anchor point relative to body2's origin. + */ + public final Vector2 localAnchorB = new Vector2(); + + /** + * The natural length between the anchor points. + */ + public float length = 1; + + /** + * The mass-spring-damper frequency in Hertz. + */ + public float frequencyHz = 0; + + /** + * The damping ratio. 0 = no damping, 1 = critical damping. + */ + public float dampingRatio = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/FrictionJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/FrictionJoint.java new file mode 100644 index 0000000..caa96a6 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/FrictionJoint.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * Friction joint. This is used for top-down friction. It provides 2D translational friction and angular friction. + */ +public class FrictionJoint extends Joint { + public FrictionJoint (World world, long addr) { + super(world, addr); + } + + /** + * Set the maximum friction force in N. + */ + public void setMaxForce (float force) { + jniSetMaxForce(addr, force); + } + + private native void jniSetMaxForce (long ddr, float force); + + /** + * Get the maximum friction force in N. + */ + public float getMaxForce () { + return jniGetMaxForce(addr); + } + + private native float jniGetMaxForce (long addr); + + /** + * Set the maximum friction torque in N*m. + */ + public void setMaxTorque (float torque) { + jniSetMaxTorque(addr, torque); + } + + private native void jniSetMaxTorque (long addr, float torque); + + /** + * Get the maximum friction torque in N*m. + */ + public float getMaxTorque () { + return jniGetMaxTorque(addr); + } + + private native float jniGetMaxTorque (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/FrictionJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/FrictionJointDef.java new file mode 100644 index 0000000..6a26e04 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/FrictionJointDef.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Friction joint definition. + */ +public class FrictionJointDef extends JointDef { + + public FrictionJointDef () { + type = JointType.FrictionJoint; + } + + /** + * Initialize the bodies, anchors, axis, and reference angle using the world anchor and world axis. + */ + public void initialize (Body bodyA, Body bodyB, Vector2 anchor) { + this.bodyA = bodyA; + this.bodyB = bodyB; + localAnchorA.set(bodyA.getLocalPoint(anchor)); + localAnchorB.set(bodyB.getLocalPoint(anchor)); + } + + /** + * The local anchor point relative to bodyA's origin. + */ + public final Vector2 localAnchorA = new Vector2(); + + /** + * The local anchor point relative to bodyB's origin. + */ + public final Vector2 localAnchorB = new Vector2(); + + /** + * The maximum friction force in N. + */ + public float maxForce = 0; + + /** + * The maximum friction torque in N-m. + */ + public float maxTorque = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/GearJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/GearJoint.java new file mode 100644 index 0000000..f25fd2b --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/GearJoint.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A gear joint is used to connect two joints together. Either joint can be a revolute or prismatic joint. You specify a gear + * ratio to bind the motions together: coordinate1 + ratio * coordinate2 = constant The ratio can be negative or positive. If one + * joint is a revolute joint and the other joint is a prismatic joint, then the ratio will have units of length or units of + * 1/length. + * @warning The revolute and prismatic joints must be attached to fixed bodies (which must be body1 on those joints). + */ +public class GearJoint extends Joint { + public GearJoint (World world, long addr) { + super(world, addr); + } + + /** + * Set/Get the gear ratio. + */ + public void setRatio (float ratio) { + jniSetRatio(addr, ratio); + } + + private native void jniSetRatio (long addr, float ratio); + + /** + * Set/Get the gear ratio. + */ + public float getRatio () { + return jniGetRatio(addr); + } + + private native float jniGetRatio (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/GearJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/GearJointDef.java new file mode 100644 index 0000000..1138693 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/GearJointDef.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Gear joint definition. This definition requires two existing revolute or prismatic joints (any combination will work). The + * provided joints must attach a dynamic body to a static body. + */ +public class GearJointDef extends JointDef { + public GearJointDef () { + type = JointType.GearJoint; + } + + /** + * The first revolute/prismatic joint attached to the gear joint. + */ + public Joint joint1 = null; + + /** + * The second revolute/prismatic joint attached to the gear joint. + */ + public Joint joint2 = null; + + /** + * The gear ratio. + * @see GearJoint for explanation. + */ + public float ratio = 1; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/LineJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/LineJoint.java new file mode 100644 index 0000000..e54bc72 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/LineJoint.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A line joint. This joint provides two degrees of freedom: translation along an axis fixed in body1 and rotation in the plane. + * You can use a joint limit to restrict the range of motion and a joint motor to drive the motion or to model joint friction. + */ +public class LineJoint extends Joint { + public LineJoint (World world, long addr) { + super(world, addr); + } + + /** + * Get the current joint translation, usually in meters. + */ + public float getJointTranslation () { + return jniGetJointTranslation(addr); + } + + private native float jniGetJointTranslation (long addr); + + /** + * Get the current joint translation speed, usually in meters per second. + */ + public float getJointSpeed () { + return jniGetJointSpeed(addr); + } + + private native float jniGetJointSpeed (long addr); + + /** + * Is the joint limit enabled? + */ + public boolean isLimitEnabled () { + return jniIsLimitEnabled(addr); + } + + private native boolean jniIsLimitEnabled (long addr); + + /** + * Enable/disable the joint limit. + */ + public void enableLimit (boolean flag) { + jniEnableLimit(addr, flag); + } + + private native void jniEnableLimit (long addr, boolean flag); + + /** + * Get the lower joint limit, usually in meters. + */ + public float getLowerLimit () { + return jniGetLowerLimit(addr); + } + + private native float jniGetLowerLimit (long addr); + + /** + * Get the upper joint limit, usually in meters. + */ + public float getUpperLimit () { + return jniGetUpperLimit(addr); + } + + private native float jniGetUpperLimit (long addr); + + /** + * Set the joint limits, usually in meters. + */ + public void setLimits (float lower, float upper) { + jniSetLimits(addr, lower, upper); + } + + private native void jniSetLimits (long addr, float lower, float upper); + + /** + * Is the joint motor enabled? + */ + public boolean isMotorEnabled () { + return jniIsMotorEnabled(addr); + } + + private native boolean jniIsMotorEnabled (long addr); + + /** + * Enable/disable the joint motor. + */ + public void enableMotor (boolean flag) { + jniEnableMotor(addr, flag); + } + + private native void jniEnableMotor (long addr, boolean flag); + + /** + * Set the motor speed, usually in meters per second. + */ + public void setMotorSpeed (float speed) { + jniSetMotorSpeed(addr, speed); + } + + private native void jniSetMotorSpeed (long addr, float speed); + + /** + * Get the motor speed, usually in meters per second. + */ + public float getMotorSpeed () { + return jniGetMotorSpeed(addr); + } + + private native float jniGetMotorSpeed (long addr); + + /** + * Set/Get the maximum motor force, usually in N. + */ + public void setMaxMotorForce (float force) { + jniSetMaxMotorForce(addr, force); + } + + private native void jniSetMaxMotorForce (long addr, float force); + + /** + * Set/Get the maximum motor force, usually in N. FIXME returns 0 at the moment due to a linking problem. + */ + public float getMaxMotorForce () { + return jniGetMaxMotorForce(addr); + } + + private native float jniGetMaxMotorForce (long addr); + + /** + * Get the current motor force, usually in N. + */ + public float getMotorForce () { + return jniGetMotorForce(addr); + } + + private native float jniGetMotorForce (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/LineJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/LineJointDef.java new file mode 100644 index 0000000..15cd8cf --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/LineJointDef.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Line joint definition. This requires defining a line of motion using an axis and an anchor point. The definition uses local + * anchor points and a local axis so that the initial configuration can violate the constraint slightly. The joint translation is + * zero when the local anchor points coincide in world space. Using local anchors and a local axis helps when saving and loading a + * game. + */ +public class LineJointDef extends JointDef { + public LineJointDef () { + type = JointType.LineJoint; + } + + /** + * Initialize the bodies, anchors, axis, and reference angle using the world anchor and world axis. + */ + public void initialize (Body bodyA, Body bodyB, Vector2 anchor, Vector2 axis) { + this.bodyA = bodyA; + this.bodyB = bodyB; + localAnchorA.set(bodyA.getLocalPoint(anchor)); + localAnchorB.set(bodyB.getLocalPoint(anchor)); + localAxisA.set(bodyA.getLocalVector(axis)); + } + + /** + * The local anchor point relative to body1's origin. + */ + public final Vector2 localAnchorA = new Vector2(); + + /** + * The local anchor point relative to body2's origin. + */ + public final Vector2 localAnchorB = new Vector2(); + + /** + * The local translation axis in body1. + */ + public final Vector2 localAxisA = new Vector2(1.0f, 0); + + /** + * Enable/disable the joint limit. + */ + public boolean enableLimit = false; + + /** + * The lower translation limit, usually in meters. + */ + public float lowerTranslation = 0; + + /** + * The upper translation limit, usually in meters. + */ + public float upperTranslation = 0; + + /** + * Enable/disable the joint motor. + */ + public boolean enableMotor = false; + + /** + * The maximum motor torque, usually in N-m. + */ + public float maxMotorForce = 0; + + /** + * The desired motor speed in radians per second. + */ + public float motorSpeed = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/MouseJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/MouseJoint.java new file mode 100644 index 0000000..956e5ca --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/MouseJoint.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A mouse joint is used to make a point on a body track a specified world point. This a soft constraint with a maximum force. + * This allows the constraint to stretch and without applying huge forces. NOTE: this joint is not documented in the manual + * because it was developed to be used in the testbed. If you want to learn how to use the mouse joint, look at the testbed. + */ +public class MouseJoint extends Joint { + public MouseJoint (World world, long addr) { + super(world, addr); + // TODO Auto-generated constructor stub + } + + /** + * Use this to update the target point. + */ + public void setTarget (Vector2 target) { + jniSetTarget(addr, target.x, target.y); + } + + private native void jniSetTarget (long addr, float x, float y); + + /** + * Use this to update the target point. + */ + final float[] tmp = new float[2]; + private final Vector2 target = new Vector2(); + + public Vector2 getTarget () { + jniGetTarget(addr, tmp); + target.x = tmp[0]; + target.y = tmp[1]; + return target; + } + + private native void jniGetTarget (long addr, float[] target); + + /** + * Set/get the maximum force in Newtons. + */ + public void setMaxForce (float force) { + jniSetMaxForce(addr, force); + } + + private native void jniSetMaxForce (long addr, float force); + + /** + * Set/get the maximum force in Newtons. + */ + public float getMaxForce () { + return jniGetMaxForce(addr); + } + + private native float jniGetMaxForce (long addr); + + /** + * Set/get the frequency in Hertz. + */ + public void setFrequency (float hz) { + jniSetFrequency(addr, hz); + } + + private native void jniSetFrequency (long addr, float hz); + + /** + * Set/get the frequency in Hertz. + */ + public float getFrequency () { + return jniGetFrequency(addr); + } + + private native float jniGetFrequency (long addr); + + /** + * Set/get the damping ratio (dimensionless). + */ + public void setDampingRatio (float ratio) { + jniSetDampingRatio(addr, ratio); + } + + private native void jniSetDampingRatio (long addr, float ratio); + + /** + * Set/get the damping ratio (dimensionless). + */ + public float getDampingRatio () { + return jniGetDampingRatio(addr); + } + + private native float jniGetDampingRatio (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/MouseJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/MouseJointDef.java new file mode 100644 index 0000000..e3398e9 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/MouseJointDef.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Mouse joint definition. This requires a world target point, tuning parameters, and the time step. + */ +public class MouseJointDef extends JointDef { + public MouseJointDef () { + type = JointType.MouseJoint; + } + + /** + * The initial world target point. This is assumed to coincide with the body anchor initially. + */ + public final Vector2 target = new Vector2(); + + /** + * The maximum constraint force that can be exerted to move the candidate body. Usually you will express as some multiple of + * the weight (multiplier * mass * gravity). + */ + public float maxForce = 0; + + /** + * The response speed. + */ + public float frequencyHz = 5.0f; + + /** + * The damping ratio. 0 = no damping, 1 = critical damping. + */ + public float dampingRatio = 0.7f; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PrismaticJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PrismaticJoint.java new file mode 100644 index 0000000..e30c9a9 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PrismaticJoint.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A prismatic joint. This joint provides one degree of freedom: translation along an axis fixed in body1. Relative rotation is + * prevented. You can use a joint limit to restrict the range of motion and a joint motor to drive the motion or to model joint + * friction. + */ +public class PrismaticJoint extends Joint { + public PrismaticJoint (World world, long addr) { + super(world, addr); + } + + /** + * Get the current joint translation, usually in meters. + */ + public float getJointTranslation () { + return jniGetJointTranslation(addr); + } + + private native float jniGetJointTranslation (long addr); + + /** + * Get the current joint translation speed, usually in meters per second. + */ + public float getJointSpeed () { + return jniGetJointSpeed(addr); + } + + private native float jniGetJointSpeed (long addr); + + /** + * Is the joint limit enabled? + */ + public boolean isLimitEnabled () { + return jniIsLimitEnabled(addr); + } + + private native boolean jniIsLimitEnabled (long addr); + + /** + * Enable/disable the joint limit. + */ + public void enableLimit (boolean flag) { + jniEnableLimit(addr, flag); + } + + private native void jniEnableLimit (long addr, boolean flag); + + /** + * Get the lower joint limit, usually in meters. + */ + public float getLowerLimit () { + return jniGetLowerLimit(addr); + } + + private native float jniGetLowerLimit (long addr); + + /** + * Get the upper joint limit, usually in meters. + */ + public float getUpperLimit () { + return jniGetUpperLimit(addr); + } + + private native float jniGetUpperLimit (long addr); + + /** + * Set the joint limits, usually in meters. + */ + public void setLimits (float lower, float upper) { + jniSetLimits(addr, lower, upper); + } + + private native void jniSetLimits (long addr, float lower, float upper); + + /** + * Is the joint motor enabled? + */ + public boolean isMotorEnabled () { + return jniIsMotorEnabled(addr); + } + + private native boolean jniIsMotorEnabled (long addr); + + /** + * Enable/disable the joint motor. + */ + public void enableMotor (boolean flag) { + jniEnableMotor(addr, flag); + } + + private native void jniEnableMotor (long addr, boolean flag); + + /** + * Set the motor speed, usually in meters per second. + */ + public void setMotorSpeed (float speed) { + jniSetMotorSpeed(addr, speed); + } + + private native void jniSetMotorSpeed (long addr, float speed); + + /** + * Get the motor speed, usually in meters per second. + */ + public float getMotorSpeed () { + return jniGetMotorSpeed(addr); + } + + private native float jniGetMotorSpeed (long addr); + + /** + * Set the maximum motor force, usually in N. + */ + public void setMaxMotorForce (float force) { + jniSetMaxMotorForce(addr, force); + } + + private native void jniSetMaxMotorForce (long addr, float force); + + /** + * Get the current motor force, usually in N. + */ + public float getMotorForce () { + return jniGetMotorForce(addr); + } + + private native float jniGetMotorForce (long addr); + +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PrismaticJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PrismaticJointDef.java new file mode 100644 index 0000000..b56fa6b --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PrismaticJointDef.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Prismatic joint definition. This requires defining a line of motion using an axis and an anchor point. The definition uses + * local anchor points and a local axis so that the initial configuration can violate the constraint slightly. The joint + * translation is zero when the local anchor points coincide in world space. Using local anchors and a local axis helps when + * saving and loading a game. + * @warning at least one body should by dynamic with a non-fixed rotation. + */ +public class PrismaticJointDef extends JointDef { + public PrismaticJointDef () { + type = JointType.PrismaticJoint; + } + + /** + * Initialize the bodies, anchors, axis, and reference angle using the world anchor and world axis. + */ + public void initialize (Body bodyA, Body bodyB, Vector2 anchor, Vector2 axis) { + this.bodyA = bodyA; + this.bodyB = bodyB; + localAnchorA.set(bodyA.getLocalPoint(anchor)); + localAnchorB.set(bodyB.getLocalPoint(anchor)); + localAxis1.set(bodyA.getLocalVector(axis)); + referenceAngle = bodyB.getAngle() - bodyA.getAngle(); + + } + + /** + * The local anchor point relative to body1's origin. + */ + public final Vector2 localAnchorA = new Vector2(); + + /** + * The local anchor point relative to body2's origin. + */ + public final Vector2 localAnchorB = new Vector2(); + + /** + * The local translation axis in body1. + */ + public final Vector2 localAxis1 = new Vector2(1, 0); + + /** + * The constrained angle between the bodies: body2_angle - body1_angle. + */ + public float referenceAngle = 0; + + /** + * Enable/disable the joint limit. + */ + public boolean enableLimit = false; + + /** + * The lower translation limit, usually in meters. + */ + public float lowerTranslation = 0; + + /** + * The upper translation limit, usually in meters. + */ + public float upperTranslation = 0; + + /** + * Enable/disable the joint motor. + */ + public boolean enableMotor = false; + + /** + * The maximum motor torque, usually in N-m. + */ + public float maxMotorForce = 0; + + /** + * The desired motor speed in radians per second. + */ + public float motorSpeed = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PulleyJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PulleyJoint.java new file mode 100644 index 0000000..e2b6b36 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PulleyJoint.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * The pulley joint is connected to two bodies and two fixed ground points. The pulley supports a ratio such that: length1 + ratio + * * length2 <= constant Yes, the force transmitted is scaled by the ratio. The pulley also enforces a maximum length limit on + * both sides. This is useful to prevent one side of the pulley hitting the top. + */ +public class PulleyJoint extends Joint { + public PulleyJoint (World world, long addr) { + super(world, addr); + } + + /** + * Get the first ground anchor. + */ + private final float[] tmp = new float[2]; + private final Vector2 groundAnchorA = new Vector2(); + + public Vector2 getGroundAnchorA () { + jniGetGroundAnchorA(addr, tmp); + groundAnchorA.set(tmp[0], tmp[1]); + return groundAnchorA; + } + + private native void jniGetGroundAnchorA (long addr, float[] anchor); + + /** + * Get the second ground anchor. + */ + private final Vector2 groundAnchorB = new Vector2(); + + public Vector2 getGroundAnchorB () { + jniGetGroundAnchorB(addr, tmp); + groundAnchorB.set(tmp[0], tmp[1]); + return groundAnchorB; + } + + private native void jniGetGroundAnchorB (long addr, float[] anchor); + + /** + * Get the current length of the segment attached to body1. + */ + public float getLength1 () { + return jniGetLength1(addr); + } + + private native float jniGetLength1 (long addr); + + /** + * Get the current length of the segment attached to body2. + */ + public float getLength2 () { + return jniGetLength2(addr); + } + + private native float jniGetLength2 (long addr); + + /** + * Get the pulley ratio. + */ + public float getRatio () { + return jniGetRatio(addr); + } + + private native float jniGetRatio (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PulleyJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PulleyJointDef.java new file mode 100644 index 0000000..b1315d8 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/PulleyJointDef.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Pulley joint definition. This requires two ground anchors, two dynamic body anchor points, max lengths for each side, and a + * pulley ratio. + */ +public class PulleyJointDef extends JointDef { + private final static float minPulleyLength = 2.0f; + + public PulleyJointDef () { + type = JointType.PulleyJoint; + collideConnected = true; + } + + /** + * Initialize the bodies, anchors, lengths, max lengths, and ratio using the world anchors. + */ + public void initialize (Body bodyA, Body bodyB, Vector2 groundAnchorA, Vector2 groundAnchorB, Vector2 anchorA, + Vector2 anchorB, float ratio) { + this.bodyA = bodyA; + this.bodyB = bodyB; + this.groundAnchorA.set(groundAnchorA); + this.groundAnchorB.set(groundAnchorB); + this.localAnchorA.set(bodyA.getLocalPoint(anchorA)); + this.localAnchorB.set(bodyB.getLocalPoint(anchorB)); + lengthA = anchorA.dst(groundAnchorA); + lengthB = anchorB.dst(groundAnchorB); + this.ratio = ratio; + float C = lengthA + ratio * lengthB; + maxLengthA = C - ratio * minPulleyLength; + maxLengthB = (C - minPulleyLength) / ratio; + + } + + /** + * The first ground anchor in world coordinates. This point never moves. + */ + public final Vector2 groundAnchorA = new Vector2(-1, 1); + + /** + * The second ground anchor in world coordinates. This point never moves. + */ + public final Vector2 groundAnchorB = new Vector2(1, 1); + + /** + * The local anchor point relative to bodyA's origin. + */ + public final Vector2 localAnchorA = new Vector2(-1, 0); + + /** + * The local anchor point relative to bodyB's origin. + */ + public final Vector2 localAnchorB = new Vector2(1, 0); + + /** + * The a reference length for the segment attached to bodyA. + */ + public float lengthA = 0; + + /** + * The maximum length of the segment attached to bodyA. + */ + public float maxLengthA = 0; + + /** + * The a reference length for the segment attached to bodyB. + */ + public float lengthB = 0; + + /** + * The maximum length of the segment attached to bodyB. + */ + public float maxLengthB = 0; + + /** + * The pulley ratio, used to simulate a block-and-tackle. + */ + public float ratio = 1; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/RevoluteJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/RevoluteJoint.java new file mode 100644 index 0000000..3d6fa7f --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/RevoluteJoint.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A revolute joint constrains two bodies to share a common point while they are free to rotate about the point. The relative + * rotation about the shared point is the joint angle. You can limit the relative rotation with a joint limit that specifies a + * lower and upper angle. You can use a motor to drive the relative rotation about the shared point. A maximum motor torque is + * provided so that infinite forces are not generated. + */ +public class RevoluteJoint extends Joint { + public RevoluteJoint (World world, long addr) { + super(world, addr); + } + + /** + * Get the current joint angle in radians. + */ + public float getJointAngle () { + return jniGetJointAngle(addr); + } + + private native float jniGetJointAngle (long addr); + + /** + * Get the current joint angle speed in radians per second. + */ + public float getJointSpeed () { + return jniGetJointSpeed(addr); + } + + private native float jniGetJointSpeed (long addr); + + /** + * Is the joint limit enabled? + */ + public boolean isLimitEnabled () { + return jniIsLimitEnabled(addr); + } + + private native boolean jniIsLimitEnabled (long addr); + + /** + * Enable/disable the joint limit. + */ + public void enableLimit (boolean flag) { + jniEnableLimit(addr, flag); + } + + private native void jniEnableLimit (long addr, boolean flag); + + /** + * Get the lower joint limit in radians. + */ + public float getLowerLimit () { + return jniGetLowerLimit(addr); + } + + private native float jniGetLowerLimit (long addr); + + /** + * Get the upper joint limit in radians. + */ + public float getUpperLimit () { + return jniGetUpperLimit(addr); + } + + private native float jniGetUpperLimit (long addr); + + /** + * Set the joint limits in radians. + * @param upper + */ + public void setLimits (float lower, float upper) { + jniSetLimits(addr, lower, upper); + } + + private native void jniSetLimits (long addr, float lower, float upper); + + /** + * Is the joint motor enabled? + */ + public boolean isMotorEnabled () { + return jniIsMotorEnabled(addr); + } + + private native boolean jniIsMotorEnabled (long addr); + + /** + * Enable/disable the joint motor. + */ + public void enableMotor (boolean flag) { + jniEnableMotor(addr, flag); + } + + private native void jniEnableMotor (long addr, boolean flag); + + /** + * Set the motor speed in radians per second. + */ + public void setMotorSpeed (float speed) { + jniSetMotorSpeed(addr, speed); + } + + private native void jniSetMotorSpeed (long addr, float speed); + + /** + * Get the motor speed in radians per second. + */ + public float getMotorSpeed () { + return jniGetMotorSpeed(addr); + } + + private native float jniGetMotorSpeed (long addr); + + /** + * Set the maximum motor torque, usually in N-m. + */ + public void setMaxMotorTorque (float torque) { + jniSetMaxMotorTorque(addr, torque); + } + + private native void jniSetMaxMotorTorque (long addr, float torque); + + /** + * Get the current motor torque, usually in N-m. + */ + public float getMotorTorque () { + return jniGetMotorTorque(addr); + } + + private native float jniGetMotorTorque (long addr); +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/RevoluteJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/RevoluteJointDef.java new file mode 100644 index 0000000..1526b91 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/RevoluteJointDef.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +/** + * Revolute joint definition. This requires defining an anchor point where the bodies are joined. The definition uses local anchor + * points so that the initial configuration can violate the constraint slightly. You also need to specify the initial relative + * angle for joint limits. This helps when saving and loading a game. The local anchor points are measured from the body's origin + * rather than the center of mass because: 1. you might not know where the center of mass will be. 2. if you add/remove shapes + * from a body and recompute the mass, the joints will be broken. + */ +public class RevoluteJointDef extends JointDef { + public RevoluteJointDef () { + type = JointType.RevoluteJoint; + } + + /** + * Initialize the bodies, anchors, and reference angle using a world anchor point. + */ + public void initialize (Body bodyA, Body bodyB, Vector2 anchor) { + this.bodyA = bodyA; + this.bodyB = bodyB; + localAnchorA.set(bodyA.getLocalPoint(anchor)); + localAnchorB.set(bodyB.getLocalPoint(anchor)); + referenceAngle = bodyB.getAngle() - bodyA.getAngle(); + } + + /** + * The local anchor point relative to body1's origin. + */ + public final Vector2 localAnchorA = new Vector2(); + + /** + * The local anchor point relative to body2's origin. + */ + public final Vector2 localAnchorB = new Vector2();; + + /** + * The body2 angle minus body1 angle in the reference state (radians). + */ + public float referenceAngle = 0; + + /** + * A flag to enable joint limits. + */ + public boolean enableLimit = false; + + /** + * The lower angle for the joint limit (radians). + */ + public float lowerAngle = 0; + + /** + * The upper angle for the joint limit (radians). + */ + public float upperAngle = 0; + + /** + * A flag to enable the joint motor. + */ + public boolean enableMotor = false; + + /** + * The desired motor speed. Usually in radians per second. + */ + public float motorSpeed = 0; + + /** + * The maximum motor torque used to achieve the desired motor speed. Usually in N-m. + */ + public float maxMotorTorque = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/WeldJoint.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/WeldJoint.java new file mode 100644 index 0000000..03745e3 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/WeldJoint.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A weld joint essentially glues two bodies together. A weld joint may distort somewhat because the island constraint solver is + * approximate. + */ +public class WeldJoint extends Joint { + public WeldJoint (World world, long addr) { + super(world, addr); + } +} diff --git a/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/WeldJointDef.java b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/WeldJointDef.java new file mode 100644 index 0000000..f5a90b3 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/physics/box2d/joints/WeldJointDef.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.physics.box2d.joints; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.JointDef; + +public class WeldJointDef extends JointDef { + public WeldJointDef () { + type = JointType.WeldJoint; + } + + // / Initialize the bodies, anchors, and reference angle using a world + // / anchor point. + public void initialize (Body body1, Body body2, Vector2 anchor) { + this.bodyA = body1; + this.bodyB = body2; + this.localAnchorA.set(body1.getLocalPoint(anchor)); + this.localAnchorB.set(body2.getLocalPoint(anchor)); + referenceAngle = body2.getAngle() - body1.getAngle(); + } + + // / The local anchor point relative to body1's origin. + public final Vector2 localAnchorA = new Vector2(); + + // / The local anchor point relative to body2's origin. + public final Vector2 localAnchorB = new Vector2(); + + // / The body2 angle minus body1 angle in the reference state (radians). + public float referenceAngle = 0; +} diff --git a/AndEngine/src/com/badlogic/gdx/utils/LongHashMap.java b/AndEngine/src/com/badlogic/gdx/utils/LongHashMap.java new file mode 100644 index 0000000..54d65d5 --- /dev/null +++ b/AndEngine/src/com/badlogic/gdx/utils/LongHashMap.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + ******************************************************************************/ + +package com.badlogic.gdx.utils; + +import java.util.Iterator; + +/** + * An long to object hashmap, taken from Amarena2D (thanks Christoph :p). + * + * @author christop widulle + * + * @param + */ +public class LongHashMap { + + private Entry[] table; + private float loadFactor; + private int size, mask, capacity, threshold; + + public LongHashMap () { + this(16, 0.75f); + } + + public LongHashMap (int initialCapacity) { + this(initialCapacity, 0.75f); + } + + public LongHashMap (int initialCapacity, float loadFactor) { + if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large."); + if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be greater than zero."); + if (loadFactor <= 0) throw new IllegalArgumentException("initialCapacity must be greater than zero."); + capacity = 1; + while (capacity < initialCapacity) { + capacity <<= 1; + } + this.loadFactor = loadFactor; + this.threshold = (int)(capacity * loadFactor); + this.table = new Entry[capacity]; + this.mask = capacity - 1; + } + + public boolean containsValue (Object value) { + Entry[] table = this.table; + for (int i = table.length; i-- > 0;) + for (Entry e = table[i]; e != null; e = e.next) + if (e.value.equals(value)) return true; + return false; + } + + public boolean containsKey (long key) { + int index = ((int)key) & mask; + for (Entry e = table[index]; e != null; e = e.next) + if (e.key == key) return true; + return false; + } + + @SuppressWarnings("unchecked") public T get (long key) { + int index = (int)(key & mask); + for (Entry e = table[index]; e != null; e = e.next) + if (e.key == key) return (T)e.value; + return null; + } + + @SuppressWarnings("unchecked") public T put (long key, T value) { + int index = (int)(key & mask); + // Check if key already exists. + for (Entry e = table[index]; e != null; e = e.next) { + if (e.key != key) continue; + Object oldValue = e.value; + e.value = value; + return (T)oldValue; + } + table[index] = new Entry(key, value, table[index]); + if (size++ >= threshold) { + // Rehash. + int newCapacity = 2 * capacity; + Entry[] newTable = new Entry[newCapacity]; + Entry[] src = table; + int bucketmask = newCapacity - 1; + for (int j = 0; j < src.length; j++) { + Entry e = src[j]; + if (e != null) { + src[j] = null; + do { + Entry next = e.next; + index = (int)(e.key & bucketmask); + e.next = newTable[index]; + newTable[index] = e; + e = next; + } while (e != null); + } + } + table = newTable; + capacity = newCapacity; + threshold = (int)(newCapacity * loadFactor); + mask = capacity - 1; + } + return null; + } + + @SuppressWarnings("unchecked") public T remove (long key) { + int index = (int)(key & mask); + Entry prev = table[index]; + Entry e = prev; + while (e != null) { + Entry next = e.next; + if (e.key == key) { + size--; + if (prev == e) { + table[index] = next; + } else { + prev.next = next; + } + return (T)e.value; + } + prev = e; + e = next; + } + return null; + } + + public int size () { + return size; + } + + public void clear () { + Entry[] table = this.table; + for (int index = table.length; --index >= 0;) + table[index] = null; + size = 0; + } + + static class Entry { + final long key; + Object value; + Entry next; + + Entry (long k, Object v, Entry n) { + key = k; + value = v; + next = n; + } + } + + EntryIterable iterable = new EntryIterable(); + + public Iterable values () { + iterable.reset(); + return iterable; + } + + class EntryIterable implements Iterable { + int currIndex = -1; + Entry currEntry = null; + + Iterator iter = new Iterator() { + @Override public boolean hasNext () { + if (currEntry == null) { + if (!loadNextEntry()) return false; + } else { + if (currEntry.next == null) { + if (loadNextEntry() == false) return false; + } else + currEntry = currEntry.next; + } + + return true; + } + + @SuppressWarnings("synthetic-access") + private boolean loadNextEntry () { + while (true) { + currIndex++; + if (currIndex >= table.length) return false; + + if (table[currIndex] == null) + continue; + else { + currEntry = table[currIndex]; + return true; + } + } + } + + @SuppressWarnings("unchecked") @Override public T next () { + return (T)currEntry.value; + } + + @Override public void remove () { + throw new UnsupportedOperationException("not implemented"); + } + + }; + + public void reset () { + currIndex = -1; + currEntry = null; + } + + @Override public Iterator iterator () { + return iter; + } + + } +} diff --git a/AndEngine/src/org/anddev/andengine/audio/BaseAudioEntity.java b/AndEngine/src/org/anddev/andengine/audio/BaseAudioEntity.java new file mode 100644 index 0000000..ea990c5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/BaseAudioEntity.java @@ -0,0 +1,86 @@ +package org.anddev.andengine.audio; + +/** + * @author Nicolas Gramlich + * @since 16:35:37 - 13.06.2010 + */ +public abstract class BaseAudioEntity implements IAudioEntity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final IAudioManager mAudioManager; + + protected float mLeftVolume = 1.0f; + protected float mRightVolume = 1.0f; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseAudioEntity(final IAudioManager pAudioManager) { + this.mAudioManager = pAudioManager; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + protected IAudioManager getAudioManager() { + return this.mAudioManager; + } + + public float getActualLeftVolume() { + return this.mLeftVolume * this.getMasterVolume(); + } + + public float getActualRightVolume() { + return this.mRightVolume * this.getMasterVolume(); + } + + protected float getMasterVolume() { + return this.mAudioManager.getMasterVolume(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getVolume() { + return (this.mLeftVolume + this.mRightVolume) * 0.5f; + } + + @Override + public float getLeftVolume() { + return this.mLeftVolume; + } + + @Override + public float getRightVolume() { + return this.mRightVolume; + } + + @Override + public final void setVolume(final float pVolume) { + this.setVolume(pVolume, pVolume); + } + + @Override + public void setVolume(final float pLeftVolume, final float pRightVolume) { + this.mLeftVolume = pLeftVolume; + this.mRightVolume = pRightVolume; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/BaseAudioManager.java b/AndEngine/src/org/anddev/andengine/audio/BaseAudioManager.java new file mode 100644 index 0000000..dce2447 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/BaseAudioManager.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.audio; + +import java.util.ArrayList; + +/** + * @author Nicolas Gramlich + * @since 18:07:02 - 13.06.2010 + */ +public abstract class BaseAudioManager implements IAudioManager { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final ArrayList mAudioEntities = new ArrayList(); + + protected float mMasterVolume = 1.0f; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getMasterVolume() { + return this.mMasterVolume; + } + + @Override + public void setMasterVolume(final float pMasterVolume) { + this.mMasterVolume = pMasterVolume; + + final ArrayList audioEntities = this.mAudioEntities; + for(int i = audioEntities.size() - 1; i >= 0; i--) { + final T audioEntity = audioEntities.get(i); + + audioEntity.onMasterVolumeChanged(pMasterVolume); + } + } + + @Override + public void add(final T pAudioEntity) { + this.mAudioEntities.add(pAudioEntity); + } + + @Override + public void releaseAll() { + final ArrayList audioEntities = this.mAudioEntities; + for(int i = audioEntities.size() - 1; i >= 0; i--) { + final T audioEntity = audioEntities.get(i); + + audioEntity.stop(); + audioEntity.release(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/IAudioEntity.java b/AndEngine/src/org/anddev/andengine/audio/IAudioEntity.java new file mode 100644 index 0000000..8fb9923 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/IAudioEntity.java @@ -0,0 +1,33 @@ +package org.anddev.andengine.audio; + +/** + * @author Nicolas Gramlich + * @since 14:53:29 - 13.06.2010 + */ +public interface IAudioEntity { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void play(); + public void pause(); + public void resume(); + public void stop(); + + public float getVolume(); + public void setVolume(final float pVolume); + + public float getLeftVolume(); + public float getRightVolume(); + public void setVolume(final float pLeftVolume, final float pRightVolume); + + public void onMasterVolumeChanged(final float pMasterVolume); + + public void setLooping(final boolean pLooping); + + public void release(); +} diff --git a/AndEngine/src/org/anddev/andengine/audio/IAudioManager.java b/AndEngine/src/org/anddev/andengine/audio/IAudioManager.java new file mode 100644 index 0000000..750395a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/IAudioManager.java @@ -0,0 +1,22 @@ +package org.anddev.andengine.audio; + +/** + * @author Nicolas Gramlich + * @since 15:02:06 - 13.06.2010 + */ +public interface IAudioManager { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public float getMasterVolume(); + public void setMasterVolume(final float pMasterVolume); + + public void add(final T pAudioEntity); + + public void releaseAll(); +} diff --git a/AndEngine/src/org/anddev/andengine/audio/music/Music.java b/AndEngine/src/org/anddev/andengine/audio/music/Music.java new file mode 100644 index 0000000..813292f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/music/Music.java @@ -0,0 +1,114 @@ +package org.anddev.andengine.audio.music; + +import org.anddev.andengine.audio.BaseAudioEntity; + +import android.media.MediaPlayer; +import android.media.MediaPlayer.OnCompletionListener; + +/** + * @author Nicolas Gramlich + * @since 14:53:12 - 13.06.2010 + */ +public class Music extends BaseAudioEntity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final MediaPlayer mMediaPlayer; + + // =========================================================== + // Constructors + // =========================================================== + + Music(final MusicManager pMusicManager, final MediaPlayer pMediaPlayer) { + super(pMusicManager); + this.mMediaPlayer = pMediaPlayer; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isPlaying() { + return this.mMediaPlayer.isPlaying(); + } + + public MediaPlayer getMediaPlayer() { + return this.mMediaPlayer; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected MusicManager getAudioManager() { + return (MusicManager)super.getAudioManager(); + } + + @Override + public void play() { + this.mMediaPlayer.start(); + } + + @Override + public void stop() { + this.mMediaPlayer.stop(); + } + + @Override + public void resume() { + this.mMediaPlayer.start(); + } + + @Override + public void pause() { + this.mMediaPlayer.pause(); + } + + @Override + public void release() { + this.mMediaPlayer.release(); + } + + @Override + public void setLooping(final boolean pLooping) { + this.mMediaPlayer.setLooping(pLooping); + } + + @Override + public void setVolume(final float pLeftVolume, final float pRightVolume) { + super.setVolume(pLeftVolume, pRightVolume); + + final float masterVolume = this.getAudioManager().getMasterVolume(); + final float actualLeftVolume = pLeftVolume * masterVolume; + final float actualRightVolume = pRightVolume * masterVolume; + + this.mMediaPlayer.setVolume(actualLeftVolume, actualRightVolume); + } + + @Override + public void onMasterVolumeChanged(final float pMasterVolume) { + this.setVolume(this.mLeftVolume, this.mRightVolume); + } + + // =========================================================== + // Methods + // =========================================================== + + public void seekTo(final int pMilliseconds) { + this.mMediaPlayer.seekTo(pMilliseconds); + } + + public void setOnCompletionListener(final OnCompletionListener pOnCompletionListener) { + this.mMediaPlayer.setOnCompletionListener(pOnCompletionListener); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/music/MusicFactory.java b/AndEngine/src/org/anddev/andengine/audio/music/MusicFactory.java new file mode 100644 index 0000000..4fd3d52 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/music/MusicFactory.java @@ -0,0 +1,91 @@ +package org.anddev.andengine.audio.music; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import android.content.Context; +import android.content.res.AssetFileDescriptor; +import android.media.MediaPlayer; + +/** + * @author Nicolas Gramlich + * @since 15:05:49 - 13.06.2010 + */ +public class MusicFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static String sAssetBasePath = ""; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * @param pAssetBasePath must end with '/' or have .length() == 0. + */ + public static void setAssetBasePath(final String pAssetBasePath) { + if(pAssetBasePath.endsWith("/") || pAssetBasePath.length() == 0) { + MusicFactory.sAssetBasePath = pAssetBasePath; + } else { + throw new IllegalStateException("pAssetBasePath must end with '/' or be lenght zero."); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static Music createMusicFromFile(final MusicManager pMusicManager, final Context pContext, final File pFile) throws IOException { + final MediaPlayer mediaPlayer = new MediaPlayer(); + + mediaPlayer.setDataSource(new FileInputStream(pFile).getFD()); + mediaPlayer.prepare(); + + final Music music = new Music(pMusicManager, mediaPlayer); + pMusicManager.add(music); + + return music; + } + + public static Music createMusicFromAsset(final MusicManager pMusicManager, final Context pContext, final String pAssetPath) throws IOException { + final MediaPlayer mediaPlayer = new MediaPlayer(); + + final AssetFileDescriptor assetFileDescritor = pContext.getAssets().openFd(MusicFactory.sAssetBasePath + pAssetPath); + mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(), assetFileDescritor.getStartOffset(), assetFileDescritor.getLength()); + mediaPlayer.prepare(); + + final Music music = new Music(pMusicManager, mediaPlayer); + pMusicManager.add(music); + + return music; + } + + public static Music createMusicFromResource(final MusicManager pMusicManager, final Context pContext, final int pMusicResID) throws IOException { + final MediaPlayer mediaPlayer = MediaPlayer.create(pContext, pMusicResID); + mediaPlayer.prepare(); + + final Music music = new Music(pMusicManager, mediaPlayer); + pMusicManager.add(music); + + return music; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/music/MusicManager.java b/AndEngine/src/org/anddev/andengine/audio/music/MusicManager.java new file mode 100644 index 0000000..4465777 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/music/MusicManager.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.audio.music; + +import org.anddev.andengine.audio.BaseAudioManager; + +/** + * @author Nicolas Gramlich + * @since 15:01:23 - 13.06.2010 + */ +public class MusicManager extends BaseAudioManager { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public MusicManager() { + + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/sound/Sound.java b/AndEngine/src/org/anddev/andengine/audio/sound/Sound.java new file mode 100644 index 0000000..fe4c621 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/sound/Sound.java @@ -0,0 +1,123 @@ +package org.anddev.andengine.audio.sound; + +import org.anddev.andengine.audio.BaseAudioEntity; + +/** + * @author Nicolas Gramlich + * @since 13:22:15 - 11.03.2010 + */ +public class Sound extends BaseAudioEntity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mSoundID; + private int mStreamID = 0; + + private int mLoopCount = 0; + private float mRate = 1.0f; + + // =========================================================== + // Constructors + // =========================================================== + + Sound(final SoundManager pSoundManager, final int pSoundID) { + super(pSoundManager); + this.mSoundID = pSoundID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void setLoopCount(final int pLoopCount) { + this.mLoopCount = pLoopCount; + if(this.mStreamID != 0) { + this.getAudioManager().getSoundPool().setLoop(this.mStreamID, pLoopCount); + } + } + + public void setRate(final float pRate) { + this.mRate = pRate; + if(this.mStreamID != 0) { + this.getAudioManager().getSoundPool().setRate(this.mStreamID, pRate); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + @Override + protected SoundManager getAudioManager() { + return (SoundManager)super.getAudioManager(); + } + + @Override + public void play() { + final float masterVolume = this.getMasterVolume(); + final float leftVolume = this.mLeftVolume * masterVolume; + final float rightVolume = this.mRightVolume * masterVolume; + this.mStreamID = this.getAudioManager().getSoundPool().play(this.mSoundID, leftVolume, rightVolume, 1, this.mLoopCount, this.mRate); + } + + @Override + public void stop() { + if(this.mStreamID != 0) { + this.getAudioManager().getSoundPool().stop(this.mStreamID); + } + } + + @Override + public void resume() { + if(this.mStreamID != 0) { + this.getAudioManager().getSoundPool().resume(this.mStreamID); + } + } + + @Override + public void pause() { + if(this.mStreamID != 0) { + this.getAudioManager().getSoundPool().pause(this.mStreamID); + } + } + + @Override + public void release() { + + } + + @Override + public void setLooping(final boolean pLooping) { + this.setLoopCount((pLooping) ? -1 : 0); + } + + @Override + public void setVolume(final float pLeftVolume, final float pRightVolume) { + super.setVolume(pLeftVolume, pRightVolume); + if(this.mStreamID != 0){ + final float masterVolume = this.getMasterVolume(); + final float leftVolume = this.mLeftVolume * masterVolume; + final float rightVolume = this.mRightVolume * masterVolume; + + this.getAudioManager().getSoundPool().setVolume(this.mStreamID, leftVolume, rightVolume); + } + } + + @Override + public void onMasterVolumeChanged(final float pMasterVolume) { + this.setVolume(this.mLeftVolume, this.mRightVolume); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/sound/SoundFactory.java b/AndEngine/src/org/anddev/andengine/audio/sound/SoundFactory.java new file mode 100644 index 0000000..bb64781 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/sound/SoundFactory.java @@ -0,0 +1,81 @@ +package org.anddev.andengine.audio.sound; + +import java.io.FileDescriptor; +import java.io.IOException; + +import android.content.Context; + +/** + * @author Nicolas Gramlich + * @since 14:23:03 - 11.03.2010 + */ +public class SoundFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static String sAssetBasePath = ""; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * @param pAssetBasePath must end with '/' or have .length() == 0. + */ + public static void setAssetBasePath(final String pAssetBasePath) { + if(pAssetBasePath.endsWith("/") || pAssetBasePath.length() == 0) { + SoundFactory.sAssetBasePath = pAssetBasePath; + } else { + throw new IllegalStateException("pAssetBasePath must end with '/' or be lenght zero."); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static Sound createSoundFromPath(final SoundManager pSoundManager, final Context pContext, final String pPath) throws IOException { + final int soundID = pSoundManager.getSoundPool().load(pPath, 1); + final Sound sound = new Sound(pSoundManager, soundID); + pSoundManager.add(sound); + return sound; + } + + public static Sound createSoundFromAsset(final SoundManager pSoundManager, final Context pContext, final String pAssetPath) throws IOException { + final int soundID = pSoundManager.getSoundPool().load(pContext.getAssets().openFd(SoundFactory.sAssetBasePath + pAssetPath), 1); + final Sound sound = new Sound(pSoundManager, soundID); + pSoundManager.add(sound); + return sound; + } + + public static Sound createSoundFromResource(final SoundManager pSoundManager, final Context pContext, final int pSoundResID) { + final int soundID = pSoundManager.getSoundPool().load(pContext, pSoundResID, 1); + final Sound sound = new Sound(pSoundManager, soundID); + pSoundManager.add(sound); + return sound; + } + + public static Sound createSoundFromFileDescriptor(final SoundManager pSoundManager, final FileDescriptor pFileDescriptor, final long pOffset, final long pLength) throws IOException { + final int soundID = pSoundManager.getSoundPool().load(pFileDescriptor, pOffset, pLength, 1); + final Sound sound = new Sound(pSoundManager, soundID); + pSoundManager.add(sound); + return sound; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/sound/SoundLibrary.java b/AndEngine/src/org/anddev/andengine/audio/sound/SoundLibrary.java new file mode 100644 index 0000000..b830172 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/sound/SoundLibrary.java @@ -0,0 +1,37 @@ +package org.anddev.andengine.audio.sound; + +import org.anddev.andengine.util.Library; + +/** + * @author Nicolas Gramlich + * @since 20:41:56 - 20.08.2010 + */ +public class SoundLibrary extends Library { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/audio/sound/SoundManager.java b/AndEngine/src/org/anddev/andengine/audio/sound/SoundManager.java new file mode 100644 index 0000000..2dbf26b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/audio/sound/SoundManager.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.audio.sound; + +import org.anddev.andengine.audio.BaseAudioManager; + +import android.media.AudioManager; +import android.media.SoundPool; + +/** + * @author Nicolas Gramlich + * @since 13:22:59 - 11.03.2010 + */ +public class SoundManager extends BaseAudioManager { + // =========================================================== + // Constants + // =========================================================== + + private static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5; + + // =========================================================== + // Fields + // =========================================================== + + private final SoundPool mSoundPool; + + // =========================================================== + // Constructors + // =========================================================== + + public SoundManager() { + this(MAX_SIMULTANEOUS_STREAMS_DEFAULT); + } + + public SoundManager(final int pMaxSimultaneousStreams) { + this.mSoundPool = new SoundPool(pMaxSimultaneousStreams, AudioManager.STREAM_MUSIC, 0); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + SoundPool getSoundPool() { + return this.mSoundPool; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + @Override + public void releaseAll() { + super.releaseAll(); + + this.mSoundPool.release(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/collision/BaseCollisionChecker.java b/AndEngine/src/org/anddev/andengine/collision/BaseCollisionChecker.java new file mode 100644 index 0000000..14582a7 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/collision/BaseCollisionChecker.java @@ -0,0 +1,112 @@ +package org.anddev.andengine.collision; + +/** + * @author Nicolas Gramlich + * @since 11:50:19 - 11.03.2010 + */ +public class BaseCollisionChecker { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean checkAxisAlignedRectangleCollision(final float pLeftA, final float pTopA, final float pRightA, final float pBottomA, final float pLeftB, final float pTopB, final float pRightB, final float pBottomB) { + return (pLeftA < pRightB && + pLeftB < pRightA && + pTopA < pBottomB && + pTopB < pBottomA); + } + + /** + * Returns an indicator of where the specified point (PX, PY) lies with + * respect to the line segment from (X1, Y1) to (X2, Y2). The + * return value can be either 1, -1, or 0 and indicates in which direction + * the specified line must pivot around its first endpoint, (X1, Y1), + * in order to point at the specified point (PX, PY). + *

+ * A return value of 1 indicates that the line segment must turn in the + * direction that takes the positive X axis towards the negative Y axis. In + * the default coordinate system used by Java 2D, this direction is + * counterclockwise. + *

+ * A return value of -1 indicates that the line segment must turn in the + * direction that takes the positive X axis towards the positive Y axis. In + * the default coordinate system, this direction is clockwise. + *

+ * A return value of 0 indicates that the point lies exactly on the line + * segment. Note that an indicator value of 0 is rare and not useful for + * determining colinearity because of floating point rounding issues. + *

+ * If the point is colinear with the line segment, but not between the + * endpoints, then the value will be -1 if the point lies + * "beyond (X1, Y1)" or 1 if the point lies "beyond (X2, Y2)". + * + * @param pX1 + * , Y1 the coordinates of the beginning of the specified + * line segment + * @param pX2 + * , Y2 the coordinates of the end of the specified line + * segment + * @param pPX + * , PY the coordinates of the specified point to be + * compared with the specified line segment + * @return an integer that indicates the position of the third specified + * coordinates with respect to the line segment formed by the first + * two specified coordinates. + */ + public static int relativeCCW(final float pX1, final float pY1, float pX2, float pY2, float pPX, float pPY) { + pX2 -= pX1; + pY2 -= pY1; + pPX -= pX1; + pPY -= pY1; + float ccw = pPX * pY2 - pPY * pX2; + if (ccw == 0.0f) { + // The point is colinear, classify based on which side of + // the segment the point falls on. We can calculate a + // relative value using the projection of PX,PY onto the + // segment - a negative value indicates the point projects + // outside of the segment in the direction of the particular + // endpoint used as the origin for the projection. + ccw = pPX * pX2 + pPY * pY2; + if (ccw > 0.0f) { + // Reverse the projection to be relative to the original X2,Y2 + // X2 and Y2 are simply negated. + // PX and PY need to have (X2 - X1) or (Y2 - Y1) subtracted + // from them (based on the original values) + // Since we really want to get a positive answer when the + // point is "beyond (X2,Y2)", then we want to calculate + // the inverse anyway - thus we leave X2 & Y2 negated. + pPX -= pX2; + pPY -= pY2; + ccw = pPX * pX2 + pPY * pY2; + if (ccw < 0.0f) { + ccw = 0.0f; + } + } + } + return (ccw < 0.0f) ? -1 : ((ccw > 0.0f) ? 1 : 0); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/collision/LineCollisionChecker.java b/AndEngine/src/org/anddev/andengine/collision/LineCollisionChecker.java new file mode 100644 index 0000000..2170e1d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/collision/LineCollisionChecker.java @@ -0,0 +1,40 @@ +package org.anddev.andengine.collision; + +/** + * @author Nicolas Gramlich + * @since 19:27:22 - 17.07.2010 + */ +public class LineCollisionChecker extends ShapeCollisionChecker { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean checkLineCollision(final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3, final float pX4, final float pY4) { + return ((BaseCollisionChecker.relativeCCW(pX1, pY1, pX2, pY2, pX3, pY3) * BaseCollisionChecker.relativeCCW(pX1, pY1, pX2, pY2, pX4, pY4) <= 0) + && (BaseCollisionChecker.relativeCCW(pX3, pY3, pX4, pY4, pX1, pY1) * BaseCollisionChecker.relativeCCW(pX3, pY3, pX4, pY4, pX2, pY2) <= 0)); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/collision/RectangularShapeCollisionChecker.java b/AndEngine/src/org/anddev/andengine/collision/RectangularShapeCollisionChecker.java new file mode 100644 index 0000000..9ff4b74 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/collision/RectangularShapeCollisionChecker.java @@ -0,0 +1,79 @@ +package org.anddev.andengine.collision; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.entity.shape.RectangularShape; + +/** + * @author Nicolas Gramlich + * @since 11:50:19 - 11.03.2010 + */ +public class RectangularShapeCollisionChecker extends ShapeCollisionChecker { + // =========================================================== + // Constants + // =========================================================== + + private static final int RECTANGULARSHAPE_VERTEX_COUNT = 4; + + private static final float[] VERTICES_CONTAINS_TMP = new float[2 * RECTANGULARSHAPE_VERTEX_COUNT]; + private static final float[] VERTICES_COLLISION_TMP_A = new float[2 * RECTANGULARSHAPE_VERTEX_COUNT]; + private static final float[] VERTICES_COLLISION_TMP_B = new float[2 * RECTANGULARSHAPE_VERTEX_COUNT]; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean checkContains(final RectangularShape pRectangularShape, final float pX, final float pY) { + RectangularShapeCollisionChecker.fillVertices(pRectangularShape, VERTICES_CONTAINS_TMP); + return ShapeCollisionChecker.checkContains(VERTICES_CONTAINS_TMP, 2 * RECTANGULARSHAPE_VERTEX_COUNT, pX, pY); + } + + public static boolean checkCollision(final RectangularShape pRectangularShapeA, final RectangularShape pRectangularShapeB) { + RectangularShapeCollisionChecker.fillVertices(pRectangularShapeA, VERTICES_COLLISION_TMP_A); + RectangularShapeCollisionChecker.fillVertices(pRectangularShapeB, VERTICES_COLLISION_TMP_B); + + return ShapeCollisionChecker.checkCollision(2 * RECTANGULARSHAPE_VERTEX_COUNT, 2 * RECTANGULARSHAPE_VERTEX_COUNT, VERTICES_COLLISION_TMP_A, VERTICES_COLLISION_TMP_B); + } + + public static void fillVertices(final RectangularShape pRectangularShape, final float[] pVertices) { + final float left = 0; + final float top = 0; + final float right = pRectangularShape.getWidth(); + final float bottom = pRectangularShape.getHeight(); + + pVertices[0 + VERTEX_INDEX_X] = left; + pVertices[0 + VERTEX_INDEX_Y] = top; + + pVertices[2 + VERTEX_INDEX_X] = right; + pVertices[2 + VERTEX_INDEX_Y] = top; + + pVertices[4 + VERTEX_INDEX_X] = right; + pVertices[4 + VERTEX_INDEX_Y] = bottom; + + pVertices[6 + VERTEX_INDEX_X] = left; + pVertices[6 + VERTEX_INDEX_Y] = bottom; + + pRectangularShape.getLocalToSceneTransformation().transform(pVertices); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/collision/ShapeCollisionChecker.java b/AndEngine/src/org/anddev/andengine/collision/ShapeCollisionChecker.java new file mode 100644 index 0000000..e111f1d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/collision/ShapeCollisionChecker.java @@ -0,0 +1,108 @@ +package org.anddev.andengine.collision; + +import org.anddev.andengine.util.constants.Constants; + + +/** + * @author Nicolas Gramlich + * @since 11:50:19 - 11.03.2010 + */ +public class ShapeCollisionChecker extends BaseCollisionChecker { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean checkCollision(final int pVerticesALength, final int pVerticesBLength, final float[] pVerticesA, final float[] pVerticesB) { + /* Check all the lines of A ... */ + for(int a = pVerticesALength - 4; a >= 0; a -= 2) { + /* ... against all lines in B. */ + if(ShapeCollisionChecker.checkCollisionSub(a, a + 2, pVerticesA, pVerticesB, pVerticesBLength)){ + return true; + } + } + /* Also check the 'around the corner of the array' line of A against all lines in B. */ + if(ShapeCollisionChecker.checkCollisionSub(pVerticesALength - 2, 0, pVerticesA, pVerticesB, pVerticesBLength)){ + return true; + } else { + /* At last check if one polygon 'contains' the other one by checking + * if one vertex of the one vertices is contained by all of the other vertices. */ + if(ShapeCollisionChecker.checkContains(pVerticesA, pVerticesALength, pVerticesB[Constants.VERTEX_INDEX_X], pVerticesB[Constants.VERTEX_INDEX_Y])) { + return true; + } else if(ShapeCollisionChecker.checkContains(pVerticesB, pVerticesBLength, pVerticesA[Constants.VERTEX_INDEX_X], pVerticesA[Constants.VERTEX_INDEX_Y])) { + return true; + } else { + return false; + } + } + } + + /** + * Checks line specified by pVerticesA[pVertexIndexA1] and pVerticesA[pVertexIndexA2] against all lines in pVerticesB. + */ + private static boolean checkCollisionSub(final int pVertexIndexA1, final int pVertexIndexA2, final float[] pVerticesA, final float[] pVerticesB, final int pVerticesBLength) { + /* Check against all the lines of B. */ + final float vertexA1X = pVerticesA[pVertexIndexA1 + Constants.VERTEX_INDEX_X]; + final float vertexA1Y = pVerticesA[pVertexIndexA1 + Constants.VERTEX_INDEX_Y]; + final float vertexA2X = pVerticesA[pVertexIndexA2 + Constants.VERTEX_INDEX_X]; + final float vertexA2Y = pVerticesA[pVertexIndexA2 + Constants.VERTEX_INDEX_Y]; + + for(int b = pVerticesBLength - 4; b >= 0; b -= 2) { + if(LineCollisionChecker.checkLineCollision(vertexA1X, vertexA1Y, vertexA2X, vertexA2Y, pVerticesB[b + Constants.VERTEX_INDEX_X], pVerticesB[b + Constants.VERTEX_INDEX_Y], pVerticesB[b + 2 + Constants.VERTEX_INDEX_X], pVerticesB[b + 2 + Constants.VERTEX_INDEX_Y])){ + return true; + } + } + /* Also check the 'around the corner of the array' line of B. */ + if(LineCollisionChecker.checkLineCollision(vertexA1X, vertexA1Y, vertexA2X, vertexA2Y, pVerticesB[pVerticesBLength - 2], pVerticesB[pVerticesBLength - 1], pVerticesB[Constants.VERTEX_INDEX_X], pVerticesB[Constants.VERTEX_INDEX_Y])){ + return true; + } + return false; + } + + public static boolean checkContains(final float[] pVertices, final int pVerticesLength, final float pX, final float pY) { + int edgeResultSum = 0; + + for(int i = pVerticesLength - 4; i >= 0; i -= 2) { + final int edgeResult = BaseCollisionChecker.relativeCCW(pVertices[i], pVertices[i + 1], pVertices[i + 2], pVertices[i + 3], pX, pY); + if(edgeResult == 0) { + return true; + } else { + edgeResultSum += edgeResult; + } + } + /* Also check the 'around the corner of the array' line. */ + final int edgeResult = BaseCollisionChecker.relativeCCW(pVertices[pVerticesLength - 2], pVertices[pVerticesLength - 1], pVertices[Constants.VERTEX_INDEX_X], pVertices[Constants.VERTEX_INDEX_Y], pX, pY); + if(edgeResult == 0){ + return true; + } else { + edgeResultSum += edgeResult; + } + + final int vertexCount = pVerticesLength / 2; + /* Point is not on the edge, so check if the edge is on the same side(left or right) of all edges. */ + return edgeResultSum == vertexCount || edgeResultSum == -vertexCount ; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/DoubleSceneSplitScreenEngine.java b/AndEngine/src/org/anddev/andengine/engine/DoubleSceneSplitScreenEngine.java new file mode 100644 index 0000000..dfb5345 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/DoubleSceneSplitScreenEngine.java @@ -0,0 +1,170 @@ +package org.anddev.andengine.engine; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.options.EngineOptions; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.opengl.util.GLHelper; + +/** + * @author Nicolas Gramlich + * @since 22:28:34 - 27.03.2010 + */ +public class DoubleSceneSplitScreenEngine extends Engine { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private Scene mSecondScene; + private final Camera mSecondCamera; + + // =========================================================== + // Constructors + // =========================================================== + + public DoubleSceneSplitScreenEngine(final EngineOptions pEngineOptions, final Camera pSecondCamera) { + super(pEngineOptions); + this.mSecondCamera = pSecondCamera; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Deprecated + @Override + public Camera getCamera() { + return super.mCamera; + } + + public Camera getFirstCamera() { + return super.mCamera; + } + + public Camera getSecondCamera() { + return this.mSecondCamera; + } + + @Deprecated + @Override + public Scene getScene() { + return super.getScene(); + } + + public Scene getFirstScene() { + return super.getScene(); + } + + public Scene getSecondScene() { + return this.mSecondScene; + } + + @Deprecated + @Override + public void setScene(final Scene pScene) { + super.setScene(pScene); + } + + public void setFirstScene(final Scene pScene) { + super.setScene(pScene); + } + + public void setSecondScene(final Scene pScene) { + this.mSecondScene = pScene; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onDrawScene(final GL10 pGL) { + final Camera firstCamera = this.getFirstCamera(); + final Camera secondCamera = this.getSecondCamera(); + + final int surfaceWidth = this.mSurfaceWidth; + final int surfaceWidthHalf = surfaceWidth >> 1; + + final int surfaceHeight = this.mSurfaceHeight; + + GLHelper.enableScissorTest(pGL); + + /* First Screen. With first camera, on the left half of the screens width. */ + { + pGL.glScissor(0, 0, surfaceWidthHalf, surfaceHeight); + pGL.glViewport(0, 0, surfaceWidthHalf, surfaceHeight); + + super.mScene.onDraw(pGL, firstCamera); + firstCamera.onDrawHUD(pGL); + } + + /* Second Screen. With second camera, on the right half of the screens width. */ + { + pGL.glScissor(surfaceWidthHalf, 0, surfaceWidthHalf, surfaceHeight); + pGL.glViewport(surfaceWidthHalf, 0, surfaceWidthHalf, surfaceHeight); + + this.mSecondScene.onDraw(pGL, secondCamera); + secondCamera.onDrawHUD(pGL); + } + + GLHelper.disableScissorTest(pGL); + } + + @Override + protected Camera getCameraFromSurfaceTouchEvent(final TouchEvent pTouchEvent) { + if(pTouchEvent.getX() <= this.mSurfaceWidth >> 1) { + return this.getFirstCamera(); + } else { + return this.getSecondCamera(); + } + } + + @Override + protected Scene getSceneFromSurfaceTouchEvent(final TouchEvent pTouchEvent) { + if(pTouchEvent.getX() <= this.mSurfaceWidth >> 1) { + return this.getFirstScene(); + } else { + return this.getSecondScene(); + } + } + + @Override + protected void onUpdateScene(final float pSecondsElapsed) { + super.onUpdateScene(pSecondsElapsed); + if(this.mSecondScene != null) { + this.mSecondScene.onUpdate(pSecondsElapsed); + } + } + + @Override + protected void convertSurfaceToSceneTouchEvent(final Camera pCamera, final TouchEvent pSurfaceTouchEvent) { + final int surfaceWidthHalf = this.mSurfaceWidth >> 1; + + if(pCamera == this.getFirstCamera()) { + pCamera.convertSurfaceToSceneTouchEvent(pSurfaceTouchEvent, surfaceWidthHalf, this.mSurfaceHeight); + } else { + pSurfaceTouchEvent.offset(-surfaceWidthHalf, 0); + pCamera.convertSurfaceToSceneTouchEvent(pSurfaceTouchEvent, surfaceWidthHalf, this.mSurfaceHeight); + } + } + + @Override + protected void updateUpdateHandlers(final float pSecondsElapsed) { + super.updateUpdateHandlers(pSecondsElapsed); + this.getSecondCamera().onUpdate(pSecondsElapsed); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/Engine.java b/AndEngine/src/org/anddev/andengine/engine/Engine.java new file mode 100644 index 0000000..eec8b20 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/Engine.java @@ -0,0 +1,715 @@ +package org.anddev.andengine.engine; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.audio.music.MusicFactory; +import org.anddev.andengine.audio.music.MusicManager; +import org.anddev.andengine.audio.sound.SoundFactory; +import org.anddev.andengine.audio.sound.SoundManager; +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.engine.handler.UpdateHandlerList; +import org.anddev.andengine.engine.handler.runnable.RunnableHandler; +import org.anddev.andengine.engine.options.EngineOptions; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.input.touch.controller.ITouchController; +import org.anddev.andengine.input.touch.controller.ITouchController.ITouchEventCallback; +import org.anddev.andengine.input.touch.controller.SingleTouchControler; +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.font.FontFactory; +import org.anddev.andengine.opengl.font.FontManager; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.region.TextureRegionFactory; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.sensor.SensorDelay; +import org.anddev.andengine.sensor.accelerometer.AccelerometerData; +import org.anddev.andengine.sensor.accelerometer.AccelerometerSensorOptions; +import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener; +import org.anddev.andengine.sensor.location.ILocationListener; +import org.anddev.andengine.sensor.location.LocationProviderStatus; +import org.anddev.andengine.sensor.location.LocationSensorOptions; +import org.anddev.andengine.sensor.orientation.IOrientationListener; +import org.anddev.andengine.sensor.orientation.OrientationData; +import org.anddev.andengine.sensor.orientation.OrientationSensorOptions; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.constants.TimeConstants; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Bundle; +import android.os.Vibrator; +import android.view.Display; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnTouchListener; +import android.view.WindowManager; + +/** + * @author Nicolas Gramlich + * @since 12:21:31 - 08.03.2010 + */ +public class Engine implements SensorEventListener, OnTouchListener, ITouchEventCallback, TimeConstants, LocationListener { + // =========================================================== + // Constants + // =========================================================== + + private static final SensorDelay SENSORDELAY_DEFAULT = SensorDelay.GAME; + + // =========================================================== + // Fields + // =========================================================== + + private boolean mRunning = false; + + private long mLastTick = -1; + private float mSecondsElapsedTotal = 0; + + private final State mThreadLocker = new State(); + + private final UpdateThread mUpdateThread = new UpdateThread(); + + private final RunnableHandler mUpdateThreadRunnableHandler = new RunnableHandler(); + + private final EngineOptions mEngineOptions; + protected final Camera mCamera; + + private ITouchController mTouchController; + + private SoundManager mSoundManager; + private MusicManager mMusicManager; + private final TextureManager mTextureManager = new TextureManager(); + private final BufferObjectManager mBufferObjectManager = new BufferObjectManager(); + private final FontManager mFontManager = new FontManager(); + + protected Scene mScene; + + private Vibrator mVibrator; + + private ILocationListener mLocationListener; + private Location mLocation; + + private IAccelerometerListener mAccelerometerListener; + private AccelerometerData mAccelerometerData; + + private IOrientationListener mOrientationListener; + private OrientationData mOrientationData; + + private final UpdateHandlerList mUpdateHandlers = new UpdateHandlerList(); + + protected int mSurfaceWidth = 1; // 1 to prevent accidental DIV/0 + protected int mSurfaceHeight = 1; // 1 to prevent accidental DIV/0 + + private boolean mIsMethodTracing; + + // =========================================================== + // Constructors + // =========================================================== + + public Engine(final EngineOptions pEngineOptions) { + TextureRegionFactory.setAssetBasePath(""); + SoundFactory.setAssetBasePath(""); + MusicFactory.setAssetBasePath(""); + FontFactory.setAssetBasePath(""); + + BufferObjectManager.setActiveInstance(this.mBufferObjectManager); + + this.mEngineOptions = pEngineOptions; + this.setTouchController(new SingleTouchControler()); + this.mCamera = pEngineOptions.getCamera(); + + if(this.mEngineOptions.needsSound()) { + this.mSoundManager = new SoundManager(); + } + + if(this.mEngineOptions.needsMusic()) { + this.mMusicManager = new MusicManager(); + } + + this.mUpdateThread.start(); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isRunning() { + return this.mRunning; + } + + public synchronized void start() { + if(!this.mRunning) { + this.mLastTick = System.nanoTime(); + this.mRunning = true; + } + } + + public synchronized void stop() { + if(this.mRunning) { + this.mRunning = false; + } + } + + public Scene getScene() { + return this.mScene; + } + + public void setScene(final Scene pScene) { + this.mScene = pScene; + } + + public EngineOptions getEngineOptions() { + return this.mEngineOptions; + } + + public Camera getCamera() { + return this.mCamera; + } + + public float getSecondsElapsedTotal() { + return this.mSecondsElapsedTotal; + } + + public void setSurfaceSize(final int pSurfaceWidth, final int pSurfaceHeight) { + // Debug.w("SurfaceView size changed to (width x height): " + pSurfaceWidth + " x " + pSurfaceHeight, new Exception()); + this.mSurfaceWidth = pSurfaceWidth; + this.mSurfaceHeight = pSurfaceHeight; + } + + public int getSurfaceWidth() { + return this.mSurfaceWidth; + } + + public int getSurfaceHeight() { + return this.mSurfaceHeight; + } + + public ITouchController getTouchController() { + return this.mTouchController; + } + + public void setTouchController(final ITouchController pTouchController) { + this.mTouchController = pTouchController; + this.mTouchController.applyTouchOptions(this.mEngineOptions.getTouchOptions()); + this.mTouchController.setTouchEventCallback(this); + } + + public AccelerometerData getAccelerometerData() { + return this.mAccelerometerData; + } + + public OrientationData getOrientationData() { + return this.mOrientationData; + } + + public SoundManager getSoundManager() throws IllegalStateException { + if(this.mSoundManager != null) { + return this.mSoundManager; + } else { + throw new IllegalStateException("To enable the SoundManager, check the EngineOptions!"); + } + } + + public MusicManager getMusicManager() throws IllegalStateException { + if(this.mMusicManager != null) { + return this.mMusicManager; + } else { + throw new IllegalStateException("To enable the MusicManager, check the EngineOptions!"); + } + } + + public TextureManager getTextureManager() { + return this.mTextureManager; + } + + public FontManager getFontManager() { + return this.mFontManager; + } + + public void clearUpdateHandlers() { + this.mUpdateHandlers.clear(); + } + + public void registerUpdateHandler(final IUpdateHandler pUpdateHandler) { + this.mUpdateHandlers.add(pUpdateHandler); + } + + public void unregisterUpdateHandler(final IUpdateHandler pUpdateHandler) { + this.mUpdateHandlers.remove(pUpdateHandler); + } + + public boolean isMethodTracing() { + return this.mIsMethodTracing; + } + + public void startMethodTracing(final String pTraceFileName) { + if(!this.mIsMethodTracing) { + this.mIsMethodTracing = true; + android.os.Debug.startMethodTracing(pTraceFileName); + } + } + + public void stopMethodTracing() { + if(this.mIsMethodTracing) { + android.os.Debug.stopMethodTracing(); + this.mIsMethodTracing = false; + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onAccuracyChanged(final Sensor pSensor, final int pAccuracy) { + if(this.mRunning) { + switch(pSensor.getType()) { + case Sensor.TYPE_ACCELEROMETER: + if(this.mAccelerometerData != null) { + this.mAccelerometerData.setAccuracy(pAccuracy); + this.mAccelerometerListener.onAccelerometerChanged(this.mAccelerometerData); + } else if(this.mOrientationData != null) { + this.mOrientationData.setAccelerometerAccuracy(pAccuracy); + this.mOrientationListener.onOrientationChanged(this.mOrientationData); + } + break; + case Sensor.TYPE_MAGNETIC_FIELD: + this.mOrientationData.setMagneticFieldAccuracy(pAccuracy); + this.mOrientationListener.onOrientationChanged(this.mOrientationData); + break; + } + } + } + + @Override + public void onSensorChanged(final SensorEvent pEvent) { + if(this.mRunning) { + switch(pEvent.sensor.getType()) { + case Sensor.TYPE_ACCELEROMETER: + if(this.mAccelerometerData != null) { + this.mAccelerometerData.setValues(pEvent.values); + this.mAccelerometerListener.onAccelerometerChanged(this.mAccelerometerData); + } else if(this.mOrientationData != null) { + this.mOrientationData.setAccelerometerValues(pEvent.values); + this.mOrientationListener.onOrientationChanged(this.mOrientationData); + } + break; + case Sensor.TYPE_MAGNETIC_FIELD: + this.mOrientationData.setMagneticFieldValues(pEvent.values); + this.mOrientationListener.onOrientationChanged(this.mOrientationData); + break; + } + } + } + + @Override + public void onLocationChanged(final Location pLocation) { + if(this.mLocation == null) { + this.mLocation = pLocation; + } else { + if(pLocation == null) { + this.mLocationListener.onLocationLost(); + } else { + this.mLocation = pLocation; + this.mLocationListener.onLocationChanged(pLocation); + } + } + } + + @Override + public void onProviderDisabled(final String pProvider) { + this.mLocationListener.onLocationProviderDisabled(); + } + + @Override + public void onProviderEnabled(final String pProvider) { + this.mLocationListener.onLocationProviderEnabled(); + } + + @Override + public void onStatusChanged(final String pProvider, final int pStatus, final Bundle pExtras) { + switch(pStatus) { + case LocationProvider.AVAILABLE: + this.mLocationListener.onLocationProviderStatusChanged(LocationProviderStatus.AVAILABLE, pExtras); + break; + case LocationProvider.OUT_OF_SERVICE: + this.mLocationListener.onLocationProviderStatusChanged(LocationProviderStatus.OUT_OF_SERVICE, pExtras); + break; + case LocationProvider.TEMPORARILY_UNAVAILABLE: + this.mLocationListener.onLocationProviderStatusChanged(LocationProviderStatus.TEMPORARILY_UNAVAILABLE, pExtras); + break; + } + } + + @Override + public boolean onTouch(final View pView, final MotionEvent pSurfaceMotionEvent) { + if(this.mRunning) { + final boolean handled = this.mTouchController.onHandleMotionEvent(pSurfaceMotionEvent); + try { + /* + * As a human cannot interact 1000x per second, we pause the + * UI-Thread for a little. + */ + Thread.sleep(20); // TODO Maybe this can be removed, when TouchEvents are handled on the UpdateThread! + } catch (final InterruptedException e) { + Debug.e(e); + } + return handled; + } else { + return false; + } + } + + @Override + public boolean onTouchEvent(final TouchEvent pSurfaceTouchEvent) { + /* + * Let the engine determine which scene and camera this event should be + * handled by. + */ + final Scene scene = this.getSceneFromSurfaceTouchEvent(pSurfaceTouchEvent); + final Camera camera = this.getCameraFromSurfaceTouchEvent(pSurfaceTouchEvent); + + this.convertSurfaceToSceneTouchEvent(camera, pSurfaceTouchEvent); + + if(this.onTouchHUD(camera, pSurfaceTouchEvent)) { + return true; + } else { + /* If HUD didn't handle it, Scene may handle it. */ + return this.onTouchScene(scene, pSurfaceTouchEvent); + } + } + + protected boolean onTouchHUD(final Camera pCamera, final TouchEvent pSceneTouchEvent) { + if(pCamera.hasHUD()) { + return pCamera.getHUD().onSceneTouchEvent(pSceneTouchEvent); + } else { + return false; + } + } + + protected boolean onTouchScene(final Scene pScene, final TouchEvent pSceneTouchEvent) { + if(pScene != null) { + return pScene.onSceneTouchEvent(pSceneTouchEvent); + } else { + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + public void runOnUpdateThread(final Runnable pRunnable) { + this.mUpdateThreadRunnableHandler.postRunnable(pRunnable); + } + + public void interruptUpdateThread(){ + this.mUpdateThread.interrupt(); + } + + public void onResume() { + this.mTextureManager.reloadTextures(); + this.mFontManager.reloadFonts(); + BufferObjectManager.setActiveInstance(this.mBufferObjectManager); + this.mBufferObjectManager.reloadBufferObjects(); + } + + public void onPause() { + + } + + protected Camera getCameraFromSurfaceTouchEvent(final TouchEvent pTouchEvent) { + return this.getCamera(); + } + + protected Scene getSceneFromSurfaceTouchEvent(final TouchEvent pTouchEvent) { + return this.mScene; + } + + protected void convertSurfaceToSceneTouchEvent(final Camera pCamera, final TouchEvent pSurfaceTouchEvent) { + pCamera.convertSurfaceToSceneTouchEvent(pSurfaceTouchEvent, this.mSurfaceWidth, this.mSurfaceHeight); + } + + public void onLoadComplete(final Scene pScene) { + this.setScene(pScene); + } + + void onTickUpdate() throws InterruptedException { + if(this.mRunning) { + final long secondsElapsed = this.getNanosecondsElapsed(); + + this.onUpdate(secondsElapsed); + + this.yieldDraw(); + } else { + this.yieldDraw(); + + Thread.sleep(16); + } + } + + private void yieldDraw() throws InterruptedException { + final State threadLocker = this.mThreadLocker; + threadLocker.notifyCanDraw(); + threadLocker.waitUntilCanUpdate(); + } + + protected void onUpdate(final long pNanosecondsElapsed) throws InterruptedException { + final float pSecondsElapsed = (float)pNanosecondsElapsed / TimeConstants.NANOSECONDSPERSECOND; + + this.mSecondsElapsedTotal += pSecondsElapsed; + this.mLastTick += pNanosecondsElapsed; + + this.mTouchController.onUpdate(pSecondsElapsed); + this.updateUpdateHandlers(pSecondsElapsed); + this.onUpdateScene(pSecondsElapsed); + } + + protected void onUpdateScene(final float pSecondsElapsed) { + if(this.mScene != null) { + this.mScene.onUpdate(pSecondsElapsed); + } + } + + protected void updateUpdateHandlers(final float pSecondsElapsed) { + this.mUpdateThreadRunnableHandler.onUpdate(pSecondsElapsed); + this.mUpdateHandlers.onUpdate(pSecondsElapsed); + this.getCamera().onUpdate(pSecondsElapsed); + } + + public void onDrawFrame(final GL10 pGL) throws InterruptedException { + final State threadLocker = this.mThreadLocker; + + threadLocker.waitUntilCanDraw(); + + this.mTextureManager.updateTextures(pGL); + this.mFontManager.updateFonts(pGL); + if(GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS) { + this.mBufferObjectManager.updateBufferObjects((GL11) pGL); + } + + this.onDrawScene(pGL); + + threadLocker.notifyCanUpdate(); + } + + protected void onDrawScene(final GL10 pGL) { + final Camera camera = this.getCamera(); + + this.mScene.onDraw(pGL, camera); + + camera.onDrawHUD(pGL); + } + + private long getNanosecondsElapsed() { + final long now = System.nanoTime(); + + return this.calculateNanosecondsElapsed(now, this.mLastTick); + } + + protected long calculateNanosecondsElapsed(final long pNow, final long pLastTick) { + return pNow - pLastTick; + } + + public boolean enableVibrator(final Context pContext) { + this.mVibrator = (Vibrator) pContext.getSystemService(Context.VIBRATOR_SERVICE); + return this.mVibrator != null; + } + + public void vibrate(final long pMilliseconds) throws IllegalStateException { + if(this.mVibrator != null) { + this.mVibrator.vibrate(pMilliseconds); + } else { + throw new IllegalStateException("You need to enable the Vibrator before you can use it!"); + } + } + + public void vibrate(final long[] pPattern, final int pRepeat) throws IllegalStateException { + if(this.mVibrator != null) { + this.mVibrator.vibrate(pPattern, pRepeat); + } else { + throw new IllegalStateException("You need to enable the Vibrator before you can use it!"); + } + } + + public void enableLocationSensor(final Context pContext, final ILocationListener pLocationListener, final LocationSensorOptions pLocationSensorOptions) { + this.mLocationListener = pLocationListener; + + final LocationManager locationManager = (LocationManager) pContext.getSystemService(Context.LOCATION_SERVICE); + final String locationProvider = locationManager.getBestProvider(pLocationSensorOptions, pLocationSensorOptions.isEnabledOnly()); + // TODO locationProvider can be null, in that case return false. Successful case should return true. + locationManager.requestLocationUpdates(locationProvider, pLocationSensorOptions.getMinimumTriggerTime(), pLocationSensorOptions.getMinimumTriggerDistance(), this); + + this.onLocationChanged(locationManager.getLastKnownLocation(locationProvider)); + } + + public void disableLocationSensor(final Context pContext) { + final LocationManager locationManager = (LocationManager) pContext.getSystemService(Context.LOCATION_SERVICE); + locationManager.removeUpdates(this); + } + + /** + * @see {@link Engine#enableAccelerometerSensor(Context, IAccelerometerListener, AccelerometerSensorOptions)} + */ + public boolean enableAccelerometerSensor(final Context pContext, final IAccelerometerListener pAccelerometerListener) { + return this.enableAccelerometerSensor(pContext, pAccelerometerListener, new AccelerometerSensorOptions(SENSORDELAY_DEFAULT)); + } + + /** + * @return true when the sensor was successfully enabled, false otherwise. + */ + public boolean enableAccelerometerSensor(final Context pContext, final IAccelerometerListener pAccelerometerListener, final AccelerometerSensorOptions pAccelerometerSensorOptions) { + final SensorManager sensorManager = (SensorManager) pContext.getSystemService(Context.SENSOR_SERVICE); + if(this.isSensorSupported(sensorManager, Sensor.TYPE_ACCELEROMETER)) { + this.mAccelerometerListener = pAccelerometerListener; + + if(this.mAccelerometerData == null) { + this.mAccelerometerData = new AccelerometerData(); + } + + this.registerSelfAsSensorListener(sensorManager, Sensor.TYPE_ACCELEROMETER, pAccelerometerSensorOptions.getSensorDelay()); + + return true; + } else { + return false; + } + } + + + /** + * @return true when the sensor was successfully disabled, false otherwise. + */ + public boolean disableAccelerometerSensor(final Context pContext) { + final SensorManager sensorManager = (SensorManager) pContext.getSystemService(Context.SENSOR_SERVICE); + if(this.isSensorSupported(sensorManager, Sensor.TYPE_ACCELEROMETER)) { + this.unregisterSelfAsSensorListener(sensorManager, Sensor.TYPE_ACCELEROMETER); + return true; + } else { + return false; + } + } + + /** + * @see {@link Engine#enableOrientationSensor(Context, IOrientationListener, OrientationSensorOptions)} + */ + public boolean enableOrientationSensor(final Context pContext, final IOrientationListener pOrientationListener) { + return this.enableOrientationSensor(pContext, pOrientationListener, new OrientationSensorOptions(SENSORDELAY_DEFAULT)); + } + + /** + * @return true when the sensor was successfully enabled, false otherwise. + */ + public boolean enableOrientationSensor(final Context pContext, final IOrientationListener pOrientationListener, final OrientationSensorOptions pOrientationSensorOptions) { + final SensorManager sensorManager = (SensorManager) pContext.getSystemService(Context.SENSOR_SERVICE); + if(this.isSensorSupported(sensorManager, Sensor.TYPE_ACCELEROMETER) && this.isSensorSupported(sensorManager, Sensor.TYPE_MAGNETIC_FIELD)) { + this.mOrientationListener = pOrientationListener; + + if(this.mOrientationData == null) { + final Display display = ((WindowManager) pContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + final int displayRotation = display.getOrientation(); + this.mOrientationData = new OrientationData(displayRotation); + } + + this.registerSelfAsSensorListener(sensorManager, Sensor.TYPE_ACCELEROMETER, pOrientationSensorOptions.getSensorDelay()); + this.registerSelfAsSensorListener(sensorManager, Sensor.TYPE_MAGNETIC_FIELD, pOrientationSensorOptions.getSensorDelay()); + + return true; + } else { + return false; + } + } + + + /** + * @return true when the sensor was successfully disabled, false otherwise. + */ + public boolean disableOrientationSensor(final Context pContext) { + final SensorManager sensorManager = (SensorManager) pContext.getSystemService(Context.SENSOR_SERVICE); + if(this.isSensorSupported(sensorManager, Sensor.TYPE_ACCELEROMETER) && this.isSensorSupported(sensorManager, Sensor.TYPE_MAGNETIC_FIELD)) { + this.unregisterSelfAsSensorListener(sensorManager, Sensor.TYPE_ACCELEROMETER); + this.unregisterSelfAsSensorListener(sensorManager, Sensor.TYPE_MAGNETIC_FIELD); + return true; + } else { + return false; + } + } + + private boolean isSensorSupported(final SensorManager pSensorManager, final int pType) { + return pSensorManager.getSensorList(pType).size() > 0; + } + + private void registerSelfAsSensorListener(final SensorManager pSensorManager, final int pType, final SensorDelay pSensorDelay) { + final Sensor sensor = pSensorManager.getSensorList(pType).get(0); + pSensorManager.registerListener(this, sensor, pSensorDelay.getDelay()); + } + + private void unregisterSelfAsSensorListener(final SensorManager pSensorManager, final int pType) { + final Sensor sensor = pSensorManager.getSensorList(pType).get(0); + pSensorManager.unregisterListener(this, sensor); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private class UpdateThread extends Thread { + public UpdateThread() { + super("UpdateThread"); + } + + @Override + public void run() { + android.os.Process.setThreadPriority(Engine.this.mEngineOptions.getUpdateThreadPriority()); + try { + while(true) { + Engine.this.onTickUpdate(); + } + } catch (final InterruptedException e) { + Debug.d("UpdateThread interrupted. Don't worry - this Exception is most likely expected!", e); + this.interrupt(); + } + } + } + + private static class State { + boolean mDrawing = false; + + public synchronized void notifyCanDraw() { + // Debug.d(">>> notifyCanDraw"); + this.mDrawing = true; + this.notifyAll(); + // Debug.d("<<< notifyCanDraw"); + } + + public synchronized void notifyCanUpdate() { + // Debug.d(">>> notifyCanUpdate"); + this.mDrawing = false; + this.notifyAll(); + // Debug.d("<<< notifyCanUpdate"); + } + + public synchronized void waitUntilCanDraw() throws InterruptedException { + // Debug.d(">>> waitUntilCanDraw"); + while(this.mDrawing == false) { + this.wait(); + } + // Debug.d("<<< waitUntilCanDraw"); + } + + public synchronized void waitUntilCanUpdate() throws InterruptedException { + // Debug.d(">>> waitUntilCanUpdate"); + while(this.mDrawing == true) { + this.wait(); + } + // Debug.d("<<< waitUntilCanUpdate"); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/engine/FixedStepEngine.java b/AndEngine/src/org/anddev/andengine/engine/FixedStepEngine.java new file mode 100644 index 0000000..3dce1d9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/FixedStepEngine.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.engine; + +import org.anddev.andengine.engine.options.EngineOptions; + + +/** + * A subclass of {@link Engine} that tries to achieve a specific amount of updates per second. + * When the time since the last update is bigger long the steplength, additional updates are executed. + * + * @author Nicolas Gramlich + * @since 10:17:47 - 02.08.2010 + */ +public class FixedStepEngine extends Engine { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final long mStepLength; + private long mSecondsElapsedAccumulator; + + // =========================================================== + // Constructors + // =========================================================== + + public FixedStepEngine(final EngineOptions pEngineOptions, final int pStepsPerSecond) { + super(pEngineOptions); + this.mStepLength = NANOSECONDSPERSECOND / pStepsPerSecond; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final long pNanosecondsElapsed) throws InterruptedException { + this.mSecondsElapsedAccumulator += pNanosecondsElapsed; + + final long stepLength = this.mStepLength; + while(this.mSecondsElapsedAccumulator >= stepLength) { + super.onUpdate(stepLength); + this.mSecondsElapsedAccumulator -= stepLength; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/LimitedFPSEngine.java b/AndEngine/src/org/anddev/andengine/engine/LimitedFPSEngine.java new file mode 100644 index 0000000..7062c9f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/LimitedFPSEngine.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.engine; + +import org.anddev.andengine.engine.options.EngineOptions; + +/** + * A subclass of {@link Engine} that tries to achieve a specific amount of + * updates per second. When the time since the last update is bigger long the + * steplength, additional updates are executed. + * + * @author Nicolas Gramlich + * @since 10:17:47 - 02.08.2010 + */ +public class LimitedFPSEngine extends Engine { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final long mPreferredFrameLengthNanoseconds; + + // =========================================================== + // Constructors + // =========================================================== + + public LimitedFPSEngine(final EngineOptions pEngineOptions, final int pFramesPerSecond) { + super(pEngineOptions); + this.mPreferredFrameLengthNanoseconds = NANOSECONDSPERSECOND / pFramesPerSecond; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final long pNanosecondsElapsed) throws InterruptedException { + final long preferredFrameLengthNanoseconds = this.mPreferredFrameLengthNanoseconds; + final long deltaFrameLengthNanoseconds = preferredFrameLengthNanoseconds - pNanosecondsElapsed; + + if(deltaFrameLengthNanoseconds <= 0) { + super.onUpdate(pNanosecondsElapsed); + } else { + final int sleepTimeMilliseconds = (int) (deltaFrameLengthNanoseconds / NANOSECONDSPERMILLISECOND); + + Thread.sleep(sleepTimeMilliseconds); + super.onUpdate(pNanosecondsElapsed + deltaFrameLengthNanoseconds); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/SingleSceneSplitScreenEngine.java b/AndEngine/src/org/anddev/andengine/engine/SingleSceneSplitScreenEngine.java new file mode 100644 index 0000000..6429c7f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/SingleSceneSplitScreenEngine.java @@ -0,0 +1,123 @@ +package org.anddev.andengine.engine; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.options.EngineOptions; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.opengl.util.GLHelper; + +/** + * @author Nicolas Gramlich + * @since 22:28:34 - 27.03.2010 + */ +public class SingleSceneSplitScreenEngine extends Engine { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Camera mSecondCamera; + + // =========================================================== + // Constructors + // =========================================================== + + public SingleSceneSplitScreenEngine(final EngineOptions pEngineOptions, final Camera pSecondCamera) { + super(pEngineOptions); + this.mSecondCamera = pSecondCamera; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Deprecated + @Override + public Camera getCamera() { + return super.mCamera; + } + + public Camera getFirstCamera() { + return super.mCamera; + } + + public Camera getSecondCamera() { + return this.mSecondCamera; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onDrawScene(final GL10 pGL) { + final Camera firstCamera = this.getFirstCamera(); + final Camera secondCamera = this.getSecondCamera(); + + final int surfaceWidth = this.mSurfaceWidth; + final int surfaceWidthHalf = surfaceWidth >> 1; + + final int surfaceHeight = this.mSurfaceHeight; + + GLHelper.enableScissorTest(pGL); + + /* First Screen. With first camera, on the left half of the screens width. */ + { + pGL.glScissor(0, 0, surfaceWidthHalf, surfaceHeight); + pGL.glViewport(0, 0, surfaceWidthHalf, surfaceHeight); + + super.mScene.onDraw(pGL, firstCamera); + firstCamera.onDrawHUD(pGL); + } + + /* Second Screen. With second camera, on the right half of the screens width. */ + { + pGL.glScissor(surfaceWidthHalf, 0, surfaceWidthHalf, surfaceHeight); + pGL.glViewport(surfaceWidthHalf, 0, surfaceWidthHalf, surfaceHeight); + + super.mScene.onDraw(pGL, secondCamera); + secondCamera.onDrawHUD(pGL); + } + + GLHelper.disableScissorTest(pGL); + } + + @Override + protected Camera getCameraFromSurfaceTouchEvent(final TouchEvent pTouchEvent) { + if(pTouchEvent.getX() <= this.mSurfaceWidth >> 1) { + return this.getFirstCamera(); + } else { + return this.getSecondCamera(); + } + } + + @Override + protected void convertSurfaceToSceneTouchEvent(final Camera pCamera, final TouchEvent pSurfaceTouchEvent) { + final int surfaceWidthHalf = this.mSurfaceWidth >> 1; + + if(pCamera == this.getFirstCamera()) { + pCamera.convertSurfaceToSceneTouchEvent(pSurfaceTouchEvent, surfaceWidthHalf, this.mSurfaceHeight); + } else { + pSurfaceTouchEvent.offset(-surfaceWidthHalf, 0); + pCamera.convertSurfaceToSceneTouchEvent(pSurfaceTouchEvent, surfaceWidthHalf, this.mSurfaceHeight); + } + } + + @Override + protected void updateUpdateHandlers(final float pSecondsElapsed) { + super.updateUpdateHandlers(pSecondsElapsed); + this.getSecondCamera().onUpdate(pSecondsElapsed); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/BoundCamera.java b/AndEngine/src/org/anddev/andengine/engine/camera/BoundCamera.java new file mode 100644 index 0000000..789bc8e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/BoundCamera.java @@ -0,0 +1,164 @@ +package org.anddev.andengine.engine.camera; + +/** + * @author Nicolas Gramlich + * @since 15:55:54 - 27.07.2010 + */ +public class BoundCamera extends Camera { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected boolean mBoundsEnabled; + + private float mBoundsMinX; + private float mBoundsMaxX; + private float mBoundsMinY; + private float mBoundsMaxY; + + private float mBoundsCenterX; + private float mBoundsCenterY; + + private float mBoundsWidth; + private float mBoundsHeight; + + // =========================================================== + // Constructors + // =========================================================== + + public BoundCamera(final float pX, final float pY, final float pWidth, final float pHeight) { + super(pX, pY, pWidth, pHeight); + } + + public BoundCamera(final float pX, final float pY, final float pWidth, final float pHeight, final float pBoundMinX, final float pBoundMaxX, final float pBoundMinY, final float pBoundMaxY) { + super(pX, pY, pWidth, pHeight); + this.setBounds(pBoundMinX, pBoundMaxX, pBoundMinY, pBoundMaxY); + this.mBoundsEnabled = true; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isBoundsEnabled() { + return this.mBoundsEnabled; + } + + public void setBoundsEnabled(final boolean pBoundsEnabled) { + this.mBoundsEnabled = pBoundsEnabled; + } + + public void setBounds(final float pBoundMinX, final float pBoundMaxX, final float pBoundMinY, final float pBoundMaxY) { + this.mBoundsMinX = pBoundMinX; + this.mBoundsMaxX = pBoundMaxX; + this.mBoundsMinY = pBoundMinY; + this.mBoundsMaxY = pBoundMaxY; + + this.mBoundsWidth = this.mBoundsMaxX - this.mBoundsMinX; + this.mBoundsHeight = this.mBoundsMaxY - this.mBoundsMinY; + + this.mBoundsCenterX = this.mBoundsMinX + this.mBoundsWidth * 0.5f; + this.mBoundsCenterY = this.mBoundsMinY + this.mBoundsHeight * 0.5f; + } + + public float getBoundsWidth() { + return this.mBoundsWidth; + } + + public float getBoundsHeight() { + return this.mBoundsHeight; + } + + @Override + public void setCenter(final float pCenterX, final float pCenterY) { + super.setCenter(pCenterX, pCenterY); + + if(this.mBoundsEnabled) { + this.ensureInBounds(); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + protected void ensureInBounds() { + super.setCenter(this.determineBoundedX(), this.determineBoundedY()); + } + + private float determineBoundedX() { + if(this.mBoundsWidth < this.getWidth()) { + return this.mBoundsCenterX; + } else { + final float currentCenterX = this.getCenterX(); + + final float minXBoundExceededAmount = this.mBoundsMinX - this.getMinX(); + final boolean minXBoundExceeded = minXBoundExceededAmount > 0; + + final float maxXBoundExceededAmount = this.getMaxX() - this.mBoundsMaxX; + final boolean maxXBoundExceeded = maxXBoundExceededAmount > 0; + + if(minXBoundExceeded) { + if(maxXBoundExceeded) { + /* Min and max X exceeded. */ + return currentCenterX - maxXBoundExceededAmount + minXBoundExceededAmount; + } else { + /* Only min X exceeded. */ + return currentCenterX + minXBoundExceededAmount; + } + } else { + if(maxXBoundExceeded) { + /* Only max X exceeded. */ + return currentCenterX - maxXBoundExceededAmount; + } else { + /* Nothing exceeded. */ + return currentCenterX; + } + } + } + } + + private float determineBoundedY() { + if(this.mBoundsHeight < this.getHeight()) { + return this.mBoundsCenterY; + } else { + final float currentCenterY = this.getCenterY(); + + final float minYBoundExceededAmount = this.mBoundsMinY - this.getMinY(); + final boolean minYBoundExceeded = minYBoundExceededAmount > 0; + + final float maxYBoundExceededAmount = this.getMaxY() - this.mBoundsMaxY; + final boolean maxYBoundExceeded = maxYBoundExceededAmount > 0; + + if(minYBoundExceeded) { + if(maxYBoundExceeded) { + /* Min and max Y exceeded. */ + return currentCenterY - maxYBoundExceededAmount + minYBoundExceededAmount; + } else { + /* Only min Y exceeded. */ + return currentCenterY + minYBoundExceededAmount; + } + } else { + if(maxYBoundExceeded) { + /* Only max Y exceeded. */ + return currentCenterY - maxYBoundExceededAmount; + } else { + /* Nothing exceeded. */ + return currentCenterY; + } + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/Camera.java b/AndEngine/src/org/anddev/andengine/engine/camera/Camera.java new file mode 100644 index 0000000..d733a98 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/Camera.java @@ -0,0 +1,364 @@ +package org.anddev.andengine.engine.camera; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.collision.BaseCollisionChecker; +import org.anddev.andengine.engine.camera.hud.HUD; +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.entity.shape.RectangularShape; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.util.MathUtils; + +/** + * @author Nicolas Gramlich + * @since 10:24:18 - 25.03.2010 + */ +public class Camera implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + protected static final float[] VERTICES_TOUCH_TMP = new float[2]; + + // =========================================================== + // Fields + // =========================================================== + + private float mMinX; + private float mMaxX; + private float mMinY; + private float mMaxY; + + private float mNearZ = -1.0f; + private float mFarZ = 1.0f; + + private HUD mHUD; + + private IEntity mChaseEntity; + + protected float mRotation = 0; + protected float mCameraSceneRotation = 0; + + // =========================================================== + // Constructors + // =========================================================== + + public Camera(final float pX, final float pY, final float pWidth, final float pHeight) { + this.mMinX = pX; + this.mMaxX = pX + pWidth; + this.mMinY = pY; + this.mMaxY = pY + pHeight; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getMinX() { + return this.mMinX; + } + + public float getMaxX() { + return this.mMaxX; + } + + public float getMinY() { + return this.mMinY; + } + + public float getMaxY() { + return this.mMaxY; + } + + public float getNearZClippingPlane() { + return this.mNearZ; + } + + public float getFarZClippingPlane() { + return this.mFarZ; + } + + public void setNearZClippingPlane(final float pNearZClippingPlane) { + this.mNearZ = pNearZClippingPlane; + } + + public void setFarZClippingPlane(final float pFarZClippingPlane) { + this.mFarZ = pFarZClippingPlane; + } + + public void setZClippingPlanes(final float pNearZClippingPlane, final float pFarZClippingPlane) { + this.mNearZ = pNearZClippingPlane; + this.mFarZ = pFarZClippingPlane; + } + + public float getWidth() { + return this.mMaxX - this.mMinX; + } + + public float getHeight() { + return this.mMaxY - this.mMinY; + } + + public float getCenterX() { + final float minX = this.mMinX; + return minX + (this.mMaxX - minX) * 0.5f; + } + + public float getCenterY() { + final float minY = this.mMinY; + return minY + (this.mMaxY - minY) * 0.5f; + } + + public void setCenter(final float pCenterX, final float pCenterY) { + final float dX = pCenterX - this.getCenterX(); + final float dY = pCenterY - this.getCenterY(); + + this.mMinX += dX; + this.mMaxX += dX; + this.mMinY += dY; + this.mMaxY += dY; + } + + public void offsetCenter(final float pX, final float pY) { + this.setCenter(this.getCenterX() + pX, this.getCenterY() + pY); + } + + public HUD getHUD() { + return this.mHUD; + } + + public void setHUD(final HUD pHUD) { + this.mHUD = pHUD; + pHUD.setCamera(this); + } + + public boolean hasHUD() { + return this.mHUD != null; + } + + public void setChaseEntity(final IEntity pChaseEntity) { + this.mChaseEntity = pChaseEntity; + } + + public float getRotation() { + return this.mRotation; + } + + public void setRotation(final float pRotation) { + this.mRotation = pRotation; + } + + public float getCameraSceneRotation() { + return this.mCameraSceneRotation; + } + + public void setCameraSceneRotation(final float pCameraSceneRotation) { + this.mCameraSceneRotation = pCameraSceneRotation; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + if(this.mHUD != null) { + this.mHUD.onUpdate(pSecondsElapsed); + } + + if(this.mChaseEntity != null) { + final float[] centerCoordinates = this.mChaseEntity.getSceneCenterCoordinates(); + this.setCenter(centerCoordinates[VERTEX_INDEX_X], centerCoordinates[VERTEX_INDEX_Y]); + } + } + + @Override + public void reset() { + + } + + // =========================================================== + // Methods + // =========================================================== + + public void onDrawHUD(final GL10 pGL) { + if(this.mHUD != null) { + this.mHUD.onDraw(pGL, this); + } + } + + public boolean isRectangularShapeVisible(final RectangularShape pRectangularShape) { + final float otherLeft = pRectangularShape.getX(); + final float otherTop = pRectangularShape.getY(); + final float otherRight = pRectangularShape.getWidthScaled() + otherLeft; + final float otherBottom = pRectangularShape.getHeightScaled() + otherTop; + + // TODO Should also use RectangularShapeCollisionChecker + return BaseCollisionChecker.checkAxisAlignedRectangleCollision(this.getMinX(), this.getMinY(), this.getMaxX(), this.getMaxY(), otherLeft, otherTop, otherRight, otherBottom); + } + + public void onApplyMatrix(final GL10 pGL) { + GLHelper.setProjectionIdentityMatrix(pGL); + + pGL.glOrthof(this.getMinX(), this.getMaxX(), this.getMaxY(), this.getMinY(), this.mNearZ, this.mFarZ); + + final float rotation = this.mRotation; + if(rotation != 0) { + this.applyRotation(pGL, this.getCenterX(), this.getCenterY(), rotation); + } + } + + public void onApplyPositionIndependentMatrix(final GL10 pGL) { + GLHelper.setProjectionIdentityMatrix(pGL); + + final float width = this.mMaxX - this.mMinX; + final float height = this.mMaxY - this.mMinY; + + pGL.glOrthof(0, width, height, 0, this.mNearZ, this.mFarZ); + + final float rotation = this.mRotation; + if(rotation != 0) { + this.applyRotation(pGL, width * 0.5f, height * 0.5f, rotation); + } + } + + public void onApplyCameraSceneMatrix(final GL10 pGL) { + GLHelper.setProjectionIdentityMatrix(pGL); + + final float width = this.mMaxX - this.mMinX; + final float height = this.mMaxY - this.mMinY; + + pGL.glOrthof(0, width, height, 0, this.mNearZ, this.mFarZ); + + final float cameraSceneRotation = this.mCameraSceneRotation; + if(cameraSceneRotation != 0) { + this.applyRotation(pGL, width * 0.5f, height * 0.5f, cameraSceneRotation); + } + } + + private void applyRotation(final GL10 pGL, final float pRotationCenterX, final float pRotationCenterY, final float pAngle) { + pGL.glTranslatef(pRotationCenterX, pRotationCenterY, 0); + pGL.glRotatef(pAngle, 0, 0, 1); + pGL.glTranslatef(-pRotationCenterX, -pRotationCenterY, 0); + } + + public void convertSceneToCameraSceneTouchEvent(final TouchEvent pSceneTouchEvent) { + this.unapplySceneRotation(pSceneTouchEvent); + + this.applySceneToCameraSceneOffset(pSceneTouchEvent); + + this.applyCameraSceneRotation(pSceneTouchEvent); + } + + public void convertCameraSceneToSceneTouchEvent(final TouchEvent pCameraSceneTouchEvent) { + this.unapplyCameraSceneRotation(pCameraSceneTouchEvent); + + this.unapplySceneToCameraSceneOffset(pCameraSceneTouchEvent); + + this.applySceneRotation(pCameraSceneTouchEvent); + } + + protected void applySceneToCameraSceneOffset(final TouchEvent pSceneTouchEvent) { + pSceneTouchEvent.offset(-this.mMinX, -this.mMinY); + } + + protected void unapplySceneToCameraSceneOffset(final TouchEvent pCameraSceneTouchEvent) { + pCameraSceneTouchEvent.offset(this.mMinX, this.mMinY); + } + + private void applySceneRotation(final TouchEvent pCameraSceneTouchEvent) { + final float rotation = -this.mRotation; + if(rotation != 0) { + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pCameraSceneTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pCameraSceneTouchEvent.getY(); + + MathUtils.rotateAroundCenter(VERTICES_TOUCH_TMP, rotation, this.getCenterX(), this.getCenterY()); + + pCameraSceneTouchEvent.set(VERTICES_TOUCH_TMP[VERTEX_INDEX_X], VERTICES_TOUCH_TMP[VERTEX_INDEX_Y]); + } + } + + private void unapplySceneRotation(final TouchEvent pSceneTouchEvent) { + final float rotation = this.mRotation; + + if(rotation != 0) { + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pSceneTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pSceneTouchEvent.getY(); + + MathUtils.revertRotateAroundCenter(VERTICES_TOUCH_TMP, rotation, this.getCenterX(), this.getCenterY()); + + pSceneTouchEvent.set(VERTICES_TOUCH_TMP[VERTEX_INDEX_X], VERTICES_TOUCH_TMP[VERTEX_INDEX_Y]); + } + } + + private void applyCameraSceneRotation(final TouchEvent pSceneTouchEvent) { + final float cameraSceneRotation = -this.mCameraSceneRotation; + + if(cameraSceneRotation != 0) { + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pSceneTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pSceneTouchEvent.getY(); + + MathUtils.rotateAroundCenter(VERTICES_TOUCH_TMP, cameraSceneRotation, (this.mMaxX - this.mMinX) * 0.5f, (this.mMaxY - this.mMinY) * 0.5f); + + pSceneTouchEvent.set(VERTICES_TOUCH_TMP[VERTEX_INDEX_X], VERTICES_TOUCH_TMP[VERTEX_INDEX_Y]); + } + } + + private void unapplyCameraSceneRotation(final TouchEvent pCameraSceneTouchEvent) { + final float cameraSceneRotation = -this.mCameraSceneRotation; + + if(cameraSceneRotation != 0) { + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pCameraSceneTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pCameraSceneTouchEvent.getY(); + + MathUtils.revertRotateAroundCenter(VERTICES_TOUCH_TMP, cameraSceneRotation, (this.mMaxX - this.mMinX) * 0.5f, (this.mMaxY - this.mMinY) * 0.5f); + + pCameraSceneTouchEvent.set(VERTICES_TOUCH_TMP[VERTEX_INDEX_X], VERTICES_TOUCH_TMP[VERTEX_INDEX_Y]); + } + } + + public void convertSurfaceToSceneTouchEvent(final TouchEvent pSurfaceTouchEvent, final int pSurfaceWidth, final int pSurfaceHeight) { + final float relativeX; + final float relativeY; + + final float rotation = this.mRotation; + if(rotation == 0) { + relativeX = pSurfaceTouchEvent.getX() / pSurfaceWidth; + relativeY = pSurfaceTouchEvent.getY() / pSurfaceHeight; + } else if(rotation == 180) { + relativeX = 1 - (pSurfaceTouchEvent.getX() / pSurfaceWidth); + relativeY = 1 - (pSurfaceTouchEvent.getY() / pSurfaceHeight); + } else { + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pSurfaceTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pSurfaceTouchEvent.getY(); + + MathUtils.rotateAroundCenter(VERTICES_TOUCH_TMP, rotation, pSurfaceWidth / 2, pSurfaceHeight / 2); + + relativeX = VERTICES_TOUCH_TMP[VERTEX_INDEX_X] / pSurfaceWidth; + relativeY = VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] / pSurfaceHeight; + } + + this.convertAxisAlignedSurfaceToSceneTouchEvent(pSurfaceTouchEvent, relativeX, relativeY); + } + + private void convertAxisAlignedSurfaceToSceneTouchEvent(final TouchEvent pSurfaceTouchEvent, final float pRelativeX, final float pRelativeY) { + final float minX = this.getMinX(); + final float maxX = this.getMaxX(); + final float minY = this.getMinY(); + final float maxY = this.getMaxY(); + + final float x = minX + pRelativeX * (maxX - minX); + final float y = minY + pRelativeY * (maxY - minY); + + pSurfaceTouchEvent.set(x, y); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/CameraFactory.java b/AndEngine/src/org/anddev/andengine/engine/camera/CameraFactory.java new file mode 100644 index 0000000..5989e8c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/CameraFactory.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.engine.camera; + +import android.app.Activity; +import android.util.DisplayMetrics; + +/** + * @author Nicolas Gramlich + * @since 13:50:42 - 03.07.2010 + */ +public class CameraFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static Camera createPixelPerfectCamera(final Activity pActivity, final float pCenterX, final float pCenterY) { + final DisplayMetrics displayMetrics = CameraFactory.getDisplayMetrics(pActivity); + + final float width = displayMetrics.widthPixels; + final float height = displayMetrics.heightPixels; + return new Camera(pCenterX - width * 0.5f, pCenterY - height * 0.5f, width, height); + } + + private static DisplayMetrics getDisplayMetrics(final Activity pActivity) { + final DisplayMetrics displayMetrics = new DisplayMetrics(); + pActivity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + return displayMetrics; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/SmoothCamera.java b/AndEngine/src/org/anddev/andengine/engine/camera/SmoothCamera.java new file mode 100644 index 0000000..f264c59 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/SmoothCamera.java @@ -0,0 +1,147 @@ +package org.anddev.andengine.engine.camera; + + +/** + * @author Nicolas Gramlich + * @since 22:11:17 - 25.03.2010 + */ +public class SmoothCamera extends ZoomCamera { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mMaxVelocityX; + private float mMaxVelocityY; + private float mMaxZoomFactorChange; + + private float mTargetCenterX; + private float mTargetCenterY; + + private float mTargetZoomFactor; + + // =========================================================== + // Constructors + // =========================================================== + + public SmoothCamera(final float pX, final float pY, final float pWidth, final float pHeight, final float pMaxVelocityX, final float pMaxVelocityY, final float pMaxZoomFactorChange) { + super(pX, pY, pWidth, pHeight); + this.mMaxVelocityX = pMaxVelocityX; + this.mMaxVelocityY = pMaxVelocityY; + this.mMaxZoomFactorChange = pMaxZoomFactorChange; + + this.mTargetCenterX = this.getCenterX(); + this.mTargetCenterY = this.getCenterY(); + + this.mTargetZoomFactor = 1.0f; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public void setCenter(final float pCenterX, final float pCenterY) { + this.mTargetCenterX = pCenterX; + this.mTargetCenterY = pCenterY; + } + + public void setCenterDirect(final float pCenterX, final float pCenterY) { + super.setCenter(pCenterX, pCenterY); + this.mTargetCenterX = pCenterX; + this.mTargetCenterY = pCenterY; + } + + @Override + public void setZoomFactor(final float pZoomFactor) { + this.mTargetZoomFactor = pZoomFactor; + } + + public void setMaxVelocityX(final float pMaxVelocityX) { + this.mMaxVelocityX = pMaxVelocityX; + } + + public void setMaxVelocityY(final float pMaxVelocityY) { + this.mMaxVelocityY = pMaxVelocityY; + } + + public void setMaxVelocityX(final float pMaxVelocityX, final float pMaxVelocityY) { + this.mMaxVelocityX = pMaxVelocityX; + this.mMaxVelocityY = pMaxVelocityY; + } + + public void setMaxZoomFactorChange(final float pMaxZoomFactorChange) { + this.mMaxZoomFactorChange = pMaxZoomFactorChange; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + super.onUpdate(pSecondsElapsed); + /* Update center. */ + final float currentCenterX = this.getCenterX(); + final float currentCenterY = this.getCenterY(); + + final float targetCenterX = this.mTargetCenterX; + final float targetCenterY = this.mTargetCenterY; + + if(currentCenterX != targetCenterX || currentCenterY != targetCenterY) { + final float diffX = targetCenterX - currentCenterX; + final float dX = this.cutToMaxVelocityX(diffX, pSecondsElapsed); + + final float diffY = targetCenterY - currentCenterY; + final float dY = this.cutToMaxVelocityY(diffY, pSecondsElapsed); + + super.setCenter(currentCenterX + dX, currentCenterY + dY); + } + + /* Update zoom. */ + final float currentZoom = this.getZoomFactor(); + + final float targetZoomFactor = this.mTargetZoomFactor; + + if(currentZoom != targetZoomFactor) { + final float diffZoom = targetZoomFactor - currentZoom; + final float dZoom = this.cutToMaxZoomFactorChange(diffZoom, pSecondsElapsed); + super.setZoomFactor(currentZoom + dZoom); + } + } + + private float cutToMaxVelocityX(final float pValue, final float pSecondsElapsed) { + if(pValue > 0) { + return Math.min(pValue, this.mMaxVelocityX * pSecondsElapsed); + } else { + return Math.max(pValue, -this.mMaxVelocityX * pSecondsElapsed); + } + } + + private float cutToMaxVelocityY(final float pValue, final float pSecondsElapsed) { + if(pValue > 0) { + return Math.min(pValue, this.mMaxVelocityY * pSecondsElapsed); + } else { + return Math.max(pValue, -this.mMaxVelocityY * pSecondsElapsed); + } + } + + private float cutToMaxZoomFactorChange(final float pValue, final float pSecondsElapsed) { + if(pValue > 0) { + return Math.min(pValue, this.mMaxZoomFactorChange * pSecondsElapsed); + } else { + return Math.max(pValue, -this.mMaxZoomFactorChange * pSecondsElapsed); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/ZoomCamera.java b/AndEngine/src/org/anddev/andengine/engine/camera/ZoomCamera.java new file mode 100644 index 0000000..98a59a4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/ZoomCamera.java @@ -0,0 +1,147 @@ +package org.anddev.andengine.engine.camera; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.util.MathUtils; + + + +/** + * @author Nicolas Gramlich + * @since 15:48:11 - 24.06.2010 + * TODO min/max(X/Y) values could be cached and only updated once the zoomfactor/center changed. + */ +public class ZoomCamera extends BoundCamera { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mZoomFactor = 1.0f; + + // =========================================================== + // Constructors + // =========================================================== + + public ZoomCamera(final float pX, final float pY, final float pWidth, final float pHeight) { + super(pX, pY, pWidth, pHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getZoomFactor() { + return this.mZoomFactor; + } + + public void setZoomFactor(final float pZoomFactor) { + this.mZoomFactor = pZoomFactor; + + if(this.mBoundsEnabled) { + this.ensureInBounds(); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getMinX() { + if(this.mZoomFactor == 1.0f) { + return super.getMinX(); + } else { + final float centerX = this.getCenterX(); + return centerX - (centerX - super.getMinX()) / this.mZoomFactor; + } + } + + @Override + public float getMaxX() { + if(this.mZoomFactor == 1.0f) { + return super.getMaxX(); + } else { + final float centerX = this.getCenterX(); + return centerX + (super.getMaxX() - centerX) / this.mZoomFactor; + } + } + + @Override + public float getMinY() { + if(this.mZoomFactor == 1.0f) { + return super.getMinY(); + } else { + final float centerY = this.getCenterY(); + return centerY - (centerY - super.getMinY()) / this.mZoomFactor; + } + } + + @Override + public float getMaxY() { + if(this.mZoomFactor == 1.0f) { + return super.getMaxY(); + } else { + final float centerY = this.getCenterY(); + return centerY + (super.getMaxY() - centerY) / this.mZoomFactor; + } + } + + @Override + public float getWidth() { + return super.getWidth() / this.mZoomFactor; + } + + @Override + public float getHeight() { + return super.getHeight() / this.mZoomFactor; + } + + @Override + protected void applySceneToCameraSceneOffset(final TouchEvent pSceneTouchEvent) { + final float zoomFactor = this.mZoomFactor; + if(zoomFactor != 1) { + final float scaleCenterX = this.getCenterX(); + final float scaleCenterY = this.getCenterY(); + + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pSceneTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pSceneTouchEvent.getY(); + + MathUtils.scaleAroundCenter(VERTICES_TOUCH_TMP, zoomFactor, zoomFactor, scaleCenterX, scaleCenterY); + + pSceneTouchEvent.set(VERTICES_TOUCH_TMP[VERTEX_INDEX_X], VERTICES_TOUCH_TMP[VERTEX_INDEX_Y]); + } + super.applySceneToCameraSceneOffset(pSceneTouchEvent); + } + + @Override + protected void unapplySceneToCameraSceneOffset(final TouchEvent pCameraSceneTouchEvent) { + super.unapplySceneToCameraSceneOffset(pCameraSceneTouchEvent); + + final float zoomFactor = this.mZoomFactor; + if(zoomFactor != 1) { + final float scaleCenterX = this.getCenterX(); + final float scaleCenterY = this.getCenterY(); + + VERTICES_TOUCH_TMP[VERTEX_INDEX_X] = pCameraSceneTouchEvent.getX(); + VERTICES_TOUCH_TMP[VERTEX_INDEX_Y] = pCameraSceneTouchEvent.getY(); + + MathUtils.revertScaleAroundCenter(VERTICES_TOUCH_TMP, zoomFactor, zoomFactor, scaleCenterX, scaleCenterY); + + pCameraSceneTouchEvent.set(VERTICES_TOUCH_TMP[VERTEX_INDEX_X], VERTICES_TOUCH_TMP[VERTEX_INDEX_Y]); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/hud/HUD.java b/AndEngine/src/org/anddev/andengine/engine/camera/hud/HUD.java new file mode 100644 index 0000000..e230779 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/hud/HUD.java @@ -0,0 +1,54 @@ +package org.anddev.andengine.engine.camera.hud; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.scene.CameraScene; +import org.anddev.andengine.entity.scene.Scene; + +/** + * While you can add a {@link HUD} to {@link Scene}, you should not do so. + * {@link HUD}s are meant to be added to {@link Camera}s via {@link Camera#setHUD(HUD)}. + * + * @author Nicolas Gramlich + * @since 14:13:13 - 01.04.2010 + */ +public class HUD extends CameraScene { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public HUD() { + this(1); + + this.setBackgroundEnabled(false); + } + + public HUD(final int pLayerCount) { + super(pLayerCount); + + this.setBackgroundEnabled(false); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/AnalogOnScreenControl.java b/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/AnalogOnScreenControl.java new file mode 100644 index 0000000..e972d21 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/AnalogOnScreenControl.java @@ -0,0 +1,103 @@ +package org.anddev.andengine.engine.camera.hud.controls; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.input.touch.detector.ClickDetector; +import org.anddev.andengine.input.touch.detector.ClickDetector.IClickDetectorListener; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.constants.TimeConstants; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 00:21:55 - 11.07.2010 + */ +public class AnalogOnScreenControl extends BaseOnScreenControl implements TimeConstants, IClickDetectorListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ClickDetector mClickDetector = new ClickDetector(this); + + // =========================================================== + // Constructors + // =========================================================== + + public AnalogOnScreenControl(final float pX, final float pY, final Camera pCamera, final TextureRegion pControlBaseTextureRegion, final TextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final IAnalogOnScreenControlListener pAnalogOnScreenControlListener) { + super(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, pAnalogOnScreenControlListener); + this.mClickDetector.setEnabled(false); + } + + public AnalogOnScreenControl(final float pX, final float pY, final Camera pCamera, final TextureRegion pControlBaseTextureRegion, final TextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final long pOnControlClickMaximumMilliseconds, final IAnalogOnScreenControlListener pAnalogOnScreenControlListener) { + super(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, pAnalogOnScreenControlListener); + this.mClickDetector.setTriggerClickMaximumMilliseconds(pOnControlClickMaximumMilliseconds); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public IAnalogOnScreenControlListener getOnScreenControlListener() { + return (IAnalogOnScreenControlListener)super.getOnScreenControlListener(); + } + + public void setOnControlClickEnabled(final boolean pOnControlClickEnabled) { + this.mClickDetector.setEnabled(pOnControlClickEnabled); + } + + public void setOnControlClickMaximumMilliseconds(final long pOnControlClickMaximumMilliseconds) { + this.mClickDetector.setTriggerClickMaximumMilliseconds(pOnControlClickMaximumMilliseconds); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onClick(final ClickDetector pClickDetector, final TouchEvent pTouchEvent) { + this.getOnScreenControlListener().onControlClick(this); + } + + @Override + protected boolean onHandleControlBaseTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + this.mClickDetector.onSceneTouchEvent(null, pSceneTouchEvent); + return super.onHandleControlBaseTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY); + } + + @Override + protected void onUpdateControlKnob(final float pRelativeX, final float pRelativeY) { + if(pRelativeX * pRelativeX + pRelativeY * pRelativeY <= 0.25f) { + super.onUpdateControlKnob(pRelativeX, pRelativeY); + } else { + final float angleRad = MathUtils.atan2(pRelativeY, pRelativeX); + super.onUpdateControlKnob(FloatMath.cos(angleRad) * 0.5f, FloatMath.sin(angleRad) * 0.5f); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface IAnalogOnScreenControlListener extends IOnScreenControlListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl); + } +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/BaseOnScreenControl.java b/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/BaseOnScreenControl.java new file mode 100644 index 0000000..1c264a4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/BaseOnScreenControl.java @@ -0,0 +1,215 @@ +package org.anddev.andengine.engine.camera.hud.controls; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.camera.hud.HUD; +import org.anddev.andengine.engine.handler.timer.ITimerCallback; +import org.anddev.andengine.engine.handler.timer.TimerHandler; +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener; +import org.anddev.andengine.entity.sprite.Sprite; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.util.MathUtils; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 10:43:09 - 11.07.2010 + */ +public abstract class BaseOnScreenControl extends HUD implements IOnSceneTouchListener { + // =========================================================== + // Constants + // =========================================================== + + private static final int INVALID_POINTER_ID = -1; + + // =========================================================== + // Fields + // =========================================================== + + private final Sprite mControlBase; + private final Sprite mControlKnob; + + private float mControlValueX; + private float mControlValueY; + + private final IOnScreenControlListener mOnScreenControlListener; + + private int mActivePointerID = INVALID_POINTER_ID; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseOnScreenControl(final float pX, final float pY, final Camera pCamera, final TextureRegion pControlBaseTextureRegion, final TextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final IOnScreenControlListener pOnScreenControlListener) { + this.setCamera(pCamera); + + this.mOnScreenControlListener = pOnScreenControlListener; + /* Create the control base. */ + this.mControlBase = new Sprite(pX, pY, pControlBaseTextureRegion) { + @Override + public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + return BaseOnScreenControl.this.onHandleControlBaseTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY); + } + }; + + /* Create the control knob. */ + this.mControlKnob = new Sprite(0, 0, pControlKnobTextureRegion); + this.onHandleControlKnobReleased(); + + /* Register listeners and add objects to this HUD. */ + this.setOnSceneTouchListener(this); + this.registerTouchArea(this.mControlBase); + this.registerUpdateHandler(new TimerHandler(pTimeBetweenUpdates, true, new ITimerCallback() { + @Override + public void onTimePassed(final TimerHandler pTimerHandler) { + BaseOnScreenControl.this.mOnScreenControlListener.onControlChange(BaseOnScreenControl.this, BaseOnScreenControl.this.mControlValueX, BaseOnScreenControl.this.mControlValueY); + } + })); + + final IEntity firstChild = this.getFirstChild(); + firstChild.attachChild(this.mControlBase); + firstChild.attachChild(this.mControlKnob); + + this.setTouchAreaBindingEnabled(true); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Sprite getControlBase() { + return this.mControlBase; + } + + public Sprite getControlKnob() { + return this.mControlKnob; + } + + public IOnScreenControlListener getOnScreenControlListener() { + return this.mOnScreenControlListener; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) { + final int pointerID = pSceneTouchEvent.getPointerID(); + if(pointerID == this.mActivePointerID) { + this.onHandleControlBaseLeft(); + + switch(pSceneTouchEvent.getAction()) { + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + this.mActivePointerID = INVALID_POINTER_ID; + } + } + return false; + } + + // =========================================================== + // Methods + // =========================================================== + + public void refreshControlKnobPosition() { + this.onUpdateControlKnob(this.mControlValueX * 0.5f, this.mControlValueY * 0.5f); + } + + /** + * When the touch happened outside of the bounds of this OnScreenControl. + * */ + protected void onHandleControlBaseLeft() { + this.onUpdateControlKnob(0, 0); + } + + /** + * When the OnScreenControl was released. + */ + protected void onHandleControlKnobReleased() { + this.onUpdateControlKnob(0, 0); + } + + protected boolean onHandleControlBaseTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + final int pointerID = pSceneTouchEvent.getPointerID(); + + switch(pSceneTouchEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + if(this.mActivePointerID == INVALID_POINTER_ID) { + this.mActivePointerID = pointerID; + this.updateControlKnob(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY); + return true; + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + if(this.mActivePointerID == pointerID) { + this.mActivePointerID = INVALID_POINTER_ID; + this.onHandleControlKnobReleased(); + return true; + } + break; + default: + if(this.mActivePointerID == pointerID) { + this.updateControlKnob(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY); + return true; + } + break; + } + return true; + } + + private void updateControlKnob(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + final Sprite controlBase = this.mControlBase; + + final float relativeX = MathUtils.bringToBounds(0, controlBase.getWidth(), pTouchAreaLocalX) / controlBase.getWidth() - 0.5f; + final float relativeY = MathUtils.bringToBounds(0, controlBase.getHeight(), pTouchAreaLocalY) / controlBase.getHeight() - 0.5f; + + this.onUpdateControlKnob(relativeX, relativeY); + } + + /** + * @param pRelativeX from -0.5 (left) to 0.5 (right). + * @param pRelativeY from -0.5 (top) to 0.5 (bottom). + */ + protected void onUpdateControlKnob(final float pRelativeX, final float pRelativeY) { + final Sprite controlBase = this.mControlBase; + final Sprite controlKnob = this.mControlKnob; + + this.mControlValueX = 2 * pRelativeX; + this.mControlValueY = 2 * pRelativeY; + + final float[] controlBaseSceneCenterCoordinates = controlBase.getSceneCenterCoordinates(); + final float x = controlBaseSceneCenterCoordinates[VERTEX_INDEX_X] - controlKnob.getWidth() * 0.5f + pRelativeX * controlBase.getWidthScaled(); + final float y = controlBaseSceneCenterCoordinates[VERTEX_INDEX_Y] - controlKnob.getHeight() * 0.5f + pRelativeY * controlBase.getHeightScaled(); + + controlKnob.setPosition(x, y); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IOnScreenControlListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * @param pBaseOnScreenControl + * @param pValueX between -1 (left) to 1 (right). + * @param pValueY between -1 (up) to 1 (down). + */ + public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY); + } +} diff --git a/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/DigitalOnScreenControl.java b/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/DigitalOnScreenControl.java new file mode 100644 index 0000000..103297c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/camera/hud/controls/DigitalOnScreenControl.java @@ -0,0 +1,67 @@ +package org.anddev.andengine.engine.camera.hud.controls; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.opengl.texture.region.TextureRegion; + +/** + * @author Nicolas Gramlich + * @since 00:21:55 - 11.07.2010 + */ +public class DigitalOnScreenControl extends BaseOnScreenControl { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public DigitalOnScreenControl(final float pX, final float pY, final Camera pCamera, final TextureRegion pControlBaseTextureRegion, final TextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final IOnScreenControlListener pOnScreenControlListener) { + super(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, pOnScreenControlListener); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onUpdateControlKnob(final float pRelativeX, final float pRelativeY) { + if(pRelativeX == 0 && pRelativeY == 0) { + super.onUpdateControlKnob(0, 0); + } + + if(Math.abs(pRelativeX) > Math.abs(pRelativeY)) { + if(pRelativeX > 0) { + super.onUpdateControlKnob(0.5f, 0); + } else if(pRelativeX < 0) { + super.onUpdateControlKnob(-0.5f, 0); + } else if(pRelativeX == 0) { + super.onUpdateControlKnob(0, 0); + } + } else { + if(pRelativeY > 0) { + super.onUpdateControlKnob(0, 0.5f); + } else if(pRelativeY < 0) { + super.onUpdateControlKnob(0, -0.5f); + } else if(pRelativeY == 0) { + super.onUpdateControlKnob(0, 0); + } + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/BaseEntityUpdateHandler.java b/AndEngine/src/org/anddev/andengine/engine/handler/BaseEntityUpdateHandler.java new file mode 100644 index 0000000..40c3d05 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/BaseEntityUpdateHandler.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.engine.handler; + +import org.anddev.andengine.entity.IEntity; + +/** + * @author Nicolas Gramlich + * @since 14:00:25 - 24.12.2010 + */ +public abstract class BaseEntityUpdateHandler implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final IEntity mEntity; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseEntityUpdateHandler(final IEntity pEntity) { + this.mEntity = pEntity; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onUpdate(final float pSecondsElapsed, final IEntity pEntity); + + @Override + public final void onUpdate(final float pSecondsElapsed) { + this.onUpdate(pSecondsElapsed, this.mEntity); + } + + @Override + public void reset() { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/IUpdateHandler.java b/AndEngine/src/org/anddev/andengine/engine/handler/IUpdateHandler.java new file mode 100644 index 0000000..add606a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/IUpdateHandler.java @@ -0,0 +1,36 @@ +package org.anddev.andengine.engine.handler; + +import org.anddev.andengine.util.IMatcher; + +/** + * @author Nicolas Gramlich + * @since 12:24:09 - 11.03.2010 + */ +public interface IUpdateHandler { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onUpdate(final float pSecondsElapsed); + public void reset(); + + // TODO Maybe add onRegister and onUnregister. (Maybe add SimpleUpdateHandler that implements all methods, but onUpdate) + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface IUpdateHandlerMatcher extends IMatcher { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/UpdateHandlerList.java b/AndEngine/src/org/anddev/andengine/engine/handler/UpdateHandlerList.java new file mode 100644 index 0000000..4323b1d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/UpdateHandlerList.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.engine.handler; + +import org.anddev.andengine.util.SmartList; + +/** + * @author Nicolas Gramlich + * @since 09:45:22 - 31.03.2010 + */ +public class UpdateHandlerList extends SmartList implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = -8842562717687229277L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public UpdateHandlerList() { + + } + + public UpdateHandlerList(final int pCapacity) { + super(pCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + final int handlerCount = this.size(); + for(int i = handlerCount - 1; i >= 0; i--) { + this.get(i).onUpdate(pSecondsElapsed); + } + } + + @Override + public void reset() { + final int handlerCount = this.size(); + for(int i = handlerCount - 1; i >= 0; i--) { + this.get(i).reset(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/collision/CollisionHandler.java b/AndEngine/src/org/anddev/andengine/engine/handler/collision/CollisionHandler.java new file mode 100644 index 0000000..6eb05ae --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/collision/CollisionHandler.java @@ -0,0 +1,86 @@ +package org.anddev.andengine.engine.handler.collision; + +import java.util.ArrayList; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.entity.shape.IShape; +import org.anddev.andengine.util.ListUtils; + +/** + * @author Nicolas Gramlich + * @since 12:19:35 - 11.03.2010 + */ +public class CollisionHandler implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ICollisionCallback mCollisionCallback; + private final IShape mCheckShape; + private final ArrayList mTargetStaticEntities; + + // =========================================================== + // Constructors + // =========================================================== + + public CollisionHandler(final ICollisionCallback pCollisionCallback, final IShape pCheckShape, final IShape pTargetShape) throws IllegalArgumentException { + this(pCollisionCallback, pCheckShape, ListUtils.toList(pTargetShape)); + } + + public CollisionHandler(final ICollisionCallback pCollisionCallback, final IShape pCheckShape, final ArrayList pTargetStaticEntities) throws IllegalArgumentException { + if (pCollisionCallback == null) { + throw new IllegalArgumentException( "pCollisionCallback must not be null!"); + } + if (pCheckShape == null) { + throw new IllegalArgumentException( "pCheckShape must not be null!"); + } + if (pTargetStaticEntities == null) { + throw new IllegalArgumentException( "pTargetStaticEntities must not be null!"); + } + + this.mCollisionCallback = pCollisionCallback; + this.mCheckShape = pCheckShape; + this.mTargetStaticEntities = pTargetStaticEntities; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + final IShape checkShape = this.mCheckShape; + final ArrayList staticEntities = this.mTargetStaticEntities; + final int staticEntityCount = staticEntities.size(); + + for(int i = 0; i < staticEntityCount; i++){ + if(checkShape.collidesWith(staticEntities.get(i))){ + final boolean proceed = this.mCollisionCallback.onCollision(checkShape, staticEntities.get(i)); + if(!proceed) { + return; + } + } + } + } + + @Override + public void reset() { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/collision/ICollisionCallback.java b/AndEngine/src/org/anddev/andengine/engine/handler/collision/ICollisionCallback.java new file mode 100644 index 0000000..86d999e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/collision/ICollisionCallback.java @@ -0,0 +1,24 @@ +package org.anddev.andengine.engine.handler.collision; + +import org.anddev.andengine.entity.shape.IShape; + +/** + * @author Nicolas Gramlich + * @since 12:05:39 - 11.03.2010 + */ +public interface ICollisionCallback { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * @param pCheckShape + * @param pTargetShape + * @return true to proceed, false to stop further collosion-checks. + */ + public boolean onCollision(final IShape pCheckShape, final IShape pTargetShape); +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/physics/PhysicsHandler.java b/AndEngine/src/org/anddev/andengine/engine/handler/physics/PhysicsHandler.java new file mode 100644 index 0000000..7abbd3e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/physics/PhysicsHandler.java @@ -0,0 +1,160 @@ +package org.anddev.andengine.engine.handler.physics; + +import org.anddev.andengine.engine.handler.BaseEntityUpdateHandler; +import org.anddev.andengine.entity.IEntity; + +/** + * @author Nicolas Gramlich + * @since 13:53:07 - 24.12.2010 + */ +public class PhysicsHandler extends BaseEntityUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private boolean mEnabled = true; + + protected float mAccelerationX = 0; + protected float mAccelerationY = 0; + + protected float mVelocityX = 0; + protected float mVelocityY = 0; + + protected float mAngularVelocity = 0; + + // =========================================================== + // Constructors + // =========================================================== + + public PhysicsHandler(final IEntity pEntity) { + super(pEntity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isEnabled() { + return this.mEnabled; + } + + public void setEnabled(final boolean pEnabled) { + this.mEnabled = pEnabled; + } + + public float getVelocityX() { + return this.mVelocityX; + } + + public float getVelocityY() { + return this.mVelocityY; + } + + public void setVelocityX(final float pVelocityX) { + this.mVelocityX = pVelocityX; + } + + public void setVelocityY(final float pVelocityY) { + this.mVelocityY = pVelocityY; + } + + public void setVelocity(final float pVelocity) { + this.mVelocityX = pVelocity; + this.mVelocityY = pVelocity; + } + + public void setVelocity(final float pVelocityX, final float pVelocityY) { + this.mVelocityX = pVelocityX; + this.mVelocityY = pVelocityY; + } + + public float getAccelerationX() { + return this.mAccelerationX; + } + + public float getAccelerationY() { + return this.mAccelerationY; + } + + public void setAccelerationX(final float pAccelerationX) { + this.mAccelerationX = pAccelerationX; + } + + public void setAccelerationY(final float pAccelerationY) { + this.mAccelerationY = pAccelerationY; + } + + public void setAcceleration(final float pAccelerationX, final float pAccelerationY) { + this.mAccelerationX = pAccelerationX; + this.mAccelerationY = pAccelerationY; + } + + public void setAcceleration(final float pAcceleration) { + this.mAccelerationX = pAcceleration; + this.mAccelerationY = pAcceleration; + } + + public void accelerate(final float pAccelerationX, final float pAccelerationY) { + this.mAccelerationX += pAccelerationX; + this.mAccelerationY += pAccelerationY; + } + + public float getAngularVelocity() { + return this.mAngularVelocity; + } + + public void setAngularVelocity(final float pAngularVelocity) { + this.mAngularVelocity = pAngularVelocity; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onUpdate(final float pSecondsElapsed, final IEntity pEntity) { + if(this.mEnabled) { + /* Apply linear acceleration. */ + final float accelerationX = this.mAccelerationX; + final float accelerationY = this.mAccelerationY; + if(accelerationX != 0 || accelerationY != 0) { + this.mVelocityX += accelerationX * pSecondsElapsed; + this.mVelocityY += accelerationY * pSecondsElapsed; + } + + /* Apply angular velocity. */ + final float angularVelocity = this.mAngularVelocity; + if(angularVelocity != 0) { + pEntity.setRotation(pEntity.getRotation() + angularVelocity * pSecondsElapsed); + } + + /* Apply linear velocity. */ + final float velocityX = this.mVelocityX; + final float velocityY = this.mVelocityY; + if(velocityX != 0 || velocityY != 0) { + pEntity.setPosition(pEntity.getX() + velocityX * pSecondsElapsed, pEntity.getY() + velocityY * pSecondsElapsed); + } + } + } + + @Override + public void reset() { + this.mAccelerationX = 0; + this.mAccelerationY = 0; + this.mVelocityX = 0; + this.mVelocityY = 0; + this.mAngularVelocity = 0; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/runnable/RunnableHandler.java b/AndEngine/src/org/anddev/andengine/engine/handler/runnable/RunnableHandler.java new file mode 100644 index 0000000..f13b0c0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/runnable/RunnableHandler.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.engine.handler.runnable; + +import java.util.ArrayList; + +import org.anddev.andengine.engine.handler.IUpdateHandler; + +/** + * @author Nicolas Gramlich + * @since 10:24:39 - 18.06.2010 + */ +public class RunnableHandler implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mRunnables = new ArrayList(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public synchronized void onUpdate(final float pSecondsElapsed) { + final ArrayList runnables = this.mRunnables; + final int runnableCount = runnables.size(); + for(int i = runnableCount - 1; i >= 0; i--) { + runnables.get(i).run(); + } + runnables.clear(); + } + + @Override + public void reset() { + this.mRunnables.clear(); + } + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void postRunnable(final Runnable pRunnable) { + this.mRunnables.add(pRunnable); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/timer/ITimerCallback.java b/AndEngine/src/org/anddev/andengine/engine/handler/timer/ITimerCallback.java new file mode 100644 index 0000000..b190e1c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/timer/ITimerCallback.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.engine.handler.timer; + +/** + * @author Nicolas Gramlich + * @since 16:23:25 - 12.03.2010 + */ +public interface ITimerCallback { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onTimePassed(final TimerHandler pTimerHandler); +} diff --git a/AndEngine/src/org/anddev/andengine/engine/handler/timer/TimerHandler.java b/AndEngine/src/org/anddev/andengine/engine/handler/timer/TimerHandler.java new file mode 100644 index 0000000..4ce3709 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/handler/timer/TimerHandler.java @@ -0,0 +1,102 @@ +package org.anddev.andengine.engine.handler.timer; + +import org.anddev.andengine.engine.handler.IUpdateHandler; + +/** + * @author Nicolas Gramlich + * @since 16:23:58 - 12.03.2010 + */ +public class TimerHandler implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mTimerSeconds; + private float mTimerSecondsElapsed; + private boolean mCallbackTriggered = false; + protected final ITimerCallback mTimerCallback; + private boolean mAutoReset; + + // =========================================================== + // Constructors + // =========================================================== + + public TimerHandler(final float pTimerSeconds, final ITimerCallback pTimerCallback) { + this(pTimerSeconds, false, pTimerCallback); + } + + public TimerHandler(final float pTimerSeconds, final boolean pAutoReset, final ITimerCallback pTimerCallback) { + this.mTimerSeconds = pTimerSeconds; + this.mAutoReset = pAutoReset; + this.mTimerCallback = pTimerCallback; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isAutoReset() { + return this.mAutoReset; + } + + public void setAutoReset(final boolean pAutoReset) { + this.mAutoReset = pAutoReset; + } + + /** + * You probably want to use this in conjunction with {@link TimerHandler#reset()}. + * @param pTimerSeconds + */ + public void setTimerSeconds(final float pTimerSeconds) { + this.mTimerSeconds = pTimerSeconds; + } + + public float getTimerSeconds() { + return this.mTimerSeconds; + } + + public float getTimerSecondsElapsed() { + return this.mTimerSecondsElapsed; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + if(this.mAutoReset) { + this.mTimerSecondsElapsed += pSecondsElapsed; + while(this.mTimerSecondsElapsed >= this.mTimerSeconds) { + this.mTimerSecondsElapsed -= this.mTimerSeconds; + this.mTimerCallback.onTimePassed(this); + } + } else { + if(!this.mCallbackTriggered) { + this.mTimerSecondsElapsed += pSecondsElapsed; + if(this.mTimerSecondsElapsed >= this.mTimerSeconds) { + this.mCallbackTriggered = true; + this.mTimerCallback.onTimePassed(this); + } + } + } + } + + @Override + public void reset() { + this.mCallbackTriggered = false; + this.mTimerSecondsElapsed = 0; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/EngineOptions.java b/AndEngine/src/org/anddev/andengine/engine/options/EngineOptions.java new file mode 100644 index 0000000..74e3900 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/EngineOptions.java @@ -0,0 +1,129 @@ +package org.anddev.andengine.engine.options; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.options.resolutionpolicy.IResolutionPolicy; + +/** + * @author Nicolas Gramlich + * @since 15:59:52 - 09.03.2010 + */ +public class EngineOptions { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final boolean mFullscreen; + private final ScreenOrientation mScreenOrientation; + private final IResolutionPolicy mResolutionPolicy; + private final Camera mCamera; + + private final TouchOptions mTouchOptions = new TouchOptions(); + private final RenderOptions mRenderOptions = new RenderOptions(); + + private boolean mNeedsSound; + private boolean mNeedsMusic; + private WakeLockOptions mWakeLockOptions = WakeLockOptions.SCREEN_BRIGHT; + private int mUpdateThreadPriority = android.os.Process.THREAD_PRIORITY_DEFAULT;; + + // =========================================================== + // Constructors + // =========================================================== + + public EngineOptions(final boolean pFullscreen, final ScreenOrientation pScreenOrientation, final IResolutionPolicy pResolutionPolicy, final Camera pCamera) { + this.mFullscreen = pFullscreen; + this.mScreenOrientation = pScreenOrientation; + this.mResolutionPolicy = pResolutionPolicy; + this.mCamera = pCamera; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public TouchOptions getTouchOptions() { + return this.mTouchOptions; + } + + public RenderOptions getRenderOptions() { + return this.mRenderOptions; + } + + public boolean isFullscreen() { + return this.mFullscreen; + } + + public ScreenOrientation getScreenOrientation() { + return this.mScreenOrientation; + } + + public IResolutionPolicy getResolutionPolicy() { + return this.mResolutionPolicy; + } + + public Camera getCamera() { + return this.mCamera; + } + + public int getUpdateThreadPriority() { + return this.mUpdateThreadPriority; + } + + /** + * @param pUpdateThreadPriority Use constants from: {@link android.os.Process}. + */ + public void setUpdateThreadPriority(final int pUpdateThreadPriority) { + this.mUpdateThreadPriority = pUpdateThreadPriority; + } + + public boolean needsSound() { + return this.mNeedsSound; + } + + public EngineOptions setNeedsSound(final boolean pNeedsSound) { + this.mNeedsSound = pNeedsSound; + return this; + } + + public boolean needsMusic() { + return this.mNeedsMusic; + } + + public EngineOptions setNeedsMusic(final boolean pNeedsMusic) { + this.mNeedsMusic = pNeedsMusic; + return this; + } + + public WakeLockOptions getWakeLockOptions() { + return this.mWakeLockOptions; + } + + public EngineOptions setWakeLockOptions(final WakeLockOptions pWakeLockOptions) { + this.mWakeLockOptions = pWakeLockOptions; + return this; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static enum ScreenOrientation { + // =========================================================== + // Elements + // =========================================================== + + LANDSCAPE, + PORTRAIT; + } +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/engine/options/RenderOptions.java b/AndEngine/src/org/anddev/andengine/engine/options/RenderOptions.java new file mode 100644 index 0000000..0a46833 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/RenderOptions.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.engine.options; + +/** + * @author Nicolas Gramlich + * @since 13:01:40 - 02.07.2010 + */ +public class RenderOptions { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private boolean mDisableExtensionVertexBufferObjects = false; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public RenderOptions enableExtensionVertexBufferObjects() { + return this.setDisableExtensionVertexBufferObjects(false); + } + + public RenderOptions disableExtensionVertexBufferObjects() { + return this.setDisableExtensionVertexBufferObjects(true); + } + + public RenderOptions setDisableExtensionVertexBufferObjects(final boolean pDisableExtensionVertexBufferObjects) { + this.mDisableExtensionVertexBufferObjects = pDisableExtensionVertexBufferObjects; + return this; + } + + /** + * Default: false + */ + public boolean isDisableExtensionVertexBufferObjects() { + return this.mDisableExtensionVertexBufferObjects; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/TouchOptions.java b/AndEngine/src/org/anddev/andengine/engine/options/TouchOptions.java new file mode 100644 index 0000000..76f9be1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/TouchOptions.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.engine.options; + +/** + * @author Nicolas Gramlich + * @since 16:03:09 - 08.09.2010 + */ +public class TouchOptions { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private boolean mRunOnUpdateThread; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public TouchOptions enableRunOnUpdateThread() { + return this.setRunOnUpdateThread(true); + } + + public TouchOptions disableRunOnUpdateThread() { + return this.setRunOnUpdateThread(false); + } + + public TouchOptions setRunOnUpdateThread(final boolean pRunOnUpdateThread) { + this.mRunOnUpdateThread = pRunOnUpdateThread; + return this; + } + + /** + * Default: true + */ + public boolean isRunOnUpdateThread() { + return this.mRunOnUpdateThread; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/WakeLockOptions.java b/AndEngine/src/org/anddev/andengine/engine/options/WakeLockOptions.java new file mode 100644 index 0000000..89f93ed --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/WakeLockOptions.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.engine.options; + +import android.os.PowerManager; + +/** + * @author Nicolas Gramlich + * @since 19:45:23 - 10.07.2010 + */ +public enum WakeLockOptions { + // =========================================================== + // Elements + // =========================================================== + + /** Screen is on at full brightness. Keyboard backlight is on at full brightness. Requires WAKE_LOCK permission! */ + BRIGHT(PowerManager.FULL_WAKE_LOCK), + /** Screen is on at full brightness. Keyboard backlight will be allowed to go off. Requires WAKE_LOCK permission!*/ + SCREEN_BRIGHT(PowerManager.SCREEN_BRIGHT_WAKE_LOCK), + /** Screen is on but may be dimmed. Keyboard backlight will be allowed to go off. Requires WAKE_LOCK permission!*/ + SCREEN_DIM(PowerManager.SCREEN_DIM_WAKE_LOCK), + /** Screen is on at full brightness. Does not require WAKE_LOCK permission! */ + SCREEN_ON(-1); + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mFlag; + + // =========================================================== + // Constructors + // =========================================================== + + private WakeLockOptions(final int pFlag) { + this.mFlag = pFlag; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getFlag() { + return this.mFlag; + } + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/BaseResolutionPolicy.java b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/BaseResolutionPolicy.java new file mode 100644 index 0000000..456aafe --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/BaseResolutionPolicy.java @@ -0,0 +1,46 @@ +package org.anddev.andengine.engine.options.resolutionpolicy; + +import android.view.View.MeasureSpec; + +/** + * @author Nicolas Gramlich + * @since 22:46:43 - 06.10.2010 + */ +public abstract class BaseResolutionPolicy implements IResolutionPolicy { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected static void throwOnNotMeasureSpecEXACTLY(final int pWidthMeasureSpec, final int pHeightMeasureSpec) { + final int specWidthMode = MeasureSpec.getMode(pWidthMeasureSpec); + final int specHeightMode = MeasureSpec.getMode(pHeightMeasureSpec); + + if (specWidthMode != MeasureSpec.EXACTLY || specHeightMode != MeasureSpec.EXACTLY) { + throw new IllegalStateException("This IResolutionPolicy requires MeasureSpec.EXACTLY ! That means "); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/FillResolutionPolicy.java b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/FillResolutionPolicy.java new file mode 100644 index 0000000..2871c8c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/FillResolutionPolicy.java @@ -0,0 +1,49 @@ +package org.anddev.andengine.engine.options.resolutionpolicy; + +import org.anddev.andengine.opengl.view.RenderSurfaceView; + +import android.view.View.MeasureSpec; + +/** + * @author Nicolas Gramlich + * @since 11:22:48 - 29.03.2010 + */ +public class FillResolutionPolicy extends BaseResolutionPolicy { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onMeasure(final RenderSurfaceView pRenderSurfaceView, final int pWidthMeasureSpec, final int pHeightMeasureSpec) { + BaseResolutionPolicy.throwOnNotMeasureSpecEXACTLY(pWidthMeasureSpec, pHeightMeasureSpec); + + final int measuredWidth = MeasureSpec.getSize(pWidthMeasureSpec); + final int measuredHeight = MeasureSpec.getSize(pHeightMeasureSpec); + + pRenderSurfaceView.setMeasuredDimensionProxy(measuredWidth, measuredHeight); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/FixedResolutionPolicy.java b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/FixedResolutionPolicy.java new file mode 100644 index 0000000..5c15df1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/FixedResolutionPolicy.java @@ -0,0 +1,50 @@ +package org.anddev.andengine.engine.options.resolutionpolicy; + +import org.anddev.andengine.opengl.view.RenderSurfaceView; + +/** + * @author Nicolas Gramlich + * @since 11:23:00 - 29.03.2010 + */ +public class FixedResolutionPolicy extends BaseResolutionPolicy { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mWidth; + private final int mHeight; + + // =========================================================== + // Constructors + // =========================================================== + + public FixedResolutionPolicy(final int pWidth, final int pHeight) { + this.mWidth = pWidth; + this.mHeight = pHeight; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onMeasure(final RenderSurfaceView pRenderSurfaceView, final int pWidthMeasureSpec, final int pHeightMeasureSpec) { + pRenderSurfaceView.setMeasuredDimensionProxy(this.mWidth, this.mHeight); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/IResolutionPolicy.java b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/IResolutionPolicy.java new file mode 100644 index 0000000..3d4c11b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/IResolutionPolicy.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.engine.options.resolutionpolicy; + +import org.anddev.andengine.opengl.view.RenderSurfaceView; + +/** + * @author Nicolas Gramlich + * @since 11:02:35 - 29.03.2010 + */ +public interface IResolutionPolicy { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onMeasure(final RenderSurfaceView pRenderSurfaceView, final int pWidthMeasureSpec, final int pHeightMeasureSpec); +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/RatioResolutionPolicy.java b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/RatioResolutionPolicy.java new file mode 100644 index 0000000..dcb2536 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/RatioResolutionPolicy.java @@ -0,0 +1,72 @@ +package org.anddev.andengine.engine.options.resolutionpolicy; + +import org.anddev.andengine.opengl.view.RenderSurfaceView; + +import android.view.View.MeasureSpec; + +/** + * @author Nicolas Gramlich + * @since 11:23:00 - 29.03.2010 + */ +public class RatioResolutionPolicy extends BaseResolutionPolicy { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mRatio; + + // =========================================================== + // Constructors + // =========================================================== + + public RatioResolutionPolicy(final float pRatio) { + this.mRatio = pRatio; + } + + public RatioResolutionPolicy(final float pWidthRatio, final float pHeightRatio) { + this.mRatio = pWidthRatio / pHeightRatio; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onMeasure(final RenderSurfaceView pRenderSurfaceView, final int pWidthMeasureSpec, final int pHeightMeasureSpec) { + BaseResolutionPolicy.throwOnNotMeasureSpecEXACTLY(pWidthMeasureSpec, pHeightMeasureSpec); + + final int specWidth = MeasureSpec.getSize(pWidthMeasureSpec); + final int specHeight = MeasureSpec.getSize(pHeightMeasureSpec); + + final float desiredRatio = this.mRatio; + final float realRatio = (float)specWidth / specHeight; + + int measuredWidth; + int measuredHeight; + if(realRatio < desiredRatio) { + measuredWidth = specWidth; + measuredHeight = Math.round(measuredWidth / desiredRatio); + } else { + measuredHeight = specHeight; + measuredWidth = Math.round(measuredHeight * desiredRatio); + } + + pRenderSurfaceView.setMeasuredDimensionProxy(measuredWidth, measuredHeight); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/RelativeResolutionPolicy.java b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/RelativeResolutionPolicy.java new file mode 100644 index 0000000..a7e0c2a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/engine/options/resolutionpolicy/RelativeResolutionPolicy.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.engine.options.resolutionpolicy; + +import org.anddev.andengine.opengl.view.RenderSurfaceView; + +import android.view.View.MeasureSpec; + +/** + * @author Nicolas Gramlich + * @since 11:23:00 - 29.03.2010 + */ +public class RelativeResolutionPolicy extends BaseResolutionPolicy { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mWidthScale; + private final float mHeightScale; + + // =========================================================== + // Constructors + // =========================================================== + + public RelativeResolutionPolicy(final float pScale) { + this(pScale, pScale); + } + + public RelativeResolutionPolicy(final float pWidthScale, final float pHeightScale) { + this.mWidthScale = pWidthScale; + this.mHeightScale = pHeightScale; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + @Override + public void onMeasure(final RenderSurfaceView pRenderSurfaceView, final int pWidthMeasureSpec, final int pHeightMeasureSpec) { + BaseResolutionPolicy.throwOnNotMeasureSpecEXACTLY(pWidthMeasureSpec, pHeightMeasureSpec); + + final int measuredWidth = (int)(MeasureSpec.getSize(pWidthMeasureSpec) * this.mWidthScale); + final int measuredHeight = (int)(MeasureSpec.getSize(pHeightMeasureSpec) * this.mHeightScale); + + pRenderSurfaceView.setMeasuredDimensionProxy(measuredWidth, measuredHeight); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/Entity.java b/AndEngine/src/org/anddev/andengine/entity/Entity.java new file mode 100644 index 0000000..b725177 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/Entity.java @@ -0,0 +1,794 @@ +package org.anddev.andengine.entity; + +import java.util.ArrayList; +import java.util.Comparator; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.engine.handler.UpdateHandlerList; +import org.anddev.andengine.entity.layer.ZIndexSorter; +import org.anddev.andengine.entity.modifier.EntityModifierList; +import org.anddev.andengine.entity.modifier.IEntityModifier; +import org.anddev.andengine.entity.modifier.IEntityModifier.IEntityModifierMatcher; +import org.anddev.andengine.util.ParameterCallable; +import org.anddev.andengine.util.SmartList; +import org.anddev.andengine.util.Transformation; +import org.anddev.andengine.util.constants.Constants; + + +/** + * @author Nicolas Gramlich + * @since 12:00:48 - 08.03.2010 + */ +public class Entity implements IEntity { + // =========================================================== + // Constants + // =========================================================== + + private static final int CHILDREN_CAPACITY_DEFAULT = 4; + private static final int ENTITYMODIFIERS_CAPACITY_DEFAULT = 4; + private static final int UPDATEHANDLERS_CAPACITY_DEFAULT = 4; + + private static final float[] VERTICES_SCENE_TO_LOCAL_TMP = new float[2]; + private static final float[] VERTICES_LOCAL_TO_SCENE_TMP = new float[2]; + + private static final ParameterCallable PARAMETERCALLABLE_DETACHCHILD = new ParameterCallable() { + @Override + public void call(final IEntity pEntity) { + pEntity.setParent(null); + pEntity.onDetached(); + } + }; + + // =========================================================== + // Fields + // =========================================================== + + protected boolean mVisible = true; + protected boolean mIgnoreUpdate = false; + + protected int mZIndex = 0; + + private IEntity mParent; + + protected SmartList mChildren; + private EntityModifierList mEntityModifiers; + private UpdateHandlerList mUpdateHandlers; + + protected float mRed = 1f; + protected float mGreen = 1f; + protected float mBlue = 1f; + protected float mAlpha = 1f; + + protected float mX; + protected float mY; + + private final float mInitialX; + private final float mInitialY; + + protected float mRotation = 0; + + protected float mRotationCenterX = 0; + protected float mRotationCenterY = 0; + + protected float mScaleX = 1f; + protected float mScaleY = 1f; + + protected float mScaleCenterX = 0; + protected float mScaleCenterY = 0; + + private final Transformation mLocalToSceneTransformation = new Transformation(); + private final Transformation mSceneToLocalTransformation = new Transformation(); + + private Object mUserData; + + // =========================================================== + // Constructors + // =========================================================== + + public Entity() { + this(0, 0); + } + + public Entity(final float pX, final float pY) { + this.mInitialX = pX; + this.mInitialY = pY; + + this.mX = pX; + this.mY = pY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean isVisible() { + return this.mVisible; + } + + @Override + public void setVisible(final boolean pVisible) { + this.mVisible = pVisible; + } + + @Override + public boolean isIgnoreUpdate() { + return this.mIgnoreUpdate; + } + + @Override + public void setIgnoreUpdate(final boolean pIgnoreUpdate) { + this.mIgnoreUpdate = pIgnoreUpdate; + } + + @Override + public IEntity getParent() { + return this.mParent; + } + + @Override + public void setParent(final IEntity pEntity) { + this.mParent = pEntity; + } + + @Override + public int getZIndex() { + return this.mZIndex; + } + + @Override + public void setZIndex(final int pZIndex) { + this.mZIndex = pZIndex; + } + + @Override + public float getX() { + return this.mX; + } + + @Override + public float getY() { + return this.mY; + } + + @Override + public float getInitialX() { + return this.mInitialX; + } + + @Override + public float getInitialY() { + return this.mInitialY; + } + + @Override + public void setPosition(final IEntity pOtherEntity) { + this.setPosition(pOtherEntity.getX(), pOtherEntity.getY()); + } + + @Override + public void setPosition(final float pX, final float pY) { + this.mX = pX; + this.mY = pY; + } + + @Override + public void setInitialPosition() { + this.mX = this.mInitialX; + this.mY = this.mInitialY; + } + + @Override + public float getRotation() { + return this.mRotation; + } + + @Override + public void setRotation(final float pRotation) { + this.mRotation = pRotation; + } + + @Override + public float getRotationCenterX() { + return this.mRotationCenterX; + } + + @Override + public float getRotationCenterY() { + return this.mRotationCenterY; + } + + @Override + public void setRotationCenterX(final float pRotationCenterX) { + this.mRotationCenterX = pRotationCenterX; + } + + @Override + public void setRotationCenterY(final float pRotationCenterY) { + this.mRotationCenterY = pRotationCenterY; + } + + @Override + public void setRotationCenter(final float pRotationCenterX, final float pRotationCenterY) { + this.mRotationCenterX = pRotationCenterX; + this.mRotationCenterY = pRotationCenterY; + } + + @Override + public boolean isScaled() { + return this.mScaleX != 1 || this.mScaleY != 1; + } + + @Override + public float getScaleX() { + return this.mScaleX; + } + + @Override + public float getScaleY() { + return this.mScaleY; + } + + @Override + public void setScaleX(final float pScaleX) { + this.mScaleX = pScaleX; + } + + @Override + public void setScaleY(final float pScaleY) { + this.mScaleY = pScaleY; + } + + @Override + public void setScale(final float pScale) { + this.mScaleX = pScale; + this.mScaleY = pScale; + } + + @Override + public void setScale(final float pScaleX, final float pScaleY) { + this.mScaleX = pScaleX; + this.mScaleY = pScaleY; + } + + @Override + public float getScaleCenterX() { + return this.mScaleCenterX; + } + + @Override + public float getScaleCenterY() { + return this.mScaleCenterY; + } + + @Override + public void setScaleCenterX(final float pScaleCenterX) { + this.mScaleCenterX = pScaleCenterX; + } + + @Override + public void setScaleCenterY(final float pScaleCenterY) { + this.mScaleCenterY = pScaleCenterY; + } + + @Override + public void setScaleCenter(final float pScaleCenterX, final float pScaleCenterY) { + this.mScaleCenterX = pScaleCenterX; + this.mScaleCenterY = pScaleCenterY; + } + + @Override + public float getRed() { + return this.mRed; + } + + @Override + public float getGreen() { + return this.mGreen; + } + + @Override + public float getBlue() { + return this.mBlue; + } + + @Override + public float getAlpha() { + return this.mAlpha; + } + + /** + * @param pAlpha from 0.0f (transparent) to 1.0f (opaque) + */ + @Override + public void setAlpha(final float pAlpha) { + this.mAlpha = pAlpha; + } + + /** + * @param pRed from 0.0f to 1.0f + * @param pGreen from 0.0f to 1.0f + * @param pBlue from 0.0f to 1.0f + */ + @Override + public void setColor(final float pRed, final float pGreen, final float pBlue) { + this.mRed = pRed; + this.mGreen = pGreen; + this.mBlue = pBlue; + } + + /** + * @param pRed from 0.0f to 1.0f + * @param pGreen from 0.0f to 1.0f + * @param pBlue from 0.0f to 1.0f + * @param pAlpha from 0.0f (transparent) to 1.0f (opaque) + */ + @Override + public void setColor(final float pRed, final float pGreen, final float pBlue, final float pAlpha) { + this.mRed = pRed; + this.mGreen = pGreen; + this.mBlue = pBlue; + this.mAlpha = pAlpha; + } + + @Override + public int getChildCount() { + if(this.mChildren == null) { + return 0; + } + return this.mChildren.size(); + } + + @Override + public IEntity getChild(final int pIndex) { + if(this.mChildren == null) { + return null; + } + return this.mChildren.get(pIndex); + } + + @Override + public IEntity getFirstChild() { + if(this.mChildren == null) { + return null; + } + return this.mChildren.get(0); + } + + @Override + public IEntity getLastChild() { + if(this.mChildren == null) { + return null; + } + return this.mChildren.get(this.mChildren.size() - 1); + } + + @Override + public boolean detachSelf() { + final IEntity parent = this.mParent; + if(parent != null) { + return parent.detachChild(this); + } else { + return false; + } + } + + @Override + public void detachChildren() { + if(this.mChildren == null) { + return; + } + this.mChildren.clear(PARAMETERCALLABLE_DETACHCHILD); + } + + @Override + public void attachChild(final IEntity pEntity) { + if(this.mChildren == null) { + this.allocateChildren(); + } + + this.mChildren.add(pEntity); + pEntity.setParent(this); + pEntity.onAttached(); + } + + @Override + public IEntity findChild(final IEntityMatcher pEntityMatcher) { + if(this.mChildren == null) { + return null; + } + return this.mChildren.find(pEntityMatcher); + } + + @Override + public void sortChildren() { + if(this.mChildren == null) { + return; + } + ZIndexSorter.getInstance().sort(this.mChildren); + } + + @Override + public void sortChildren(final Comparator pEntityComparator) { + if(this.mChildren == null) { + return; + } + ZIndexSorter.getInstance().sort(this.mChildren, pEntityComparator); + } + + @Override + public boolean detachChild(final IEntity pEntity) { + if(this.mChildren == null) { + return false; + } + return this.mChildren.remove(pEntity, PARAMETERCALLABLE_DETACHCHILD); + } + + @Override + public IEntity detachChild(final IEntityMatcher pEntityMatcher) { + if(this.mChildren == null) { + return null; + } + return this.mChildren.remove(pEntityMatcher); + } + + @Override + public boolean detachChildren(final IEntityMatcher pEntityMatcher) { + if(this.mChildren == null) { + return false; + } + return this.mChildren.removeAll(pEntityMatcher, Entity.PARAMETERCALLABLE_DETACHCHILD); + } + + @Override + public void registerUpdateHandler(final IUpdateHandler pUpdateHandler) { + if(this.mUpdateHandlers == null) { + this.allocateUpdateHandlers(); + } + this.mUpdateHandlers.add(pUpdateHandler); + } + + @Override + public boolean unregisterUpdateHandler(final IUpdateHandler pUpdateHandler) { + if(this.mUpdateHandlers == null) { + return false; + } + return this.mUpdateHandlers.remove(pUpdateHandler); + } + + @Override + public boolean unregisterUpdateHandlers(final IUpdateHandlerMatcher pUpdateHandlerMatcher) { + if(this.mUpdateHandlers == null) { + return false; + } + return this.mUpdateHandlers.removeAll(pUpdateHandlerMatcher); + } + + @Override + public void clearUpdateHandlers() { + if(this.mUpdateHandlers == null) { + return; + } + this.mUpdateHandlers.clear(); + } + + @Override + public void registerEntityModifier(final IEntityModifier pEntityModifier) { + if(this.mEntityModifiers == null) { + this.allocateEntityModifiers(); + } + this.mEntityModifiers.add(pEntityModifier); + } + + @Override + public boolean unregisterEntityModifier(final IEntityModifier pEntityModifier) { + if(this.mEntityModifiers == null) { + return false; + } + return this.mEntityModifiers.remove(pEntityModifier); + } + + @Override + public boolean unregisterEntityModifiers(final IEntityModifierMatcher pEntityModifierMatcher) { + if(this.mEntityModifiers == null) { + return false; + } + return this.mEntityModifiers.removeAll(pEntityModifierMatcher); + } + + @Override + public void clearEntityModifiers() { + if(this.mEntityModifiers == null) { + return; + } + this.mEntityModifiers.clear(); + } + + @Override + public float[] getSceneCenterCoordinates() { + return this.convertLocalToSceneCoordinates(0, 0); + } + + @Override + public float[] convertLocalToSceneCoordinates(final float pX, final float pY) { + Entity.VERTICES_LOCAL_TO_SCENE_TMP[Constants.VERTEX_INDEX_X] = pX; + Entity.VERTICES_LOCAL_TO_SCENE_TMP[Constants.VERTEX_INDEX_Y] = pY; + + this.getLocalToSceneTransformation().transform(Entity.VERTICES_LOCAL_TO_SCENE_TMP); + + return Entity.VERTICES_LOCAL_TO_SCENE_TMP; + } + + @Override + public float[] convertSceneToLocalCoordinates(final float pX, final float pY) { + Entity.VERTICES_SCENE_TO_LOCAL_TMP[Constants.VERTEX_INDEX_X] = pX; + Entity.VERTICES_SCENE_TO_LOCAL_TMP[Constants.VERTEX_INDEX_Y] = pY; + + this.getSceneToLocalTransformation().transform(Entity.VERTICES_SCENE_TO_LOCAL_TMP); + + return Entity.VERTICES_SCENE_TO_LOCAL_TMP; + } + + @Override + public Transformation getLocalToSceneTransformation() { + // TODO skip this calculation when the transformation is not "dirty" + final Transformation localToSceneTransformation = this.mLocalToSceneTransformation; + localToSceneTransformation.setToIdentity(); + + /* Scale. */ + final float scaleX = this.mScaleX; + final float scaleY = this.mScaleY; + if(scaleX != 1 || scaleY != 1) { + final float scaleCenterX = this.mScaleCenterX; + final float scaleCenterY = this.mScaleCenterY; + + /* TODO Check if it is worth to check for scaleCenterX == 0 && scaleCenterY == 0 as the two postTranslate can be saved. + * The same obviously applies for all similar occurrences of this pattern in this class. */ + + localToSceneTransformation.postTranslate(-scaleCenterX, -scaleCenterY); + localToSceneTransformation.postScale(scaleX, scaleY); + localToSceneTransformation.postTranslate(scaleCenterX, scaleCenterY); + } + + /* TODO There is a special, but very likely case when mRotationCenter and mScaleCenter are the same. + * In that case the last postTranslate of the scale and the first postTranslate of the rotation is superfluous. */ + + /* Rotation. */ + final float rotation = this.mRotation; + if(rotation != 0) { + final float rotationCenterX = this.mRotationCenterX; + final float rotationCenterY = this.mRotationCenterY; + + localToSceneTransformation.postTranslate(-rotationCenterX, -rotationCenterY); + localToSceneTransformation.postRotate(rotation); + localToSceneTransformation.postTranslate(rotationCenterX, rotationCenterY); + } + + /* Translation. */ + localToSceneTransformation.postTranslate(this.mX, this.mY); + + final IEntity parent = this.mParent; + if(parent != null) { + localToSceneTransformation.postConcat(parent.getLocalToSceneTransformation()); + } + + return localToSceneTransformation; + } + + @Override + public Transformation getSceneToLocalTransformation() { + // TODO skip this calculation when the transformation is not "dirty" + final Transformation sceneToLocalTransformation = this.mSceneToLocalTransformation; + sceneToLocalTransformation.setToIdentity(); + + final IEntity parent = this.mParent; + if(parent != null) { + sceneToLocalTransformation.postConcat(parent.getSceneToLocalTransformation()); + } + + /* Translation. */ + sceneToLocalTransformation.postTranslate(-this.mX, -this.mY); + + /* Rotation. */ + final float rotation = this.mRotation; + if(rotation != 0) { + final float rotationCenterX = this.mRotationCenterX; + final float rotationCenterY = this.mRotationCenterY; + + sceneToLocalTransformation.postTranslate(-rotationCenterX, -rotationCenterY); + sceneToLocalTransformation.postRotate(-rotation); + sceneToLocalTransformation.postTranslate(rotationCenterX, rotationCenterY); + } + + /* TODO There is a special, but very likely case when mRotationCenter and mScaleCenter are the same. + * In that case the last postTranslate of the rotation and the first postTranslate of the scale is superfluous. */ + + /* Scale. */ + final float scaleX = this.mScaleX; + final float scaleY = this.mScaleY; + if(scaleX != 1 || scaleY != 1) { + final float scaleCenterX = this.mScaleCenterX; + final float scaleCenterY = this.mScaleCenterY; + + sceneToLocalTransformation.postTranslate(-scaleCenterX, -scaleCenterY); + sceneToLocalTransformation.postScale(1 / scaleX, 1 / scaleY); + sceneToLocalTransformation.postTranslate(scaleCenterX, scaleCenterY); + } + + return sceneToLocalTransformation; + } + + @Override + public void onAttached() { + + } + + @Override + public void onDetached() { + + } + + @Override + public Object getUserData() { + return this.mUserData; + } + + @Override + public void setUserData(final Object pUserData) { + this.mUserData = pUserData; + } + + @Override + public final void onDraw(final GL10 pGL, final Camera pCamera) { + if(this.mVisible) { + this.onManagedDraw(pGL, pCamera); + } + } + + @Override + public final void onUpdate(final float pSecondsElapsed) { + if(!this.mIgnoreUpdate) { + this.onManagedUpdate(pSecondsElapsed); + } + } + + @Override + public void reset() { + this.mVisible = true; + this.mIgnoreUpdate = false; + + this.mX = this.mInitialX; + this.mY = this.mInitialY; + this.mRotation = 0; + this.mScaleX = 1; + this.mScaleY = 1; + + this.mRed = 1.0f; + this.mGreen = 1.0f; + this.mBlue = 1.0f; + this.mAlpha = 1.0f; + + if(this.mEntityModifiers != null) { + this.mEntityModifiers.reset(); + } + + if(this.mChildren != null) { + final ArrayList entities = this.mChildren; + for(int i = entities.size() - 1; i >= 0; i--) { + entities.get(i).reset(); + } + } + } + + // =========================================================== + // Methods + // =========================================================== + + protected void doDraw(final GL10 pGL, final Camera pCamera) { + + } + + private void allocateEntityModifiers() { + this.mEntityModifiers = new EntityModifierList(this, Entity.ENTITYMODIFIERS_CAPACITY_DEFAULT); + } + + private void allocateChildren() { + this.mChildren = new SmartList(Entity.CHILDREN_CAPACITY_DEFAULT); + } + + private void allocateUpdateHandlers() { + this.mUpdateHandlers = new UpdateHandlerList(Entity.UPDATEHANDLERS_CAPACITY_DEFAULT); + } + + protected void onApplyTransformations(final GL10 pGL) { + /* Translation. */ + this.applyTranslation(pGL); + + /* Rotation. */ + this.applyRotation(pGL); + + /* Scale. */ + this.applyScale(pGL); + } + + protected void applyTranslation(final GL10 pGL) { + pGL.glTranslatef(this.mX, this.mY, 0); + } + + protected void applyRotation(final GL10 pGL) { + final float rotation = this.mRotation; + + if(rotation != 0) { + final float rotationCenterX = this.mRotationCenterX; + final float rotationCenterY = this.mRotationCenterY; + + pGL.glTranslatef(rotationCenterX, rotationCenterY, 0); + pGL.glRotatef(rotation, 0, 0, 1); + pGL.glTranslatef(-rotationCenterX, -rotationCenterY, 0); + + /* TODO There is a special, but very likely case when mRotationCenter and mScaleCenter are the same. + * In that case the last glTranslatef of the rotation and the first glTranslatef of the scale is superfluous. + * The problem is that applyRotation and applyScale would need to be "merged" in order to efficiently check for that condition. */ + } + } + + protected void applyScale(final GL10 pGL) { + final float scaleX = this.mScaleX; + final float scaleY = this.mScaleY; + + if(scaleX != 1 || scaleY != 1) { + final float scaleCenterX = this.mScaleCenterX; + final float scaleCenterY = this.mScaleCenterY; + + pGL.glTranslatef(scaleCenterX, scaleCenterY, 0); + pGL.glScalef(scaleX, scaleY, 1); + pGL.glTranslatef(-scaleCenterX, -scaleCenterY, 0); + } + } + + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + pGL.glPushMatrix(); + { + this.onApplyTransformations(pGL); + + this.doDraw(pGL, pCamera); + + if(this.mChildren != null) { + final ArrayList entities = this.mChildren; + final int entityCount = entities.size(); + for(int i = 0; i < entityCount; i++) { + entities.get(i).onDraw(pGL, pCamera); + } + } + } + pGL.glPopMatrix(); + } + + protected void onManagedUpdate(final float pSecondsElapsed) { + if(this.mEntityModifiers != null) { + this.mEntityModifiers.onUpdate(pSecondsElapsed); + } + if(this.mUpdateHandlers != null) { + this.mUpdateHandlers.onUpdate(pSecondsElapsed); + } + + if(this.mChildren != null) { + final ArrayList entities = this.mChildren; + final int entityCount = entities.size(); + for(int i = 0; i < entityCount; i++) { + entities.get(i).onUpdate(pSecondsElapsed); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/IEntity.java b/AndEngine/src/org/anddev/andengine/entity/IEntity.java new file mode 100644 index 0000000..9b3fa5d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/IEntity.java @@ -0,0 +1,171 @@ +package org.anddev.andengine.entity; + +import java.util.Comparator; + +import org.anddev.andengine.engine.Engine; +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.engine.handler.runnable.RunnableHandler; +import org.anddev.andengine.entity.modifier.IEntityModifier; +import org.anddev.andengine.entity.modifier.IEntityModifier.IEntityModifierMatcher; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.opengl.IDrawable; +import org.anddev.andengine.util.IMatcher; +import org.anddev.andengine.util.Transformation; + + + +/** + * @author Nicolas Gramlich + * @since 11:20:25 - 08.03.2010 + */ +public interface IEntity extends IDrawable, IUpdateHandler { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean isVisible(); + public void setVisible(boolean pVisible); + + public boolean isIgnoreUpdate(); + public void setIgnoreUpdate(boolean pIgnoreUpdate); + + public int getZIndex(); + public void setZIndex(final int pZIndex); + + public IEntity getParent(); + public void setParent(final IEntity pEntity); + + public float getX(); + public float getY(); + + public float getInitialX(); + public float getInitialY(); + + public void setInitialPosition(); + public void setPosition(final IEntity pOtherEntity); + public void setPosition(final float pX, final float pY); + + public float getRotation(); + public void setRotation(final float pRotation); + + public float getRotationCenterX(); + public float getRotationCenterY(); + public void setRotationCenterX(final float pRotationCenterX); + public void setRotationCenterY(final float pRotationCenterY); + public void setRotationCenter(final float pRotationCenterX, final float pRotationCenterY); + + public boolean isScaled(); + public float getScaleX(); + public float getScaleY(); + public void setScaleX(final float pScaleX); + public void setScaleY(final float pScaleY); + public void setScale(final float pScale); + public void setScale(final float pScaleX, final float pScaleY); + + public float getScaleCenterX(); + public float getScaleCenterY(); + public void setScaleCenterX(final float pScaleCenterX); + public void setScaleCenterY(final float pScaleCenterY); + public void setScaleCenter(final float pScaleCenterX, final float pScaleCenterY); + + public float getRed(); + public float getGreen(); + public float getBlue(); + public float getAlpha(); + public void setAlpha(final float pAlpha); + + public void setColor(final float pRed, final float pGreen, final float pBlue); + public void setColor(final float pRed, final float pGreen, final float pBlue, final float pAlpha); + + public float[] getSceneCenterCoordinates(); + + public float[] convertLocalToSceneCoordinates(final float pX, final float pY); + public float[] convertSceneToLocalCoordinates(final float pX, final float pY); + + public Transformation getLocalToSceneTransformation(); + public Transformation getSceneToLocalTransformation(); + + public int getChildCount(); + + public void onAttached(); + public void onDetached(); + + public void attachChild(final IEntity pEntity); + + public IEntity getChild(final int pIndex); + public IEntity getFirstChild(); + public IEntity getLastChild(); + + public IEntity findChild(final IEntityMatcher pEntityMatcher); + + /** + * Sorts the {@link IEntity}s based on their ZIndex. Sort is stable. + */ + public void sortChildren(); + + /** + * Sorts the {@link IEntity}s based on the {@link Comparator} supplied. Sort is stable. + * @param pEntityComparator + */ + public void sortChildren(final Comparator pEntityComparator); + + public boolean detachSelf(); + + /** + * WARNING: This function should be called from within + * {@link RunnableHandler#postRunnable(Runnable)} which is registered + * to a {@link Scene} or the {@link Engine} itself, because otherwise + * it may throw an {@link ArrayIndexOutOfBoundsException} in the + * Update-Thread or the GL-Thread! + */ + public boolean detachChild(final IEntity pEntity); + /** + * WARNING: This function should be called from within + * {@link RunnableHandler#postRunnable(Runnable)} which is registered + * to a {@link Scene} or the {@link Engine} itself, because otherwise + * it may throw an {@link ArrayIndexOutOfBoundsException} in the + * Update-Thread or the GL-Thread! + */ + public IEntity detachChild(final IEntityMatcher pEntityMatcher); + /** + * WARNING: This function should be called from within + * {@link RunnableHandler#postRunnable(Runnable)} which is registered + * to a {@link Scene} or the {@link Engine} itself, because otherwise + * it may throw an {@link ArrayIndexOutOfBoundsException} in the + * Update-Thread or the GL-Thread! + */ + public boolean detachChildren(final IEntityMatcher pEntityMatcher); + + public void detachChildren(); + + public void registerUpdateHandler(final IUpdateHandler pUpdateHandler); + public boolean unregisterUpdateHandler(final IUpdateHandler pUpdateHandler); + public boolean unregisterUpdateHandlers(final IUpdateHandlerMatcher pUpdateHandlerMatcher); + public void clearUpdateHandlers(); + + public void registerEntityModifier(final IEntityModifier pEntityModifier); + public boolean unregisterEntityModifier(final IEntityModifier pEntityModifier); + public boolean unregisterEntityModifiers(final IEntityModifierMatcher pEntityModifierMatcher); + public void clearEntityModifiers(); + + public void setUserData(Object pUserData); + public Object getUserData(); + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface IEntityMatcher extends IMatcher { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/Layer.java b/AndEngine/src/org/anddev/andengine/entity/layer/Layer.java new file mode 100644 index 0000000..4780685 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/Layer.java @@ -0,0 +1,45 @@ +package org.anddev.andengine.entity.layer; + +import org.anddev.andengine.entity.Entity; + +/** + * @author Nicolas Gramlich + * @since 11:48:23 - 20.12.2010 + */ +public class Layer extends Entity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public Layer() { + super(0, 0); + } + + public Layer(final float pX, final float pY) { + super(pX, pY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/ZIndexSorter.java b/AndEngine/src/org/anddev/andengine/entity/layer/ZIndexSorter.java new file mode 100644 index 0000000..e41e972 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/ZIndexSorter.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.layer; + +import java.util.Comparator; +import java.util.List; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.sort.InsertionSorter; + +public class ZIndexSorter extends InsertionSorter { + // =========================================================== + // Constants + // =========================================================== + + private static ZIndexSorter INSTANCE; + + // =========================================================== + // Fields + // =========================================================== + + private final Comparator mZIndexComparator = new Comparator() { + @Override + public int compare(final IEntity pEntityA, final IEntity pEntityB) { + return pEntityA.getZIndex() - pEntityB.getZIndex(); + } + }; + + // =========================================================== + // Constructors + // =========================================================== + + private ZIndexSorter() { + + } + + public static ZIndexSorter getInstance() { + if(INSTANCE == null) { + INSTANCE = new ZIndexSorter(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void sort(final IEntity[] pEntities) { + this.sort(pEntities, this.mZIndexComparator); + } + + public void sort(final IEntity[] pEntities, final int pStart, final int pEnd) { + this.sort(pEntities, pStart, pEnd, this.mZIndexComparator); + } + + public void sort(final List pEntities) { + this.sort(pEntities, this.mZIndexComparator); + } + + public void sort(final List pEntities, final int pStart, final int pEnd) { + this.sort(pEntities, pStart, pEnd, this.mZIndexComparator); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayer.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayer.java new file mode 100644 index 0000000..332e0d3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayer.java @@ -0,0 +1,321 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.collision.RectangularShapeCollisionChecker; +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener; +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.entity.shape.RectangularShape; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; +import org.anddev.andengine.util.Base64; +import org.anddev.andengine.util.Base64InputStream; +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.SAXUtils; +import org.anddev.andengine.util.StreamUtils; +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 20:27:31 - 20.07.2010 + */ +public class TMXLayer extends RectangularShape implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final TMXTiledMap mTMXTiledMap; + + private final String mName; + private final int mTileColumns; + private final int mTileRows; + private final TMXTile[][] mTMXTiles; + + private int mTilesAdded; + private final int mGlobalTileIDsExpected; + + private final float[] mCullingVertices = new float[2 * RectangleVertexBuffer.VERTICES_PER_RECTANGLE]; + + private final TMXProperties mTMXLayerProperties = new TMXProperties(); + + // =========================================================== + // Constructors + // =========================================================== + + public TMXLayer(final TMXTiledMap pTMXTiledMap, final Attributes pAttributes) { + super(0, 0, 0, 0, null); + + this.mTMXTiledMap = pTMXTiledMap; + this.mName = pAttributes.getValue("", TAG_LAYER_ATTRIBUTE_NAME); + this.mTileColumns = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_LAYER_ATTRIBUTE_WIDTH); + this.mTileRows = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_LAYER_ATTRIBUTE_HEIGHT); + this.mTMXTiles = new TMXTile[this.mTileRows][this.mTileColumns]; + + super.mWidth = pTMXTiledMap.getTileWidth() * this.mTileColumns; + final float width = super.mWidth; + super.mBaseWidth = width; + + super.mHeight = pTMXTiledMap.getTileHeight() * this.mTileRows; + final float height = super.mHeight; + super.mBaseHeight = height; + + this.mRotationCenterX = width * 0.5f; + this.mRotationCenterY = height * 0.5f; + + this.mScaleCenterX = this.mRotationCenterX; + this.mScaleCenterY = this.mRotationCenterY; + + this.mGlobalTileIDsExpected = this.mTileColumns * this.mTileRows; + + this.setVisible(SAXUtils.getIntAttribute(pAttributes, TAG_LAYER_ATTRIBUTE_VISIBLE, TAG_LAYER_ATTRIBUTE_VISIBLE_VALUE_DEFAULT) == 1); + this.setAlpha(SAXUtils.getFloatAttribute(pAttributes, TAG_LAYER_ATTRIBUTE_OPACITY, TAG_LAYER_ATTRIBUTE_OPACITY_VALUE_DEFAULT)); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public String getName() { + return this.mName; + } + + public int getTileColumns() { + return this.mTileColumns; + } + + public int getTileRows() { + return this.mTileRows; + } + + public TMXTile[][] getTMXTiles() { + return this.mTMXTiles; + } + + public TMXTile getTMXTile(final int pTileColumn, final int pTileRow) throws ArrayIndexOutOfBoundsException { + return this.mTMXTiles[pTileRow][pTileColumn]; + } + + /** + * @param pX in SceneCoordinates. + * @param pY in SceneCoordinates. + * @return the {@link TMXTile} located at pX/pY. + */ + public TMXTile getTMXTileAt(final float pX, final float pY) { + final float[] localCoords = this.convertSceneToLocalCoordinates(pX, pY); + final TMXTiledMap tmxTiledMap = this.mTMXTiledMap; + + final int tileColumn = (int)(localCoords[VERTEX_INDEX_X] / tmxTiledMap.getTileWidth()); + if(tileColumn < 0 || tileColumn > this.mTileColumns - 1) { + return null; + } + final int tileRow = (int)(localCoords[VERTEX_INDEX_Y] / tmxTiledMap.getTileWidth()); + if(tileRow < 0 || tileRow > this.mTileRows - 1) { + return null; + } + + return this.mTMXTiles[tileRow][tileColumn]; + } + + public void addTMXLayerProperty(final TMXLayerProperty pTMXLayerProperty) { + this.mTMXLayerProperties.add(pTMXLayerProperty); + } + + public TMXProperties getTMXLayerProperties() { + return this.mTMXLayerProperties; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + @Deprecated + public void setRotation(final float pRotation) { + + } + + @Override + protected void onUpdateVertexBuffer() { + /* Nothing. */ + } + + @Override + protected void onInitDraw(final GL10 pGL) { + super.onInitDraw(pGL); + + GLHelper.enableTextures(pGL); + GLHelper.enableTexCoordArray(pGL); + } + + @Override + protected void onApplyVertices(final GL10 pGL) { + if(GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS) { + final GL11 gl11 = (GL11)pGL; + + this.mTMXTiledMap.getSharedVertexBuffer().selectOnHardware(gl11); + GLHelper.vertexZeroPointer(gl11); + } else { + GLHelper.vertexPointer(pGL, this.mTMXTiledMap.getSharedVertexBuffer().getFloatBuffer()); + } + } + + @Override + protected void drawVertices(final GL10 pGL, final Camera pCamera) { + final TMXTile[][] tmxTiles = this.mTMXTiles; + + final int tileColumns = this.mTileColumns; + final int tileRows = this.mTileRows; + final int tileWidth = this.mTMXTiledMap.getTileWidth(); + final int tileHeight = this.mTMXTiledMap.getTileHeight(); + + final float scaledTileWidth = tileWidth * this.mScaleX; + final float scaledTileHeight = tileHeight * this.mScaleY; + + final float[] cullingVertices = this.mCullingVertices; + RectangularShapeCollisionChecker.fillVertices(this, cullingVertices); + + final float layerMinX = cullingVertices[VERTEX_INDEX_X]; + final float layerMinY = cullingVertices[VERTEX_INDEX_Y]; + + final float cameraMinX = pCamera.getMinX(); + final float cameraMinY = pCamera.getMinY(); + final float cameraWidth = pCamera.getWidth(); + final float cameraHeight = pCamera.getHeight(); + + /* Determine the area that is visible in the camera. */ + final float firstColumnRaw = (cameraMinX - layerMinX) / scaledTileWidth; + final int firstColumn = MathUtils.bringToBounds(0, tileColumns - 1, (int)Math.floor(firstColumnRaw)); + final int lastColumn = MathUtils.bringToBounds(0, tileColumns - 1, (int)Math.ceil(firstColumnRaw + cameraWidth / scaledTileWidth)); + + final float firstRowRaw = (cameraMinY - layerMinY) / scaledTileHeight; + final int firstRow = MathUtils.bringToBounds(0, tileRows - 1, (int)Math.floor(firstRowRaw)); + final int lastRow = MathUtils.bringToBounds(0, tileRows - 1, (int)Math.floor(firstRowRaw + cameraHeight / scaledTileHeight)); + + final int visibleTilesTotalWidth = (lastColumn - firstColumn + 1) * tileWidth; + + pGL.glTranslatef(firstColumn * tileWidth, firstRow * tileHeight, 0); + + for(int row = firstRow; row <= lastRow; row++) { + final TMXTile[] tmxTileRow = tmxTiles[row]; + + for(int column = firstColumn; column <= lastColumn; column++) { + final TextureRegion textureRegion = tmxTileRow[column].mTextureRegion; + if(textureRegion != null) { + textureRegion.onApply(pGL); + + pGL.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); + } + pGL.glTranslatef(tileWidth, 0, 0); + } + /* Translate one row downwards and the back left to the first column. + * Just like the 'Carriage Return' + 'New Line' (\r\n) on a typewriter. */ + pGL.glTranslatef(-visibleTilesTotalWidth, tileHeight, 0); + } + pGL.glLoadIdentity(); + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + /* Nothing. */ + } + + // =========================================================== + // Methods + // =========================================================== + + void initializeTMXTileFromXML(final Attributes pAttributes, final ITMXTilePropertiesListener pTMXTilePropertyListener) { + this.addTileByGlobalTileID(SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_TILE_ATTRIBUTE_GID), pTMXTilePropertyListener); + } + + void initializeTMXTilesFromDataString(final String pDataString, final String pDataEncoding, final String pDataCompression, final ITMXTilePropertiesListener pTMXTilePropertyListener) throws IOException, IllegalArgumentException { + DataInputStream dataIn = null; + try{ + InputStream in = new ByteArrayInputStream(pDataString.getBytes("UTF-8")); + + /* Wrap decoding Streams if neccessary. */ + if(pDataEncoding != null && pDataEncoding.equals(TAG_DATA_ATTRIBUTE_ENCODING_VALUE_BASE64)) { + in = new Base64InputStream(in, Base64.DEFAULT); + } + if(pDataCompression != null){ + if(pDataCompression.equals(TAG_DATA_ATTRIBUTE_COMPRESSION_VALUE_GZIP)) { + in = new GZIPInputStream(in); + } else { + throw new IllegalArgumentException("Supplied compression '" + pDataCompression + "' is not supported yet."); + } + } + dataIn = new DataInputStream(in); + + while(this.mTilesAdded < this.mGlobalTileIDsExpected) { + final int globalTileID = this.readGlobalTileID(dataIn); + this.addTileByGlobalTileID(globalTileID, pTMXTilePropertyListener); + } + } finally { + StreamUtils.close(dataIn); + } + } + + private void addTileByGlobalTileID(final int pGlobalTileID, final ITMXTilePropertiesListener pTMXTilePropertyListener) { + final TMXTiledMap tmxTiledMap = this.mTMXTiledMap; + + final int tilesHorizontal = this.mTileColumns; + + final int column = this.mTilesAdded % tilesHorizontal; + final int row = this.mTilesAdded / tilesHorizontal; + + final TMXTile[][] tmxTiles = this.mTMXTiles; + + final TextureRegion tmxTileTextureRegion; + if(pGlobalTileID == 0) { + tmxTileTextureRegion = null; + } else { + tmxTileTextureRegion = tmxTiledMap.getTextureRegionFromGlobalTileID(pGlobalTileID); + } + final TMXTile tmxTile = new TMXTile(pGlobalTileID, column, row, this.mTMXTiledMap.getTileWidth(), this.mTMXTiledMap.getTileHeight(), tmxTileTextureRegion); + tmxTiles[row][column] = tmxTile; + + if(pGlobalTileID != 0) { + /* Notify the ITMXTilePropertiesListener if it exists. */ + if(pTMXTilePropertyListener != null) { + final TMXProperties tmxTileProperties = tmxTiledMap.getTMXTileProperties(pGlobalTileID); + if(tmxTileProperties != null) { + pTMXTilePropertyListener.onTMXTileWithPropertiesCreated(tmxTiledMap, this, tmxTile, tmxTileProperties); + } + } + } + + this.mTilesAdded++; + } + + private int readGlobalTileID(final DataInputStream pDataIn) throws IOException { + final int lowestByte = pDataIn.read(); + final int secondLowestByte = pDataIn.read(); + final int secondHighestByte = pDataIn.read(); + final int highestByte = pDataIn.read(); + + if(lowestByte < 0 || secondLowestByte < 0 || secondHighestByte < 0 || highestByte < 0) { + throw new IllegalArgumentException("Couldn't read global Tile ID."); + } + + return lowestByte | secondLowestByte << 8 |secondHighestByte << 16 | highestByte << 24; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayerProperty.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayerProperty.java new file mode 100644 index 0000000..0c47b5b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLayerProperty.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 18:48:46 - 12.10.2010 + */ +public class TMXLayerProperty extends TMXProperty { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXLayerProperty(final Attributes pAttributes) { + super(pAttributes); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLoader.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLoader.java new file mode 100644 index 0000000..0b272f8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXLoader.java @@ -0,0 +1,118 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import android.content.Context; + +/** + * @author Nicolas Gramlich + * @since 19:10:45 - 20.07.2010 + */ +public class TMXLoader { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Context mContext; + private final TextureManager mTextureManager; + private final TextureOptions mTextureOptions; + private final ITMXTilePropertiesListener mTMXTilePropertyListener; + + // =========================================================== + // Constructors + // =========================================================== + + public TMXLoader(final Context pContext, final TextureManager pTextureManager) { + this(pContext, pTextureManager, TextureOptions.DEFAULT); + } + + public TMXLoader(final Context pContext, final TextureManager pTextureManager, final TextureOptions pTextureOptions) { + this(pContext, pTextureManager, pTextureOptions, null); + } + + public TMXLoader(final Context pContext, final TextureManager pTextureManager, final ITMXTilePropertiesListener pTMXTilePropertyListener) { + this(pContext, pTextureManager, TextureOptions.DEFAULT, pTMXTilePropertyListener); + } + + public TMXLoader(final Context pContext, final TextureManager pTextureManager, final TextureOptions pTextureOptions, final ITMXTilePropertiesListener pTMXTilePropertyListener) { + this.mContext = pContext; + this.mTextureManager = pTextureManager; + this.mTextureOptions = pTextureOptions; + this.mTMXTilePropertyListener = pTMXTilePropertyListener; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public TMXTiledMap loadFromAsset(final Context pContext, final String pAssetPath) throws TMXLoadException { + try { + return this.load(pContext.getAssets().open(pAssetPath)); + } catch (final IOException e) { + throw new TMXLoadException("Could not load TMXTiledMap from asset: " + pAssetPath, e); + } + } + + public TMXTiledMap load(final InputStream pInputStream) throws TMXLoadException { + try{ + final SAXParserFactory spf = SAXParserFactory.newInstance(); + final SAXParser sp = spf.newSAXParser(); + + final XMLReader xr = sp.getXMLReader(); + final TMXParser tmxParser = new TMXParser(this.mContext, this.mTextureManager, this.mTextureOptions, this.mTMXTilePropertyListener); + xr.setContentHandler(tmxParser); + + xr.parse(new InputSource(new BufferedInputStream(pInputStream))); + + return tmxParser.getTMXTiledMap(); + } catch (final SAXException e) { + throw new TMXLoadException(e); + } catch (final ParserConfigurationException pe) { + /* Doesn't happen. */ + return null; + } catch (final IOException e) { + throw new TMXLoadException(e); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ITMXTilePropertiesListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onTMXTileWithPropertiesCreated(final TMXTiledMap pTMXTiledMap, final TMXLayer pTMXLayer, final TMXTile pTMXTile, final TMXProperties pTMXTileProperties); + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObject.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObject.java new file mode 100644 index 0000000..023b45f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObject.java @@ -0,0 +1,88 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.util.SAXUtils; +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 11:21:01 - 29.07.2010 + */ +public class TMXObject implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final String mName; + private final String mType; + private final int mX; + private final int mY; + private final int mWidth; + private final int mHeight; + private final TMXProperties mTMXObjectProperties = new TMXProperties(); + + // =========================================================== + // Constructors + // =========================================================== + + public TMXObject(final Attributes pAttributes) { + this.mName = pAttributes.getValue("", TAG_OBJECT_ATTRIBUTE_NAME); + this.mType = pAttributes.getValue("", TAG_OBJECT_ATTRIBUTE_TYPE); + this.mX = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_OBJECT_ATTRIBUTE_X); + this.mY = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_OBJECT_ATTRIBUTE_Y); + this.mWidth = SAXUtils.getIntAttribute(pAttributes, TAG_OBJECT_ATTRIBUTE_WIDTH, 0); + this.mHeight = SAXUtils.getIntAttribute(pAttributes, TAG_OBJECT_ATTRIBUTE_HEIGHT, 0); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public String getName() { + return this.mName; + } + + public String getType() { + return this.mType; + } + + public int getX() { + return this.mX; + } + + public int getY() { + return this.mY; + } + + public int getWidth() { + return this.mWidth; + } + + public int getHeight() { + return this.mHeight; + } + + public void addTMXObjectProperty(final TMXObjectProperty pTMXObjectProperty) { + this.mTMXObjectProperties.add(pTMXObjectProperty); + } + + public TMXProperties getTMXObjectProperties() { + return this.mTMXObjectProperties; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroup.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroup.java new file mode 100644 index 0000000..42a286d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroup.java @@ -0,0 +1,81 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.util.SAXUtils; +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 11:20:49 - 29.07.2010 + */ +public class TMXObjectGroup implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final String mName; + private final int mWidth; + private final int mHeight; + private final ArrayList mTMXObjects = new ArrayList(); + private final TMXProperties mTMXObjectGroupProperties = new TMXProperties(); + + // =========================================================== + // Constructors + // =========================================================== + + public TMXObjectGroup(final Attributes pAttributes) { + this.mName = pAttributes.getValue("", TAG_OBJECTGROUP_ATTRIBUTE_NAME); + this.mWidth = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_OBJECTGROUP_ATTRIBUTE_WIDTH); + this.mHeight = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_OBJECTGROUP_ATTRIBUTE_HEIGHT); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public String getName() { + return this.mName; + } + + public int getWidth() { + return this.mWidth; + } + + public int getHeight() { + return this.mHeight; + } + + void addTMXObject(final TMXObject pTMXObject) { + this.mTMXObjects.add(pTMXObject); + } + + public ArrayList getTMXObjects() { + return this.mTMXObjects ; + } + + public void addTMXObjectGroupProperty(final TMXObjectGroupProperty pTMXObjectGroupProperty) { + this.mTMXObjectGroupProperties.add(pTMXObjectGroupProperty); + } + + public TMXProperties getTMXObjectGroupProperties() { + return this.mTMXObjectGroupProperties; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroupProperty.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroupProperty.java new file mode 100644 index 0000000..9732aee --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectGroupProperty.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 19:48:01 - 12.10.2010 + */ +public class TMXObjectGroupProperty extends TMXProperty { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXObjectGroupProperty(final Attributes pAttributes) { + super(pAttributes); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectProperty.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectProperty.java new file mode 100644 index 0000000..5edb1a0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXObjectProperty.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 11:19:44 - 29.07.2010 + */ +public class TMXObjectProperty extends TMXProperty { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXObjectProperty(final Attributes pAttributes) { + super(pAttributes); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXParser.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXParser.java new file mode 100644 index 0000000..f7bf943 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXParser.java @@ -0,0 +1,217 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import java.io.IOException; +import java.util.ArrayList; + +import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener; +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXParseException; +import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TSXLoadException; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.SAXUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import android.content.Context; + +/** + * @author Nicolas Gramlich + * @since 19:11:29 - 20.07.2010 + */ +public class TMXParser extends DefaultHandler implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Context mContext; + private final TextureManager mTextureManager; + private final ITMXTilePropertiesListener mTMXTilePropertyListener; + private final TextureOptions mTextureOptions; + + private TMXTiledMap mTMXTiledMap; + + private int mLastTileSetTileID; + + private final StringBuilder mStringBuilder = new StringBuilder(); + + private String mDataEncoding; + private String mDataCompression; + + private boolean mInMap; + private boolean mInTileset; + @SuppressWarnings("unused") + private boolean mInImage; + private boolean mInTile; + private boolean mInProperties; + @SuppressWarnings("unused") + private boolean mInProperty; + private boolean mInLayer; + private boolean mInData; + private boolean mInObjectGroup; + private boolean mInObject; + + // =========================================================== + // Constructors + // =========================================================== + + public TMXParser(final Context pContext, final TextureManager pTextureManager, final TextureOptions pTextureOptions, final ITMXTilePropertiesListener pTMXTilePropertyListener) { + this.mContext = pContext; + this.mTextureManager = pTextureManager; + this.mTextureOptions = pTextureOptions; + this.mTMXTilePropertyListener = pTMXTilePropertyListener; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + TMXTiledMap getTMXTiledMap() { + return this.mTMXTiledMap; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void startElement(final String pUri, final String pLocalName, final String pQualifiedName, final Attributes pAttributes) throws SAXException { + if(pLocalName.equals(TAG_MAP)){ + this.mInMap = true; + this.mTMXTiledMap = new TMXTiledMap(pAttributes); + } else if(pLocalName.equals(TAG_TILESET)){ + this.mInTileset = true; + final TMXTileSet tmxTileSet; + final String tsxTileSetSource = pAttributes.getValue("", TAG_TILESET_ATTRIBUTE_SOURCE); + if(tsxTileSetSource == null) { + tmxTileSet = new TMXTileSet(pAttributes, this.mTextureOptions); + } else { + try { + final int firstGlobalTileID = SAXUtils.getIntAttribute(pAttributes, TAG_TILESET_ATTRIBUTE_FIRSTGID, 1); + tmxTileSet = new TSXLoader(this.mContext, this.mTextureManager, this.mTextureOptions).loadFromAsset(this.mContext, firstGlobalTileID, tsxTileSetSource); + } catch (final TSXLoadException e) { + throw new TMXParseException("Failed to load TMXTileSet from source: " + tsxTileSetSource, e); + } + } + this.mTMXTiledMap.addTMXTileSet(tmxTileSet); + } else if(pLocalName.equals(TAG_IMAGE)){ + this.mInImage = true; + final ArrayList tmxTileSets = this.mTMXTiledMap.getTMXTileSets(); + tmxTileSets.get(tmxTileSets.size() - 1).setImageSource(this.mContext, this.mTextureManager, pAttributes); + } else if(pLocalName.equals(TAG_TILE)) { + this.mInTile = true; + if(this.mInTileset) { + this.mLastTileSetTileID = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_TILE_ATTRIBUTE_ID); + } else if(this.mInData) { + final ArrayList tmxLayers = this.mTMXTiledMap.getTMXLayers(); + tmxLayers.get(tmxLayers.size() - 1).initializeTMXTileFromXML(pAttributes, this.mTMXTilePropertyListener); + } + } else if(pLocalName.equals(TAG_PROPERTIES)) { + this.mInProperties = true; + } else if(this.mInProperties && pLocalName.equals(TAG_PROPERTY)) { + this.mInProperty = true; + if(this.mInTile) { + final ArrayList tmxTileSets = this.mTMXTiledMap.getTMXTileSets(); + final TMXTileSet lastTMXTileSet = tmxTileSets.get(tmxTileSets.size() - 1); + + lastTMXTileSet.addTMXTileProperty(this.mLastTileSetTileID, new TMXTileProperty(pAttributes)); + } else if(this.mInLayer) { + final ArrayList tmxLayers = this.mTMXTiledMap.getTMXLayers(); + final TMXLayer lastTMXLayer = tmxLayers.get(tmxLayers.size() - 1); + + lastTMXLayer.addTMXLayerProperty(new TMXLayerProperty(pAttributes)); + } else if(this.mInObject) { + final ArrayList tmxObjectGroups = this.mTMXTiledMap.getTMXObjectGroups(); + final TMXObjectGroup lastTMXObjectGroup = tmxObjectGroups.get(tmxObjectGroups.size() - 1); + + final ArrayList tmxObjects = lastTMXObjectGroup.getTMXObjects(); + final TMXObject lastTMXObject = tmxObjects.get(tmxObjects.size() - 1); + + lastTMXObject.addTMXObjectProperty(new TMXObjectProperty(pAttributes)); + } else if(this.mInObjectGroup) { + final ArrayList tmxObjectGroups = this.mTMXTiledMap.getTMXObjectGroups(); + final TMXObjectGroup lastTMXObjectGroup = tmxObjectGroups.get(tmxObjectGroups.size() - 1); + + lastTMXObjectGroup.addTMXObjectGroupProperty(new TMXObjectGroupProperty(pAttributes)); + } else if(this.mInMap) { + this.mTMXTiledMap.addTMXTiledMapProperty(new TMXTiledMapProperty(pAttributes)); + } + } else if(pLocalName.equals(TAG_LAYER)){ + this.mInLayer = true; + this.mTMXTiledMap.addTMXLayer(new TMXLayer(this.mTMXTiledMap, pAttributes)); + } else if(pLocalName.equals(TAG_DATA)){ + this.mInData = true; + this.mDataEncoding = pAttributes.getValue("", TAG_DATA_ATTRIBUTE_ENCODING); + this.mDataCompression = pAttributes.getValue("", TAG_DATA_ATTRIBUTE_COMPRESSION); + } else if(pLocalName.equals(TAG_OBJECTGROUP)){ + this.mInObjectGroup = true; + this.mTMXTiledMap.addTMXObjectGroup(new TMXObjectGroup(pAttributes)); + } else if(pLocalName.equals(TAG_OBJECT)){ + this.mInObject = true; + final ArrayList tmxObjectGroups = this.mTMXTiledMap.getTMXObjectGroups(); + tmxObjectGroups.get(tmxObjectGroups.size() - 1).addTMXObject(new TMXObject(pAttributes)); + } else { + throw new TMXParseException("Unexpected start tag: '" + pLocalName + "'."); + } + } + + @Override + public void characters(final char[] pCharacters, final int pStart, final int pLength) throws SAXException { + this.mStringBuilder.append(pCharacters, pStart, pLength); + } + + @Override + public void endElement(final String pUri, final String pLocalName, final String pQualifiedName) throws SAXException { + if(pLocalName.equals(TAG_MAP)){ + this.mInMap = false; + } else if(pLocalName.equals(TAG_TILESET)){ + this.mInTileset = false; + } else if(pLocalName.equals(TAG_IMAGE)){ + this.mInImage = false; + } else if(pLocalName.equals(TAG_TILE)) { + this.mInTile = false; + } else if(pLocalName.equals(TAG_PROPERTIES)) { + this.mInProperties = false; + } else if(pLocalName.equals(TAG_PROPERTY)) { + this.mInProperty = false; + } else if(pLocalName.equals(TAG_LAYER)){ + this.mInLayer = false; + } else if(pLocalName.equals(TAG_DATA)){ + final boolean binarySaved = this.mDataCompression != null && this.mDataEncoding != null; + if(binarySaved) { + final ArrayList tmxLayers = this.mTMXTiledMap.getTMXLayers(); + try { + tmxLayers.get(tmxLayers.size() - 1).initializeTMXTilesFromDataString(this.mStringBuilder.toString().trim(), this.mDataEncoding, this.mDataCompression, this.mTMXTilePropertyListener); + } catch (final IOException e) { + Debug.e(e); + } + this.mDataCompression = null; + this.mDataEncoding = null; + } + this.mInData = false; + } else if(pLocalName.equals(TAG_OBJECTGROUP)){ + this.mInObjectGroup = false; + } else if(pLocalName.equals(TAG_OBJECT)){ + this.mInObject = false; + } else { + throw new TMXParseException("Unexpected end tag: '" + pLocalName + "'."); + } + + /* Reset the StringBuilder. */ + this.mStringBuilder.setLength(0); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperties.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperties.java new file mode 100644 index 0000000..da5af71 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperties.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; + +/** + * @author Nicolas Gramlich + * @since 10:14:06 - 27.07.2010 + */ +public class TMXProperties extends ArrayList implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 8912773556975105201L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean containsTMXProperty(final String pName, final String pValue) { + for(int i = this.size() - 1; i >= 0; i--) { + final T tmxProperty = this.get(i); + if(tmxProperty.getName().equals(pName) && tmxProperty.getValue().equals(pValue)) { + return true; + } + } + return false; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperty.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperty.java new file mode 100644 index 0000000..12341b7 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXProperty.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 10:14:06 - 27.07.2010 + */ +public class TMXProperty implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final String mName; + private final String mValue; + + // =========================================================== + // Constructors + // =========================================================== + + public TMXProperty(final Attributes pAttributes) { + this.mName = pAttributes.getValue("", TAG_PROPERTY_ATTRIBUTE_NAME); + this.mValue = pAttributes.getValue("", TAG_PROPERTY_ATTRIBUTE_VALUE); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public String getName() { + return this.mName; + } + + public String getValue() { + return this.mValue; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public String toString() { + return this.mName + "='" + this.mValue + "'"; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTile.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTile.java new file mode 100644 index 0000000..2f42a68 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTile.java @@ -0,0 +1,107 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.anddev.andengine.opengl.texture.region.TextureRegion; + +/** + * @author Nicolas Gramlich + * @since 10:39:48 - 05.08.2010 + */ +public class TMXTile { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + int mGlobalTileID; + private final int mTileRow; + private final int mTileColumn; + private final int mTileWidth; + private final int mTileHeight; + TextureRegion mTextureRegion; + + // =========================================================== + // Constructors + // =========================================================== + + public TMXTile(final int pGlobalTileID, final int pTileColumn, final int pTileRow, final int pTileWidth, final int pTileHeight, final TextureRegion pTextureRegion) { + this.mGlobalTileID = pGlobalTileID; + this.mTileRow = pTileRow; + this.mTileColumn = pTileColumn; + this.mTileWidth = pTileWidth; + this.mTileHeight = pTileHeight; + this.mTextureRegion = pTextureRegion; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getGlobalTileID() { + return this.mGlobalTileID; + } + + public int getTileRow() { + return this.mTileRow; + } + + public int getTileColumn() { + return this.mTileColumn; + } + + public int getTileX() { + return this.mTileColumn * this.mTileWidth; + } + + public int getTileY() { + return this.mTileRow * this.mTileHeight; + } + + public int getTileWidth() { + return this.mTileWidth; + } + + public int getTileHeight() { + return this.mTileHeight; + } + + public TextureRegion getTextureRegion() { + return this.mTextureRegion; + } + + /** + * Note this will also set the {@link TextureRegion} with the associated pGlobalTileID of the {@link TMXTiledMap}. + * @param pTMXTiledMap + * @param pGlobalTileID + */ + public void setGlobalTileID(final TMXTiledMap pTMXTiledMap, final int pGlobalTileID) { + this.mGlobalTileID = pGlobalTileID; + this.mTextureRegion = pTMXTiledMap.getTextureRegionFromGlobalTileID(pGlobalTileID); + } + + /** + * You'd probably want to call {@link TMXTile#setGlobalTileID(TMXTiledMap, int)} instead. + * @param pTextureRegion + */ + public void setTextureRegion(final TextureRegion pTextureRegion) { + this.mTextureRegion = pTextureRegion; + } + + public TMXProperties getTMXTileProperties(final TMXTiledMap pTMXTiledMap) { + return pTMXTiledMap.getTMXTileProperties(this.mGlobalTileID); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileProperty.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileProperty.java new file mode 100644 index 0000000..ee7c1d5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileProperty.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 11:20:09 - 29.07.2010 + */ +public class TMXTileProperty extends TMXProperty { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXTileProperty(final Attributes pAttributes) { + super(pAttributes); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileSet.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileSet.java new file mode 100644 index 0000000..ee05c7e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTileSet.java @@ -0,0 +1,177 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXParseException; +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.TextureFactory; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.texture.region.TextureRegionFactory; +import org.anddev.andengine.opengl.texture.source.AssetTextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.ColorKeyTextureSourceDecorator; +import org.anddev.andengine.opengl.texture.source.decorator.shape.RectangleTextureSourceDecoratorShape; +import org.anddev.andengine.util.SAXUtils; +import org.xml.sax.Attributes; + +import android.content.Context; +import android.graphics.Color; +import android.util.SparseArray; + +/** + * @author Nicolas Gramlich + * @since 19:03:24 - 20.07.2010 + */ +public class TMXTileSet implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mFirstGlobalTileID; + private final String mName; + private final int mTileWidth; + private final int mTileHeight; + + private String mImageSource; + private Texture mTexture; + private final TextureOptions mTextureOptions; + + private int mTilesHorizontal; + @SuppressWarnings("unused") + private int mTilesVertical; + + private final int mSpacing; + private final int mMargin; + + private final SparseArray> mTMXTileProperties = new SparseArray>(); + // =========================================================== + // Constructors + // =========================================================== + + TMXTileSet(final Attributes pAttributes, final TextureOptions pTextureOptions) { + this(SAXUtils.getIntAttribute(pAttributes, TAG_TILESET_ATTRIBUTE_FIRSTGID, 1), pAttributes, pTextureOptions); + } + + TMXTileSet(final int pFirstGlobalTileID, final Attributes pAttributes, final TextureOptions pTextureOptions) { + this.mFirstGlobalTileID = SAXUtils.getIntAttribute(pAttributes, TAG_TILESET_ATTRIBUTE_FIRSTGID, 1); + this.mName = pAttributes.getValue("", TAG_TILESET_ATTRIBUTE_NAME); + this.mTileWidth = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_TILESET_ATTRIBUTE_TILEWIDTH); + this.mTileHeight = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_TILESET_ATTRIBUTE_TILEHEIGHT); + this.mSpacing = SAXUtils.getIntAttribute(pAttributes, TAG_TILESET_ATTRIBUTE_SPACING, 0); + this.mMargin = SAXUtils.getIntAttribute(pAttributes, TAG_TILESET_ATTRIBUTE_MARGIN, 0); + + this.mTextureOptions = pTextureOptions; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public final int getFirstGlobalTileID() { + return this.mFirstGlobalTileID; + } + + public final String getName() { + return this.mName; + } + + public final int getTileWidth() { + return this.mTileWidth; + } + + public final int getTileHeight() { + return this.mTileHeight; + } + + public Texture getTexture() { + return this.mTexture; + } + + public void setImageSource(final Context pContext, final TextureManager pTextureManager, final Attributes pAttributes) throws TMXParseException { + this.mImageSource = pAttributes.getValue("", TAG_IMAGE_ATTRIBUTE_SOURCE); + + final AssetTextureSource assetTextureSource = new AssetTextureSource(pContext, this.mImageSource); + this.mTilesHorizontal = TMXTileSet.determineCount(assetTextureSource.getWidth(), this.mTileWidth, this.mMargin, this.mSpacing); + this.mTilesVertical = TMXTileSet.determineCount(assetTextureSource.getHeight(), this.mTileHeight, this.mMargin, this.mSpacing); + this.mTexture = TextureFactory.createForTextureSourceSize(assetTextureSource, this.mTextureOptions); + + final String transparentColor = SAXUtils.getAttribute(pAttributes, TAG_IMAGE_ATTRIBUTE_TRANS, null); + if(transparentColor == null) { + TextureRegionFactory.createFromSource(this.mTexture, assetTextureSource, 0, 0); + } else { + try{ + final int color = Color.parseColor((transparentColor.startsWith("#")) ? transparentColor : "#" + transparentColor); + TextureRegionFactory.createFromSource(this.mTexture, new ColorKeyTextureSourceDecorator(assetTextureSource, RectangleTextureSourceDecoratorShape.getDefaultInstance(), color), 0, 0); + } catch (final IllegalArgumentException e) { + throw new TMXParseException("Illegal value: '" + transparentColor + "' for attribute 'trans' supplied!", e); + } + } + pTextureManager.loadTexture(this.mTexture); + } + + public String getImageSource() { + return this.mImageSource; + } + + public SparseArray> getTMXTileProperties() { + return this.mTMXTileProperties; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public TMXProperties getTMXTilePropertiesFromGlobalTileID(final int pGlobalTileID) { + final int localTileID = pGlobalTileID - this.mFirstGlobalTileID; + return this.mTMXTileProperties.get(localTileID); + } + + public void addTMXTileProperty(final int pLocalTileID, final TMXTileProperty pTMXTileProperty) { + final TMXProperties existingProperties = this.mTMXTileProperties.get(pLocalTileID); + if(existingProperties != null) { + existingProperties.add(pTMXTileProperty); + } else { + final TMXProperties newProperties = new TMXProperties(); + newProperties.add(pTMXTileProperty); + this.mTMXTileProperties.put(pLocalTileID, newProperties); + } + } + + public TextureRegion getTextureRegionFromGlobalTileID(final int pGlobalTileID) { + final int localTileID = pGlobalTileID - this.mFirstGlobalTileID; + final int tileColumn = localTileID % this.mTilesHorizontal; + final int tileRow = localTileID / this.mTilesHorizontal; + + final int texturePositionX = this.mMargin + (this.mSpacing + this.mTileWidth) * tileColumn; + final int texturePositionY = this.mMargin + (this.mSpacing + this.mTileHeight) * tileRow; + + return new TextureRegion(this.mTexture, texturePositionX, texturePositionY, this.mTileWidth, this.mTileHeight); + } + + private static int determineCount(final int pTotalExtent, final int pTileExtent, final int pMargin, final int pSpacing) { + int count = 0; + int remainingExtent = pTotalExtent; + + remainingExtent -= pMargin * 2; + + while(remainingExtent > 0) { + remainingExtent -= pTileExtent; + remainingExtent -= pSpacing; + count++; + } + + return count; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMap.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMap.java new file mode 100644 index 0000000..f07b49d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMap.java @@ -0,0 +1,198 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; +import org.anddev.andengine.util.SAXUtils; +import org.xml.sax.Attributes; + +import android.util.SparseArray; + +/** + * @author Nicolas Gramlich + * @since 19:38:11 - 20.07.2010 + */ +public class TMXTiledMap implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final String mOrientation; + private final int mTileColumns; + private final int mTilesRows; + private final int mTileWidth; + private final int mTileHeight; + + private final ArrayList mTMXTileSets = new ArrayList(); + private final ArrayList mTMXLayers = new ArrayList(); + private final ArrayList mTMXObjectGroups = new ArrayList(); + + private final RectangleVertexBuffer mSharedVertexBuffer; + + private final SparseArray mGlobalTileIDToTextureRegionCache = new SparseArray(); + private final SparseArray> mGlobalTileIDToTMXTilePropertiesCache = new SparseArray>(); + + private final TMXProperties mTMXTiledMapProperties = new TMXProperties(); + + // =========================================================== + // Constructors + // =========================================================== + + TMXTiledMap(final Attributes pAttributes) { + this.mOrientation = pAttributes.getValue("", TAG_MAP_ATTRIBUTE_ORIENTATION); + if(this.mOrientation.equals(TAG_MAP_ATTRIBUTE_ORIENTATION_VALUE_ORTHOGONAL) == false) { + throw new IllegalArgumentException(TAG_MAP_ATTRIBUTE_ORIENTATION + ": '" + this.mOrientation + "' is not supported."); + } + this.mTileColumns = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_MAP_ATTRIBUTE_WIDTH); + this.mTilesRows = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_MAP_ATTRIBUTE_HEIGHT); + this.mTileWidth = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_MAP_ATTRIBUTE_TILEWIDTH); + this.mTileHeight = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_MAP_ATTRIBUTE_TILEHEIGHT); + + this.mSharedVertexBuffer = new RectangleVertexBuffer(GL11.GL_STATIC_DRAW); + BufferObjectManager.getActiveInstance().loadBufferObject(this.mSharedVertexBuffer); + this.mSharedVertexBuffer.update(this.mTileWidth, this.mTileHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public final String getOrientation() { + return this.mOrientation; + } + /** + * @deprecated Instead use {@link TMXTiledMap#getTileColumns()} * {@link TMXTiledMap#getTileWidth()}. + * @return + */ + @Deprecated + public final int getWidth() { + return this.mTileColumns; + } + + public final int getTileColumns() { + return this.mTileColumns; + } + + /** + * @deprecated Instead use {@link TMXTiledMap#getTileRows()} * {@link TMXTiledMap#getTileHeight()}. + * @return + */ + @Deprecated + public final int getHeight() { + return this.mTilesRows; + } + + public final int getTileRows() { + return this.mTilesRows; + } + + public final int getTileWidth() { + return this.mTileWidth; + } + + public final int getTileHeight() { + return this.mTileHeight; + } + + public RectangleVertexBuffer getSharedVertexBuffer() { + return this.mSharedVertexBuffer; + } + + void addTMXTileSet(final TMXTileSet pTMXTileSet) { + this.mTMXTileSets.add(pTMXTileSet); + } + + public ArrayList getTMXTileSets() { + return this.mTMXTileSets; + } + + void addTMXLayer(final TMXLayer pTMXLayer) { + this.mTMXLayers.add(pTMXLayer); + } + + public ArrayList getTMXLayers() { + return this.mTMXLayers; + } + + void addTMXObjectGroup(final TMXObjectGroup pTMXObjectGroup) { + this.mTMXObjectGroups.add(pTMXObjectGroup); + } + + public ArrayList getTMXObjectGroups() { + return this.mTMXObjectGroups; + } + + public TMXProperties getTMXTilePropertiesByGlobalTileID(final int pGlobalTileID) { + return this.mGlobalTileIDToTMXTilePropertiesCache.get(pGlobalTileID); + } + + public void addTMXTiledMapProperty(final TMXTiledMapProperty pTMXTiledMapProperty) { + this.mTMXTiledMapProperties.add(pTMXTiledMapProperty); + } + + public TMXProperties getTMXTiledMapProperties() { + return this.mTMXTiledMapProperties; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public TMXProperties getTMXTileProperties(final int pGlobalTileID) { + final SparseArray> globalTileIDToTMXTilePropertiesCache = this.mGlobalTileIDToTMXTilePropertiesCache; + + final TMXProperties cachedTMXTileProperties = globalTileIDToTMXTilePropertiesCache.get(pGlobalTileID); + if(cachedTMXTileProperties != null) { + return cachedTMXTileProperties; + } else { + final ArrayList tmxTileSets = this.mTMXTileSets; + + for(int i = tmxTileSets.size() - 1; i >= 0; i--) { + final TMXTileSet tmxTileSet = tmxTileSets.get(i); + if(pGlobalTileID >= tmxTileSet.getFirstGlobalTileID()) { + return tmxTileSet.getTMXTilePropertiesFromGlobalTileID(pGlobalTileID); + } + } + throw new IllegalArgumentException("No TMXTileProperties found for pGlobalTileID=" + pGlobalTileID); + } + } + + public TextureRegion getTextureRegionFromGlobalTileID(final int pGlobalTileID) { + final SparseArray globalTileIDToTextureRegionCache = this.mGlobalTileIDToTextureRegionCache; + + final TextureRegion cachedTextureRegion = globalTileIDToTextureRegionCache.get(pGlobalTileID); + if(cachedTextureRegion != null) { + return cachedTextureRegion; + } else { + final ArrayList tmxTileSets = this.mTMXTileSets; + + for(int i = tmxTileSets.size() - 1; i >= 0; i--) { + final TMXTileSet tmxTileSet = tmxTileSets.get(i); + if(pGlobalTileID >= tmxTileSet.getFirstGlobalTileID()) { + final TextureRegion textureRegion = tmxTileSet.getTextureRegionFromGlobalTileID(pGlobalTileID); + /* Add to cache for the all future pGlobalTileIDs with the same value. */ + globalTileIDToTextureRegionCache.put(pGlobalTileID, textureRegion); + return textureRegion; + } + } + throw new IllegalArgumentException("No TextureRegion found for pGlobalTileID=" + pGlobalTileID); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMapProperty.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMapProperty.java new file mode 100644 index 0000000..832860b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TMXTiledMapProperty.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 18:48:41 - 12.10.2010 + */ +public class TMXTiledMapProperty extends TMXProperty { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXTiledMapProperty(final Attributes pAttributes) { + super(pAttributes); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXLoader.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXLoader.java new file mode 100644 index 0000000..13648a4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXLoader.java @@ -0,0 +1,92 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TSXLoadException; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import android.content.Context; + +/** + * @author Nicolas Gramlich + * @since 17:18:37 - 08.08.2010 + */ +public class TSXLoader { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Context mContext; + private final TextureManager mTextureManager; + private final TextureOptions mTextureOptions; + + // =========================================================== + // Constructors + // =========================================================== + + public TSXLoader(final Context pContext, final TextureManager pTextureManager, final TextureOptions pTextureOptions) { + this.mContext = pContext; + this.mTextureManager = pTextureManager; + this.mTextureOptions = pTextureOptions; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public TMXTileSet loadFromAsset(final Context pContext, final int pFirstGlobalTileID, final String pAssetPath) throws TSXLoadException { + try { + return this.load(pFirstGlobalTileID, pContext.getAssets().open(pAssetPath)); + } catch (final IOException e) { + throw new TSXLoadException("Could not load TMXTileSet from asset: " + pAssetPath, e); + } + } + + private TMXTileSet load(final int pFirstGlobalTileID, final InputStream pInputStream) throws TSXLoadException { + try{ + final SAXParserFactory spf = SAXParserFactory.newInstance(); + final SAXParser sp = spf.newSAXParser(); + + final XMLReader xr = sp.getXMLReader(); + final TSXParser tsxParser = new TSXParser(this.mContext, this.mTextureManager, this.mTextureOptions, pFirstGlobalTileID); + xr.setContentHandler(tsxParser); + + xr.parse(new InputSource(new BufferedInputStream(pInputStream))); + + return tsxParser.getTMXTileSet(); + } catch (final SAXException e) { + throw new TSXLoadException(e); + } catch (final ParserConfigurationException pe) { + /* Doesn't happen. */ + return null; + } catch (final IOException e) { + throw new TSXLoadException(e); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXParser.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXParser.java new file mode 100644 index 0000000..47f6f59 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/TSXParser.java @@ -0,0 +1,115 @@ +package org.anddev.andengine.entity.layer.tiled.tmx; + +import org.anddev.andengine.entity.layer.tiled.tmx.util.constants.TMXConstants; +import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXParseException; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.anddev.andengine.util.SAXUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import android.content.Context; + +/** + * @author Nicolas Gramlich + * @since 18:37:32 - 08.08.2010 + */ +public class TSXParser extends DefaultHandler implements TMXConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Context mContext; + private final TextureManager mTextureManager; + private final TextureOptions mTextureOptions; + + private TMXTileSet mTMXTileSet; + + private int mLastTileSetTileID; + + @SuppressWarnings("unused") + private boolean mInTileset; + @SuppressWarnings("unused") + private boolean mInImage; + @SuppressWarnings("unused") + private boolean mInTile; + @SuppressWarnings("unused") + private boolean mInProperties; + @SuppressWarnings("unused") + private boolean mInProperty; + private final int mFirstGlobalTileID; + + // =========================================================== + // Constructors + // =========================================================== + + public TSXParser(final Context pContext, final TextureManager pTextureManager, final TextureOptions pTextureOptions, final int pFirstGlobalTileID) { + this.mContext = pContext; + this.mTextureManager = pTextureManager; + this.mTextureOptions = pTextureOptions; + this.mFirstGlobalTileID = pFirstGlobalTileID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + TMXTileSet getTMXTileSet() { + return this.mTMXTileSet; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void startElement(final String pUri, final String pLocalName, final String pQualifiedName, final Attributes pAttributes) throws SAXException { + if(pLocalName.equals(TAG_TILESET)){ + this.mInTileset = true; + this.mTMXTileSet = new TMXTileSet(this.mFirstGlobalTileID, pAttributes, this.mTextureOptions); + } else if(pLocalName.equals(TAG_IMAGE)){ + this.mInImage = true; + this.mTMXTileSet.setImageSource(this.mContext, this.mTextureManager, pAttributes); + } else if(pLocalName.equals(TAG_TILE)) { + this.mInTile = true; + this.mLastTileSetTileID = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_TILE_ATTRIBUTE_ID); + } else if(pLocalName.equals(TAG_PROPERTIES)) { + this.mInProperties = true; + } else if(pLocalName.equals(TAG_PROPERTY)) { + this.mInProperty = true; + this.mTMXTileSet.addTMXTileProperty(this.mLastTileSetTileID, new TMXTileProperty(pAttributes)); + } else { + throw new TMXParseException("Unexpected start tag: '" + pLocalName + "'."); + } + } + + @Override + public void endElement(final String pUri, final String pLocalName, final String pQualifiedName) throws SAXException { + if(pLocalName.equals(TAG_TILESET)){ + this.mInTileset = false; + } else if(pLocalName.equals(TAG_IMAGE)){ + this.mInImage = false; + } else if(pLocalName.equals(TAG_TILE)) { + this.mInTile = false; + } else if(pLocalName.equals(TAG_PROPERTIES)) { + this.mInProperties = false; + } else if(pLocalName.equals(TAG_PROPERTY)) { + this.mInProperty = false; + } else { + throw new TMXParseException("Unexpected end tag: '" + pLocalName + "'."); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/TMXConstants.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/TMXConstants.java new file mode 100644 index 0000000..0542684 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/constants/TMXConstants.java @@ -0,0 +1,81 @@ +package org.anddev.andengine.entity.layer.tiled.tmx.util.constants; + +/** + * See: TMX Map Format. + * + * @author Nicolas Gramlich + * @since 19:20:22 - 20.07.2010 + */ +public interface TMXConstants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final int BYTES_PER_GLOBALTILEID = 4; + + public static final String TAG_MAP = "map"; + public static final String TAG_MAP_ATTRIBUTE_ORIENTATION = "orientation"; + public static final String TAG_MAP_ATTRIBUTE_ORIENTATION_VALUE_ORTHOGONAL = "orthogonal"; + public static final String TAG_MAP_ATTRIBUTE_ORIENTATION_VALUE_ISOMETRIC = "isometric"; + public static final String TAG_MAP_ATTRIBUTE_WIDTH = "width"; + public static final String TAG_MAP_ATTRIBUTE_HEIGHT = "height"; + public static final String TAG_MAP_ATTRIBUTE_TILEWIDTH = "tilewidth"; + public static final String TAG_MAP_ATTRIBUTE_TILEHEIGHT = "tileheight"; + + public static final String TAG_TILESET = "tileset"; + public static final String TAG_TILESET_ATTRIBUTE_FIRSTGID = "firstgid"; + public static final String TAG_TILESET_ATTRIBUTE_SOURCE = "source"; + public static final String TAG_TILESET_ATTRIBUTE_NAME = "name"; + public static final String TAG_TILESET_ATTRIBUTE_TILEWIDTH = "tilewidth"; + public static final String TAG_TILESET_ATTRIBUTE_TILEHEIGHT = "tileheight"; + public static final String TAG_TILESET_ATTRIBUTE_SPACING = "spacing"; + public static final String TAG_TILESET_ATTRIBUTE_MARGIN = "margin"; + + public static final String TAG_IMAGE = "image"; + public static final String TAG_IMAGE_ATTRIBUTE_SOURCE = "source"; + public static final String TAG_IMAGE_ATTRIBUTE_TRANS = "trans"; + + public static final String TAG_TILE = "tile"; + public static final String TAG_TILE_ATTRIBUTE_ID = "id"; + public static final String TAG_TILE_ATTRIBUTE_GID = "gid"; + + public static final String TAG_PROPERTIES = "properties"; + + public static final String TAG_PROPERTY = "property"; + public static final String TAG_PROPERTY_ATTRIBUTE_NAME = "name"; + public static final String TAG_PROPERTY_ATTRIBUTE_VALUE = "value"; + + public static final String TAG_LAYER = "layer"; + public static final String TAG_LAYER_ATTRIBUTE_NAME = "name"; + public static final String TAG_LAYER_ATTRIBUTE_WIDTH = "width"; + public static final String TAG_LAYER_ATTRIBUTE_HEIGHT = "height"; + public static final String TAG_LAYER_ATTRIBUTE_VISIBLE = "visible"; + public static final int TAG_LAYER_ATTRIBUTE_VISIBLE_VALUE_DEFAULT = 1; + public static final String TAG_LAYER_ATTRIBUTE_OPACITY = "opacity"; + public static final float TAG_LAYER_ATTRIBUTE_OPACITY_VALUE_DEFAULT = 1.0f; + + public static final String TAG_DATA = "data"; + public static final String TAG_DATA_ATTRIBUTE_ENCODING = "encoding"; + public static final String TAG_DATA_ATTRIBUTE_ENCODING_VALUE_BASE64 = "base64"; + public static final String TAG_DATA_ATTRIBUTE_COMPRESSION = "compression"; + public static final String TAG_DATA_ATTRIBUTE_COMPRESSION_VALUE_GZIP = "gzip"; + public static final String TAG_DATA_ATTRIBUTE_COMPRESSION_VALUE_ZLIB = "zlib"; + + + public static final String TAG_OBJECTGROUP = "objectgroup"; + public static final String TAG_OBJECTGROUP_ATTRIBUTE_NAME = "name"; + public static final String TAG_OBJECTGROUP_ATTRIBUTE_WIDTH = "width"; + public static final String TAG_OBJECTGROUP_ATTRIBUTE_HEIGHT = "height"; + + public static final String TAG_OBJECT = "object"; + public static final String TAG_OBJECT_ATTRIBUTE_NAME = "name"; + public static final String TAG_OBJECT_ATTRIBUTE_TYPE = "type"; + public static final String TAG_OBJECT_ATTRIBUTE_X = "x"; + public static final String TAG_OBJECT_ATTRIBUTE_Y = "y"; + public static final String TAG_OBJECT_ATTRIBUTE_WIDTH = "width"; + public static final String TAG_OBJECT_ATTRIBUTE_HEIGHT = "height"; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXException.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXException.java new file mode 100644 index 0000000..d5e4f6f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXException.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.entity.layer.tiled.tmx.util.exception; + +/** + * @author Nicolas Gramlich + * @since 17:20:25 - 08.08.2010 + */ +public abstract class TMXException extends Exception { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 337819550394833109L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXException() { + super(); + } + + public TMXException(final String pDetailMessage, final Throwable pThrowable) { + super(pDetailMessage, pThrowable); + } + + public TMXException(final String pDetailMessage) { + super(pDetailMessage); + } + + public TMXException(final Throwable pThrowable) { + super(pThrowable); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXLoadException.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXLoadException.java new file mode 100644 index 0000000..5c32e15 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXLoadException.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.entity.layer.tiled.tmx.util.exception; + +/** + * @author Nicolas Gramlich + * @since 00:10:02 - 28.07.2010 + */ +public class TMXLoadException extends TMXException { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = -8295358631698809883L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXLoadException() { + super(); + } + + public TMXLoadException(final String pDetailMessage, final Throwable pThrowable) { + super(pDetailMessage, pThrowable); + } + + public TMXLoadException(final String pDetailMessage) { + super(pDetailMessage); + } + + public TMXLoadException(final Throwable pThrowable) { + super(pThrowable); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXParseException.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXParseException.java new file mode 100644 index 0000000..2d94f66 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TMXParseException.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.layer.tiled.tmx.util.exception; + +import org.xml.sax.SAXException; + +/** + * @author Nicolas Gramlich + * @since 00:10:02 - 28.07.2010 + */ +public class TMXParseException extends SAXException { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 2213964295487921492L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TMXParseException() { + super(); + } + + public TMXParseException(final String pDetailMessage) { + super(pDetailMessage); + } + + public TMXParseException(final Exception pException) { + super(pException); + } + + public TMXParseException(final String pMessage, final Exception pException) { + super(pMessage, pException); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXLoadException.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXLoadException.java new file mode 100644 index 0000000..c2d6f3a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXLoadException.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.entity.layer.tiled.tmx.util.exception; + +/** + * @author Nicolas Gramlich + * @since 18:37:53 - 08.08.2010 + */ +public class TSXLoadException extends TMXException { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 10055223972707703L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TSXLoadException() { + super(); + } + + public TSXLoadException(final String pDetailMessage, final Throwable pThrowable) { + super(pDetailMessage, pThrowable); + } + + public TSXLoadException(final String pDetailMessage) { + super(pDetailMessage); + } + + public TSXLoadException(final Throwable pThrowable) { + super(pThrowable); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXParseException.java b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXParseException.java new file mode 100644 index 0000000..2265725 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/layer/tiled/tmx/util/exception/TSXParseException.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.layer.tiled.tmx.util.exception; + +import org.xml.sax.SAXException; + +/** + * @author Nicolas Gramlich + * @since 18:37:46 - 08.08.2010 + */ +public class TSXParseException extends SAXException { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = -7598783248970268198L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TSXParseException() { + super(); + } + + public TSXParseException(final String pDetailMessage) { + super(pDetailMessage); + } + + public TSXParseException(final Exception pException) { + super(pException); + } + + public TSXParseException(final String pMessage, final Exception pException) { + super(pMessage, pException); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/AlphaModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/AlphaModifier.java new file mode 100644 index 0000000..ea1ca11 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/AlphaModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 23:13:01 - 19.03.2010 + */ +public class AlphaModifier extends SingleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public AlphaModifier(final float pDuration, final float pFromAlpha, final float pToAlpha) { + this(pDuration, pFromAlpha, pToAlpha, null, IEaseFunction.DEFAULT); + } + + public AlphaModifier(final float pDuration, final float pFromAlpha, final float pToAlpha, final IEaseFunction pEaseFunction) { + this(pDuration, pFromAlpha, pToAlpha, null, pEaseFunction); + } + + public AlphaModifier(final float pDuration, final float pFromAlpha, final float pToAlpha, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromAlpha, pToAlpha, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public AlphaModifier(final float pDuration, final float pFromAlpha, final float pToAlpha, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromAlpha, pToAlpha, pEntityModifierListener, pEaseFunction); + } + + protected AlphaModifier(final AlphaModifier pAlphaModifier) { + super(pAlphaModifier); + } + + @Override + public AlphaModifier clone(){ + return new AlphaModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValue(final IEntity pEntity, final float pAlpha) { + pEntity.setAlpha(pAlpha); + } + + @Override + protected void onSetValue(final IEntity pEntity, final float pPercentageDone, final float pAlpha) { + pEntity.setAlpha(pAlpha); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/ColorModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/ColorModifier.java new file mode 100644 index 0000000..30368aa --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/ColorModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 15:39:50 - 29.06.2010 + */ +public class ColorModifier extends TripleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue) { + this(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, null, IEaseFunction.DEFAULT); + } + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final IEaseFunction pEaseFunction) { + this(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, null, pEaseFunction); + } + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, pEntityModifierListener, pEaseFunction); + } + + protected ColorModifier(final ColorModifier pColorModifier) { + super(pColorModifier); + } + + @Override + public ColorModifier clone(){ + return new ColorModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValues(final IEntity pEntity, final float pRed, final float pGreen, final float pBlue) { + pEntity.setColor(pRed, pGreen, pBlue); + } + + @Override + protected void onSetValues(final IEntity pEntity, final float pPerctentageDone, final float pRed, final float pGreen, final float pBlue) { + pEntity.setColor(pRed, pGreen, pBlue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/DelayModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/DelayModifier.java new file mode 100644 index 0000000..6f54ce1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/DelayModifier.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; + +/** + * @author Nicolas Gramlich + * @since 22:55:13 - 19.03.2010 + */ +public class DelayModifier extends DurationShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public DelayModifier(final float pDuration, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pEntityModifierListener); + } + + public DelayModifier(final float pDuration) { + super(pDuration); + } + + protected DelayModifier(final DelayModifier pDelayModifier) { + super(pDelayModifier); + } + + @Override + public DelayModifier clone(){ + return new DelayModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedInitialize(final IEntity pEntity) { + + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed, final IEntity pEntity) { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/DoubleValueSpanShapeModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/DoubleValueSpanShapeModifier.java new file mode 100644 index 0000000..7bd40f9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/DoubleValueSpanShapeModifier.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.BaseDoubleValueSpanModifier; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 23:29:22 - 19.03.2010 + */ +public abstract class DoubleValueSpanShapeModifier extends BaseDoubleValueSpanModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public DoubleValueSpanShapeModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB); + } + + public DoubleValueSpanShapeModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pEaseFunction); + } + + public DoubleValueSpanShapeModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pEntityModifierListener); + } + + public DoubleValueSpanShapeModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pEntityModifierListener, pEaseFunction); + } + + protected DoubleValueSpanShapeModifier(final DoubleValueSpanShapeModifier pDoubleValueSpanModifier) { + super(pDoubleValueSpanModifier); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/DurationShapeModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/DurationShapeModifier.java new file mode 100644 index 0000000..19b46bb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/DurationShapeModifier.java @@ -0,0 +1,54 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.BaseDurationModifier; + +/** + * @author Nicolas Gramlich + * @since 16:10:42 - 19.03.2010 + */ +public abstract class DurationShapeModifier extends BaseDurationModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public DurationShapeModifier() { + super(); + } + + public DurationShapeModifier(final float pDuration) { + super(pDuration); + } + + public DurationShapeModifier(final float pDuration, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pEntityModifierListener); + } + + protected DurationShapeModifier(final DurationShapeModifier pDurationShapeModifier) { + super(pDurationShapeModifier); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/EntityModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/EntityModifier.java new file mode 100644 index 0000000..2c584e6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/EntityModifier.java @@ -0,0 +1,50 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.BaseModifier; + +/** + * @author Nicolas Gramlich + * @since 10:53:16 - 03.09.2010 + */ +public abstract class EntityModifier extends BaseModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public EntityModifier() { + super(); + } + + public EntityModifier(final IEntityModifierListener pEntityModifierListener) { + super(pEntityModifierListener); + } + + protected EntityModifier(final EntityModifier pEntityModifier) { + super(pEntityModifier); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/EntityModifierList.java b/AndEngine/src/org/anddev/andengine/entity/modifier/EntityModifierList.java new file mode 100644 index 0000000..9499623 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/EntityModifierList.java @@ -0,0 +1,48 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ModifierList; + +/** + * @author Nicolas Gramlich + * @since 14:19:18 - 24.12.2010 + */ +public class EntityModifierList extends ModifierList { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 161652765736600082L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public EntityModifierList(final IEntity pTarget) { + super(pTarget); + } + + public EntityModifierList(final IEntity pTarget, final int pCapacity) { + super(pTarget, pCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/FadeInModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/FadeInModifier.java new file mode 100644 index 0000000..afac975 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/FadeInModifier.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + + +/** + * @author Nicolas Gramlich + * @since 19:03:12 - 08.06.2010 + */ +public class FadeInModifier extends AlphaModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public FadeInModifier(final float pDuration) { + super(pDuration, 0.0f, 1.0f, IEaseFunction.DEFAULT); + } + + public FadeInModifier(final float pDuration, final IEaseFunction pEaseFunction) { + super(pDuration, 0.0f, 1.0f, pEaseFunction); + } + + public FadeInModifier(final float pDuration, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, 0.0f, 1.0f, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public FadeInModifier(final float pDuration, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, 0.0f, 1.0f, pEntityModifierListener, pEaseFunction); + } + + protected FadeInModifier(final FadeInModifier pFadeInModifier) { + super(pFadeInModifier); + } + + @Override + public FadeInModifier clone() { + return new FadeInModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/FadeOutModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/FadeOutModifier.java new file mode 100644 index 0000000..ace0648 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/FadeOutModifier.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + + +/** + * @author Nicolas Gramlich + * @since 19:03:12 - 08.06.2010 + */ +public class FadeOutModifier extends AlphaModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public FadeOutModifier(final float pDuration) { + super(pDuration, 1.0f, 0.0f, IEaseFunction.DEFAULT); + } + + public FadeOutModifier(final float pDuration, final IEaseFunction pEaseFunction) { + super(pDuration, 1.0f, 0.0f, pEaseFunction); + } + + public FadeOutModifier(final float pDuration, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, 1.0f, 0.0f, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public FadeOutModifier(final float pDuration, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, 1.0f, 0.0f, pEntityModifierListener, pEaseFunction); + } + + protected FadeOutModifier(final FadeOutModifier pFadeOutModifier) { + super(pFadeOutModifier); + } + + @Override + public FadeOutModifier clone() { + return new FadeOutModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/IEntityModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/IEntityModifier.java new file mode 100644 index 0000000..8ccf302 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/IEntityModifier.java @@ -0,0 +1,43 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.IMatcher; +import org.anddev.andengine.util.modifier.IModifier; + +/** + * @author Nicolas Gramlich + * @since 11:17:50 - 19.03.2010 + */ +public interface IEntityModifier extends IModifier { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IEntityModifierListener extends IModifierListener{ + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } + + public interface IEntityModifierMatcher extends IMatcher> { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/LoopEntityModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/LoopEntityModifier.java new file mode 100644 index 0000000..b9f3d7b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/LoopEntityModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.LoopModifier; + +/** + * @author Nicolas Gramlich + * @since 12:42:13 - 03.09.2010 + */ +public class LoopEntityModifier extends LoopModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public LoopEntityModifier(final IEntityModifier pEntityModifier) { + super(pEntityModifier); + } + + public LoopEntityModifier(final IEntityModifierListener pEntityModifierListener, final int pLoopCount, final ILoopEntityModifierListener pLoopModifierListener, final IEntityModifier pEntityModifier) { + super(pEntityModifierListener, pLoopCount, pLoopModifierListener, pEntityModifier); + } + + public LoopEntityModifier(final IEntityModifierListener pEntityModifierListener, final int pLoopCount, final IEntityModifier pEntityModifier) { + super(pEntityModifierListener, pLoopCount, pEntityModifier); + } + + public LoopEntityModifier(final int pLoopCount, final IEntityModifier pEntityModifier) { + super(pLoopCount, pEntityModifier); + } + + protected LoopEntityModifier(final LoopEntityModifier pLoopEntityModifier) { + super(pLoopEntityModifier); + } + + @Override + public LoopEntityModifier clone() { + return new LoopEntityModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ILoopEntityModifierListener extends ILoopModifierListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/MoveModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/MoveModifier.java new file mode 100644 index 0000000..0afd687 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/MoveModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 16:12:52 - 19.03.2010 + */ +public class MoveModifier extends DoubleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public MoveModifier(final float pDuration, final float pFromX, final float pToX, final float pFromY, final float pToY) { + this(pDuration, pFromX, pToX, pFromY, pToY, null, IEaseFunction.DEFAULT); + } + + public MoveModifier(final float pDuration, final float pFromX, final float pToX, final float pFromY, final float pToY, final IEaseFunction pEaseFunction) { + this(pDuration, pFromX, pToX, pFromY, pToY, null, pEaseFunction); + } + + public MoveModifier(final float pDuration, final float pFromX, final float pToX, final float pFromY, final float pToY, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromX, pToX, pFromY, pToY, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public MoveModifier(final float pDuration, final float pFromX, final float pToX, final float pFromY, final float pToY, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromX, pToX, pFromY, pToY, pEntityModifierListener, pEaseFunction); + } + + protected MoveModifier(final MoveModifier pMoveModifier) { + super(pMoveModifier); + } + + @Override + public MoveModifier clone(){ + return new MoveModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValues(final IEntity pEntity, final float pX, final float pY) { + pEntity.setPosition(pX, pY); + } + + @Override + protected void onSetValues(final IEntity pEntity, final float pPercentageDone, final float pX, final float pY) { + pEntity.setPosition(pX, pY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/MoveXModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/MoveXModifier.java new file mode 100644 index 0000000..2c254ac --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/MoveXModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 12:03:22 - 30.08.2010 + */ +public class MoveXModifier extends SingleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public MoveXModifier(final float pDuration, final float pFromX, final float pToX) { + this(pDuration, pFromX, pToX, null, IEaseFunction.DEFAULT); + } + + public MoveXModifier(final float pDuration, final float pFromX, final float pToX, final IEaseFunction pEaseFunction) { + this(pDuration, pFromX, pToX, null, pEaseFunction); + } + + public MoveXModifier(final float pDuration, final float pFromX, final float pToX, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromX, pToX, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public MoveXModifier(final float pDuration, final float pFromX, final float pToX, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromX, pToX, pEntityModifierListener, pEaseFunction); + } + + protected MoveXModifier(final MoveXModifier pMoveXModifier) { + super(pMoveXModifier); + } + + @Override + public MoveXModifier clone(){ + return new MoveXModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValue(final IEntity pEntity, final float pX) { + pEntity.setPosition(pX, pEntity.getY()); + } + + @Override + protected void onSetValue(final IEntity pEntity, final float pPercentageDone, final float pX) { + pEntity.setPosition(pX, pEntity.getY()); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/MoveYModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/MoveYModifier.java new file mode 100644 index 0000000..87a511b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/MoveYModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 12:04:21 - 30.08.2010 + */ +public class MoveYModifier extends SingleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public MoveYModifier(final float pDuration, final float pFromY, final float pToY) { + this(pDuration, pFromY, pToY, null, IEaseFunction.DEFAULT); + } + + public MoveYModifier(final float pDuration, final float pFromY, final float pToY, final IEaseFunction pEaseFunction) { + this(pDuration, pFromY, pToY, null, pEaseFunction); + } + + public MoveYModifier(final float pDuration, final float pFromY, final float pToY, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromY, pToY, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public MoveYModifier(final float pDuration, final float pFromY, final float pToY, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromY, pToY, pEntityModifierListener, pEaseFunction); + } + + protected MoveYModifier(final MoveYModifier pMoveYModifier) { + super(pMoveYModifier); + } + + @Override + public MoveYModifier clone(){ + return new MoveYModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValue(final IEntity pEntity, final float pY) { + pEntity.setPosition(pEntity.getX(), pY); + } + + @Override + protected void onSetValue(final IEntity pEntity, final float pPercentageDone, final float pY) { + pEntity.setPosition(pEntity.getX(), pY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/ParallelEntityModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/ParallelEntityModifier.java new file mode 100644 index 0000000..73047f3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/ParallelEntityModifier.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ParallelModifier; + +/** + * @author Nicolas Gramlich + * @since 12:40:31 - 03.09.2010 + */ +public class ParallelEntityModifier extends ParallelModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ParallelEntityModifier(final IEntityModifier... pEntityModifiers) throws IllegalArgumentException { + super(pEntityModifiers); + } + + public ParallelEntityModifier(final IEntityModifierListener pEntityModifierListener, final IEntityModifier... pEntityModifiers) throws IllegalArgumentException { + super(pEntityModifierListener, pEntityModifiers); + } + + protected ParallelEntityModifier(final ParallelEntityModifier pParallelShapeModifier) { + super(pParallelShapeModifier); + } + + @Override + public ParallelEntityModifier clone() { + return new ParallelEntityModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/PathModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/PathModifier.java new file mode 100644 index 0000000..5d1e6e9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/PathModifier.java @@ -0,0 +1,316 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.IModifier; +import org.anddev.andengine.util.modifier.SequenceModifier; +import org.anddev.andengine.util.modifier.SequenceModifier.ISubSequenceModifierListener; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 16:50:02 - 16.06.2010 + */ +public class PathModifier extends EntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final SequenceModifier mSequenceModifier; + + private IPathModifierListener mPathModifierListener; + + private final Path mPath; + + // =========================================================== + // Constructors + // =========================================================== + + public PathModifier(final float pDuration, final Path pPath) { + this(pDuration, pPath, null, IEaseFunction.DEFAULT); + } + + public PathModifier(final float pDuration, final Path pPath, final IEaseFunction pEaseFunction) { + this(pDuration, pPath, null, pEaseFunction); + } + + public PathModifier(final float pDuration, final Path pPath, final IEntityModifierListener pEntityModiferListener) { + this(pDuration, pPath, pEntityModiferListener, null, IEaseFunction.DEFAULT); + } + + public PathModifier(final float pDuration, final Path pPath, final IEntityModifierListener pEntityModiferListener, final IEaseFunction pEaseFunction) { + this(pDuration, pPath, pEntityModiferListener, null, pEaseFunction); + } + + public PathModifier(final float pDuration, final Path pPath, final IEntityModifierListener pEntityModiferListener, final IPathModifierListener pPathModifierListener) throws IllegalArgumentException { + this(pDuration, pPath, pEntityModiferListener, pPathModifierListener, IEaseFunction.DEFAULT); + } + + public PathModifier(final float pDuration, final Path pPath, final IEntityModifierListener pEntityModiferListener, final IPathModifierListener pPathModifierListener, final IEaseFunction pEaseFunction) throws IllegalArgumentException { + final int pathSize = pPath.getSize(); + + if (pathSize < 2) { + throw new IllegalArgumentException("Path needs at least 2 waypoints!"); + } + + this.mPath = pPath; + this.mModifierListener = pEntityModiferListener; + this.mPathModifierListener = pPathModifierListener; + + final MoveModifier[] moveModifiers = new MoveModifier[pathSize - 1]; + + final float[] coordinatesX = pPath.getCoordinatesX(); + final float[] coordinatesY = pPath.getCoordinatesY(); + + final float velocity = pPath.getLength() / pDuration; + + final int modifierCount = moveModifiers.length; + for(int i = 0; i < modifierCount; i++) { + final float duration = pPath.getSegmentLength(i) / velocity; + + if(i == 0) { + /* When the first modifier is initialized, we have to + * fire onWaypointPassed of mPathModifierListener. */ + moveModifiers[i] = new MoveModifier(duration, coordinatesX[i], coordinatesX[i + 1], coordinatesY[i], coordinatesY[i + 1], null, pEaseFunction){ + @Override + protected void onManagedInitialize(final IEntity pEntity) { + super.onManagedInitialize(pEntity); + if(PathModifier.this.mPathModifierListener != null) { + PathModifier.this.mPathModifierListener.onWaypointPassed(PathModifier.this, pEntity, 0); + } + } + }; + } else { + moveModifiers[i] = new MoveModifier(duration, coordinatesX[i], coordinatesX[i + 1], coordinatesY[i], coordinatesY[i + 1], null, pEaseFunction); + } + } + + + /* Create a new SequenceModifier and register the listeners that + * call through to mEntityModifierListener and mPathModifierListener. */ + this.mSequenceModifier = new SequenceModifier( + new IEntityModifierListener() { + @Override + public void onModifierFinished(final IModifier pEntityModifier, final IEntity pEntity) { + if(PathModifier.this.mPathModifierListener != null) { + PathModifier.this.mPathModifierListener.onWaypointPassed(PathModifier.this, pEntity, modifierCount); + } + if(PathModifier.this.mModifierListener != null) { + PathModifier.this.mModifierListener.onModifierFinished(PathModifier.this, pEntity); + } + } + }, + new ISubSequenceModifierListener() { + @Override + public void onSubSequenceFinished(final IModifier pEntityModifier, final IEntity pEntity, final int pIndex) { + if(PathModifier.this.mPathModifierListener != null) { + PathModifier.this.mPathModifierListener.onWaypointPassed(PathModifier.this, pEntity, pIndex); + } + } + }, + moveModifiers + ); + } + + protected PathModifier(final PathModifier pPathModifier) { + this.mPath = pPathModifier.mPath.clone(); + this.mSequenceModifier = pPathModifier.mSequenceModifier.clone(); + } + + @Override + public PathModifier clone() { + return new PathModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Path getPath() { + return this.mPath; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean isFinished() { + return this.mSequenceModifier.isFinished(); + } + + @Override + public float getDuration() { + return this.mSequenceModifier.getDuration(); + } + + public IPathModifierListener getPathModifierListener() { + return this.mPathModifierListener; + } + + public void setPathModifierListener(final IPathModifierListener pPathModifierListener) { + this.mPathModifierListener = pPathModifierListener; + } + + @Override + public void reset() { + this.mSequenceModifier.reset(); + } + + @Override + public void onUpdate(final float pSecondsElapsed, final IEntity pEntity) { + this.mSequenceModifier.onUpdate(pSecondsElapsed, pEntity); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IPathModifierListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public void onWaypointPassed(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex); + } + + public static class Path { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float[] mCoordinatesX; + private final float[] mCoordinatesY; + + private int mIndex; + private boolean mLengthChanged = false; + private float mLength; + + // =========================================================== + // Constructors + // =========================================================== + + public Path(final int pLength) { + this.mCoordinatesX = new float[pLength]; + this.mCoordinatesY = new float[pLength]; + + this.mIndex = 0; + this.mLengthChanged = false; + } + + public Path(final float[] pCoordinatesX, final float[] pCoordinatesY) throws IllegalArgumentException { + if (pCoordinatesX.length != pCoordinatesY.length) { + throw new IllegalArgumentException("Coordinate-Arrays must have the same length."); + } + + this.mCoordinatesX = pCoordinatesX; + this.mCoordinatesY = pCoordinatesY; + + this.mIndex = pCoordinatesX.length; + this.mLengthChanged = true; + } + + public Path(final Path pPath) { + final int size = pPath.getSize(); + this.mCoordinatesX = new float[size]; + this.mCoordinatesY = new float[size]; + + System.arraycopy(pPath.mCoordinatesX, 0, this.mCoordinatesX, 0, size); + System.arraycopy(pPath.mCoordinatesY, 0, this.mCoordinatesY, 0, size); + + this.mIndex = pPath.mIndex; + this.mLengthChanged = pPath.mLengthChanged; + this.mLength = pPath.mLength; + } + + @Override + public Path clone() { + return new Path(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Path to(final float pX, final float pY) { + this.mCoordinatesX[this.mIndex] = pX; + this.mCoordinatesY[this.mIndex] = pY; + + this.mIndex++; + + this.mLengthChanged = true; + + return this; + } + + public float[] getCoordinatesX() { + return this.mCoordinatesX; + } + + public float[] getCoordinatesY() { + return this.mCoordinatesY; + } + + public int getSize() { + return this.mCoordinatesX.length; + } + + public float getLength() { + if(this.mLengthChanged) { + this.updateLength(); + } + return this.mLength; + } + + public float getSegmentLength(final int pSegmentIndex) { + final float[] coordinatesX = this.mCoordinatesX; + final float[] coordinatesY = this.mCoordinatesY; + + final int nextSegmentIndex = pSegmentIndex + 1; + + final float dx = coordinatesX[pSegmentIndex] - coordinatesX[nextSegmentIndex]; + final float dy = coordinatesY[pSegmentIndex] - coordinatesY[nextSegmentIndex]; + + return FloatMath.sqrt(dx * dx + dy * dy); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + private void updateLength() { + float length = 0.0f; + + for(int i = this.mIndex - 2; i >= 0; i--) { + length += this.getSegmentLength(i); + } + this.mLength = length; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } + +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/RotationAtModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/RotationAtModifier.java new file mode 100644 index 0000000..0592bbc --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/RotationAtModifier.java @@ -0,0 +1,83 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + + +/** + * @author Nicolas Gramlich + * @since 21:59:38 - 06.07.2010 + */ +public class RotationAtModifier extends RotationModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mRotationCenterX; + private final float mRotationCenterY; + + // =========================================================== + // Constructors + // =========================================================== + + public RotationAtModifier(final float pDuration, final float pFromRotation, final float pToRotation, final float pRotationCenterX, final float pRotationCenterY) { + super(pDuration, pFromRotation, pToRotation, IEaseFunction.DEFAULT); + this.mRotationCenterX = pRotationCenterX; + this.mRotationCenterY = pRotationCenterY; + } + + public RotationAtModifier(final float pDuration, final float pFromRotation, final float pToRotation, final float pRotationCenterX, final float pRotationCenterY, final IEaseFunction pEaseFunction) { + super(pDuration, pFromRotation, pToRotation, pEaseFunction); + this.mRotationCenterX = pRotationCenterX; + this.mRotationCenterY = pRotationCenterY; + } + + public RotationAtModifier(final float pDuration, final float pFromRotation, final float pToRotation, final float pRotationCenterX, final float pRotationCenterY, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromRotation, pToRotation, pEntityModifierListener, IEaseFunction.DEFAULT); + this.mRotationCenterX = pRotationCenterX; + this.mRotationCenterY = pRotationCenterY; + } + + public RotationAtModifier(final float pDuration, final float pFromRotation, final float pToRotation, final float pRotationCenterX, final float pRotationCenterY, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromRotation, pToRotation, pEntityModifierListener, pEaseFunction); + this.mRotationCenterX = pRotationCenterX; + this.mRotationCenterY = pRotationCenterY; + } + + protected RotationAtModifier(final RotationAtModifier pRotationAtModifier) { + super(pRotationAtModifier); + this.mRotationCenterX = pRotationAtModifier.mRotationCenterX; + this.mRotationCenterY = pRotationAtModifier.mRotationCenterY; + } + + @Override + public RotationAtModifier clone(){ + return new RotationAtModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedInitialize(final IEntity pEntity) { + super.onManagedInitialize(pEntity); + pEntity.setRotationCenter(this.mRotationCenterX, this.mRotationCenterY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/RotationByModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/RotationByModifier.java new file mode 100644 index 0000000..2566343 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/RotationByModifier.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; + +/** + * @author Nicolas Gramlich + * @since 16:12:52 - 19.03.2010 + */ +public class RotationByModifier extends SingleValueChangeShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RotationByModifier(final float pDuration, final float pRotation) { + super(pDuration, pRotation); + } + + protected RotationByModifier(final RotationByModifier pRotationByModifier) { + super(pRotationByModifier); + } + + @Override + public RotationByModifier clone(){ + return new RotationByModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onChangeValue(final IEntity pEntity, final float pValue) { + pEntity.setRotation(pEntity.getRotation() + pValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/RotationModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/RotationModifier.java new file mode 100644 index 0000000..935e5dd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/RotationModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 16:12:52 - 19.03.2010 + */ +public class RotationModifier extends SingleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RotationModifier(final float pDuration, final float pFromRotation, final float pToRotation) { + this(pDuration, pFromRotation, pToRotation, null, IEaseFunction.DEFAULT); + } + + public RotationModifier(final float pDuration, final float pFromRotation, final float pToRotation, final IEaseFunction pEaseFunction) { + this(pDuration, pFromRotation, pToRotation, null, pEaseFunction); + } + + public RotationModifier(final float pDuration, final float pFromRotation, final float pToRotation, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromRotation, pToRotation, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public RotationModifier(final float pDuration, final float pFromRotation, final float pToRotation, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromRotation, pToRotation, pEntityModifierListener, pEaseFunction); + } + + protected RotationModifier(final RotationModifier pRotationModifier) { + super(pRotationModifier); + } + + @Override + public RotationModifier clone(){ + return new RotationModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValue(final IEntity pEntity, final float pRotation) { + pEntity.setRotation(pRotation); + } + + @Override + protected void onSetValue(final IEntity pEntity, final float pPercentageDone, final float pRotation) { + pEntity.setRotation(pRotation); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/ScaleAtModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/ScaleAtModifier.java new file mode 100644 index 0000000..10f4c2a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/ScaleAtModifier.java @@ -0,0 +1,93 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + + +/** + * @author Nicolas Gramlich + * @since 21:53:30 - 06.07.2010 + */ +public class ScaleAtModifier extends ScaleModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mScaleCenterX; + private final float mScaleCenterY; + + // =========================================================== + // Constructors + // =========================================================== + + public ScaleAtModifier(final float pDuration, final float pFromScale, final float pToScale, final float pScaleCenterX, final float pScaleCenterY) { + this(pDuration, pFromScale, pToScale, pScaleCenterX, pScaleCenterY, IEaseFunction.DEFAULT); + } + + public ScaleAtModifier(final float pDuration, final float pFromScale, final float pToScale, final float pScaleCenterX, final float pScaleCenterY, final IEaseFunction pEaseFunction) { + this(pDuration, pFromScale, pToScale, pScaleCenterX, pScaleCenterY, null, pEaseFunction); + } + + public ScaleAtModifier(final float pDuration, final float pFromScale, final float pToScale, final float pScaleCenterX, final float pScaleCenterY, final IEntityModifierListener pEntityModifierListener) { + this(pDuration, pFromScale, pToScale, pScaleCenterX, pScaleCenterY, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public ScaleAtModifier(final float pDuration, final float pFromScale, final float pToScale, final float pScaleCenterX, final float pScaleCenterY, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + this(pDuration, pFromScale, pToScale, pFromScale, pToScale, pScaleCenterX, pScaleCenterY, pEntityModifierListener, pEaseFunction); + } + + public ScaleAtModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final float pScaleCenterX, final float pScaleCenterY) { + this(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pScaleCenterX, pScaleCenterY, IEaseFunction.DEFAULT); + } + + public ScaleAtModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final float pScaleCenterX, final float pScaleCenterY, final IEaseFunction pEaseFunction) { + this(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pScaleCenterX, pScaleCenterY, null, pEaseFunction); + } + + public ScaleAtModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final float pScaleCenterX, final float pScaleCenterY, final IEntityModifierListener pEntityModifierListener) { + this(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pScaleCenterX, pScaleCenterY, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public ScaleAtModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final float pScaleCenterX, final float pScaleCenterY, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pEntityModifierListener, pEaseFunction); + this.mScaleCenterX = pScaleCenterX; + this.mScaleCenterY = pScaleCenterY; + } + + protected ScaleAtModifier(final ScaleAtModifier pScaleAtModifier) { + super(pScaleAtModifier); + this.mScaleCenterX = pScaleAtModifier.mScaleCenterX; + this.mScaleCenterY = pScaleAtModifier.mScaleCenterY; + } + + @Override + public ScaleAtModifier clone(){ + return new ScaleAtModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedInitialize(final IEntity pEntity) { + super.onManagedInitialize(pEntity); + pEntity.setScaleCenter(this.mScaleCenterX, this.mScaleCenterY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/ScaleModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/ScaleModifier.java new file mode 100644 index 0000000..19685e2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/ScaleModifier.java @@ -0,0 +1,89 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 23:37:53 - 19.03.2010 + */ +public class ScaleModifier extends DoubleValueSpanShapeModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ScaleModifier(final float pDuration, final float pFromScale, final float pToScale) { + this(pDuration, pFromScale, pToScale, null, IEaseFunction.DEFAULT); + } + + public ScaleModifier(final float pDuration, final float pFromScale, final float pToScale, final IEaseFunction pEaseFunction) { + this(pDuration, pFromScale, pToScale, null, pEaseFunction); + } + + public ScaleModifier(final float pDuration, final float pFromScale, final float pToScale, final IEntityModifierListener pEntityModifierListener) { + this(pDuration, pFromScale, pToScale, pFromScale, pToScale, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public ScaleModifier(final float pDuration, final float pFromScale, final float pToScale, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + this(pDuration, pFromScale, pToScale, pFromScale, pToScale, pEntityModifierListener, pEaseFunction); + } + + public ScaleModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY) { + this(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, null, IEaseFunction.DEFAULT); + } + + public ScaleModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final IEaseFunction pEaseFunction) { + this(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, null, pEaseFunction); + } + + public ScaleModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pEntityModifierListener, IEaseFunction.DEFAULT); + } + + public ScaleModifier(final float pDuration, final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pEntityModifierListener, pEaseFunction); + } + + protected ScaleModifier(final ScaleModifier pScaleModifier) { + super(pScaleModifier); + } + + @Override + public ScaleModifier clone(){ + return new ScaleModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValues(final IEntity pEntity, final float pScaleA, final float pScaleB) { + pEntity.setScale(pScaleA, pScaleB); + } + + @Override + protected void onSetValues(final IEntity pEntity, final float pPercentageDone, final float pScaleA, final float pScaleB) { + pEntity.setScale(pScaleA, pScaleB); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/SequenceEntityModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/SequenceEntityModifier.java new file mode 100644 index 0000000..3179e04 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/SequenceEntityModifier.java @@ -0,0 +1,69 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.SequenceModifier; + +/** + * @author Nicolas Gramlich + * @since 12:41:15 - 03.09.2010 + */ +public class SequenceEntityModifier extends SequenceModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SequenceEntityModifier(final IEntityModifier... pEntityModifiers) throws IllegalArgumentException { + super(pEntityModifiers); + } + + public SequenceEntityModifier(final IEntityModifierListener pEntityModifierListener, final IEntityModifier... pEntityModifiers) throws IllegalArgumentException { + super(pEntityModifierListener, pEntityModifiers); + } + + public SequenceEntityModifier(final IEntityModifierListener pEntityModifierListener, final ISubSequenceShapeModifierListener pSubSequenceShapeModifierListener, final IEntityModifier... pEntityModifiers) throws IllegalArgumentException { + super(pEntityModifierListener, pSubSequenceShapeModifierListener, pEntityModifiers); + } + + protected SequenceEntityModifier(final SequenceEntityModifier pSequenceShapeModifier) { + super(pSequenceShapeModifier); + } + + @Override + public SequenceEntityModifier clone() { + return new SequenceEntityModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ISubSequenceShapeModifierListener extends ISubSequenceModifierListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/SingleValueChangeShapeModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/SingleValueChangeShapeModifier.java new file mode 100644 index 0000000..7715b95 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/SingleValueChangeShapeModifier.java @@ -0,0 +1,50 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.BaseSingleValueChangeModifier; + +/** + * @author Nicolas Gramlich + * @since 15:34:35 - 17.06.2010 + */ +public abstract class SingleValueChangeShapeModifier extends BaseSingleValueChangeModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SingleValueChangeShapeModifier(final float pDuration, final float pValueChange) { + super(pDuration, pValueChange); + } + + public SingleValueChangeShapeModifier(final float pDuration, final float pValueChange, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pValueChange, pEntityModifierListener); + } + + protected SingleValueChangeShapeModifier(final SingleValueChangeShapeModifier pSingleValueChangeShapeModifier) { + super(pSingleValueChangeShapeModifier); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/SingleValueSpanShapeModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/SingleValueSpanShapeModifier.java new file mode 100644 index 0000000..bd15413 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/SingleValueSpanShapeModifier.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.BaseSingleValueSpanModifier; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 23:29:22 - 19.03.2010 + */ +public abstract class SingleValueSpanShapeModifier extends BaseSingleValueSpanModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SingleValueSpanShapeModifier(final float pDuration, final float pFromValue, final float pToValue) { + super(pDuration, pFromValue, pToValue); + } + + public SingleValueSpanShapeModifier(final float pDuration, final float pFromValue, final float pToValue, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValue, pToValue, pEaseFunction); + } + + public SingleValueSpanShapeModifier(final float pDuration, final float pFromValue, final float pToValue, final IEntityModifierListener pEntityModifierListener) { + super(pDuration, pFromValue, pToValue, pEntityModifierListener); + } + + public SingleValueSpanShapeModifier(final float pDuration, final float pFromValue, final float pToValue, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValue, pToValue, pEntityModifierListener, pEaseFunction); + } + + protected SingleValueSpanShapeModifier(final SingleValueSpanShapeModifier pSingleValueSpanShapeModifier) { + super(pSingleValueSpanShapeModifier); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/modifier/TripleValueSpanShapeModifier.java b/AndEngine/src/org/anddev/andengine/entity/modifier/TripleValueSpanShapeModifier.java new file mode 100644 index 0000000..3e2d51e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/modifier/TripleValueSpanShapeModifier.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.modifier; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.util.modifier.BaseTripleValueSpanModifier; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 15:35:18 - 29.06.2010 + */ +public abstract class TripleValueSpanShapeModifier extends BaseTripleValueSpanModifier implements IEntityModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TripleValueSpanShapeModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final float pFromValueC, final float pToValueC, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pFromValueC, pToValueC, pEaseFunction); + } + + public TripleValueSpanShapeModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final float pFromValueC, final float pToValueC, final IEntityModifierListener pEntityModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pFromValueC, pToValueC, pEntityModifierListener, pEaseFunction); + } + + protected TripleValueSpanShapeModifier(final TripleValueSpanShapeModifier pTripleValueSpanModifier) { + super(pTripleValueSpanModifier); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/Particle.java b/AndEngine/src/org/anddev/andengine/entity/particle/Particle.java new file mode 100644 index 0000000..08c9e6d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/Particle.java @@ -0,0 +1,101 @@ +package org.anddev.andengine.entity.particle; + +import org.anddev.andengine.engine.handler.physics.PhysicsHandler; +import org.anddev.andengine.entity.sprite.Sprite; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 19:37:13 - 14.03.2010 + */ +public class Particle extends Sprite { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mLifeTime; + private float mDeathTime = -1; + boolean mDead = false; + private final PhysicsHandler mPhysicsHandler = new PhysicsHandler(this); + + // =========================================================== + // Constructors + // ===========================================================; + + public Particle(final float pX, final float pY, final TextureRegion pTextureRegion) { + super(pX, pY, pTextureRegion); + this.mLifeTime = 0; + } + + public Particle(final float pX, final float pY, final TextureRegion pTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pTextureRegion, pRectangleVertexBuffer); + this.mLifeTime = 0; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getLifeTime() { + return this.mLifeTime; + } + + public float getDeathTime() { + return this.mDeathTime; + } + + public void setDeathTime(final float pDeathTime) { + this.mDeathTime = pDeathTime; + } + + public boolean isDead() { + return this.mDead ; + } + + public void setDead(final boolean pDead) { + this.mDead = pDead; + } + + public PhysicsHandler getPhysicsHandler() { + return this.mPhysicsHandler; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + if(!this.mDead){ + this.mLifeTime += pSecondsElapsed; + this.mPhysicsHandler.onUpdate(pSecondsElapsed); + super.onManagedUpdate(pSecondsElapsed); + final float deathTime = this.mDeathTime; + if(deathTime != -1 && this.mLifeTime > deathTime) { + this.setDead(true); + } + } + } + + // =========================================================== + // Methods + // =========================================================== + + @Override + public void reset() { + super.reset(); + this.mPhysicsHandler.reset(); + this.mDead = false; + this.mDeathTime = -1; + this.mLifeTime = 0; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/ParticleSystem.java b/AndEngine/src/org/anddev/andengine/entity/particle/ParticleSystem.java new file mode 100644 index 0000000..781c070 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/ParticleSystem.java @@ -0,0 +1,258 @@ +package org.anddev.andengine.entity.particle; + +import static org.anddev.andengine.util.MathUtils.RANDOM; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.Entity; +import org.anddev.andengine.entity.particle.emitter.IParticleEmitter; +import org.anddev.andengine.entity.particle.emitter.RectangleParticleEmitter; +import org.anddev.andengine.entity.particle.initializer.IParticleInitializer; +import org.anddev.andengine.entity.particle.modifier.IParticleModifier; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 19:42:27 - 14.03.2010 + */ +public class ParticleSystem extends Entity { + // =========================================================== + // Constants + // =========================================================== + + private static final int BLENDFUNCTION_SOURCE_DEFAULT = GL10.GL_ONE; + private static final int BLENDFUNCTION_DESTINATION_DEFAULT = GL10.GL_ONE_MINUS_SRC_ALPHA; + + private final float[] POSITION_OFFSET = new float[2]; + + // =========================================================== + // Fields + // =========================================================== + + private final IParticleEmitter mParticleEmitter; + + private final Particle[] mParticles; + + private int mSourceBlendFunction = BLENDFUNCTION_SOURCE_DEFAULT; + private int mDestinationBlendFunction = BLENDFUNCTION_DESTINATION_DEFAULT; + + private final ArrayList mParticleInitializers = new ArrayList(); + private final ArrayList mParticleModifiers = new ArrayList(); + + private final float mRateMinimum; + private final float mRateMaximum; + + private final TextureRegion mTextureRegion; + + private boolean mParticlesSpawnEnabled = true; + + private final int mParticlesMaximum; + private int mParticlesAlive; + private float mParticlesDueToSpawn; + + private int mParticleModifierCount; + private int mParticleInitializerCount; + + private RectangleVertexBuffer mSharedParticleVertexBuffer; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * Creates a ParticleSystem with a {@link RectangleParticleEmitter}. + * @deprecated Instead use {@link ParticleSystem#ParticleSystem(IParticleEmitter, float, float, int, TextureRegion)}. + */ + @Deprecated + public ParticleSystem(final float pX, final float pY, final float pWidth, final float pHeight, final float pRateMinimum, final float pRateMaximum, final int pParticlesMaximum, final TextureRegion pTextureRegion) { + this(new RectangleParticleEmitter(pX + pWidth * 0.5f, pY + pHeight * 0.5f, pWidth, pHeight), pRateMinimum, pRateMaximum, pParticlesMaximum, pTextureRegion); + } + + public ParticleSystem(final IParticleEmitter pParticleEmitter, final float pRateMinimum, final float pRateMaximum, final int pParticlesMaximum, final TextureRegion pTextureRegion) { + super(0, 0); + + this.mParticleEmitter = pParticleEmitter; + this.mParticles = new Particle[pParticlesMaximum]; + this.mRateMinimum = pRateMinimum; + this.mRateMaximum = pRateMaximum; + this.mParticlesMaximum = pParticlesMaximum; + this.mTextureRegion = pTextureRegion; + + this.registerUpdateHandler(this.mParticleEmitter); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isParticlesSpawnEnabled() { + return this.mParticlesSpawnEnabled; + } + + public void setParticlesSpawnEnabled(final boolean pParticlesSpawnEnabled) { + this.mParticlesSpawnEnabled = pParticlesSpawnEnabled; + } + + public void setBlendFunction(final int pSourceBlendFunction, final int pDestinationBlendFunction) { + this.mSourceBlendFunction = pSourceBlendFunction; + this.mDestinationBlendFunction = pDestinationBlendFunction; + } + + public IParticleEmitter getParticleEmitter() { + return this.mParticleEmitter; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void reset() { + super.reset(); + + this.mParticlesDueToSpawn = 0; + this.mParticlesAlive = 0; + } + + @Override + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + final Particle[] particles = this.mParticles; + for(int i = this.mParticlesAlive - 1; i >= 0; i--) { + particles[i].onDraw(pGL, pCamera); + } + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + super.onManagedUpdate(pSecondsElapsed); + + if(this.mParticlesSpawnEnabled) { + this.spawnParticles(pSecondsElapsed); + } + + final Particle[] particles = this.mParticles; + + final ArrayList particleModifiers = this.mParticleModifiers; + final int particleModifierCountMinusOne = this.mParticleModifierCount - 1; + + for(int i = this.mParticlesAlive - 1; i >= 0; i--) { + final Particle particle = particles[i]; + + /* Apply all particleModifiers */ + for(int j = particleModifierCountMinusOne; j >= 0; j--) { + particleModifiers.get(j).onUpdateParticle(particle); + } + + particle.onUpdate(pSecondsElapsed); + if(particle.mDead){ + this.mParticlesAlive--; + final int particlesAlive = this.mParticlesAlive; + particles[i] = particles[particlesAlive]; + particles[particlesAlive] = particle; + } + } + } + + // =========================================================== + // Methods + // =========================================================== + + public void addParticleModifier(final IParticleModifier pParticleModifier) { + this.mParticleModifiers.add(pParticleModifier); + this.mParticleModifierCount++; + } + + public void removeParticleModifier(final IParticleModifier pParticleModifier) { + this.mParticleModifierCount--; + this.mParticleModifiers.remove(pParticleModifier); + } + + public void addParticleInitializer(final IParticleInitializer pParticleInitializer) { + this.mParticleInitializers.add(pParticleInitializer); + this.mParticleInitializerCount++; + } + + public void removeParticleInitializer(final IParticleInitializer pParticleInitializer) { + this.mParticleInitializerCount--; + this.mParticleInitializers.remove(pParticleInitializer); + } + + private void spawnParticles(final float pSecondsElapsed) { + final float currentRate = this.determineCurrentRate(); + final float newParticlesThisFrame = currentRate * pSecondsElapsed; + + this.mParticlesDueToSpawn += newParticlesThisFrame; + + final int particlesToSpawnThisFrame = Math.min(this.mParticlesMaximum - this.mParticlesAlive, (int)FloatMath.floor(this.mParticlesDueToSpawn)); + this.mParticlesDueToSpawn -= particlesToSpawnThisFrame; + + for(int i = 0; i < particlesToSpawnThisFrame; i++){ + this.spawnParticle(); + } + } + + private void spawnParticle() { + final Particle[] particles = this.mParticles; + + final int particlesAlive = this.mParticlesAlive; + if(particlesAlive < this.mParticlesMaximum){ + Particle particle = particles[particlesAlive]; + + /* New particle needs to be created. */ + this.mParticleEmitter.getPositionOffset(this.POSITION_OFFSET); + + final float x = this.POSITION_OFFSET[VERTEX_INDEX_X]; + final float y = this.POSITION_OFFSET[VERTEX_INDEX_Y]; + + if(particle != null) { + particle.reset(); + particle.setPosition(x, y); + } else { + if(particlesAlive == 0) { + /* This is the very first particle. */ + particle = new Particle(x, y, this.mTextureRegion); + this.mSharedParticleVertexBuffer = particle.getVertexBuffer(); + } else { + particle = new Particle(x, y, this.mTextureRegion, this.mSharedParticleVertexBuffer); + } + particles[particlesAlive] = particle; + } + particle.setBlendFunction(this.mSourceBlendFunction, this.mDestinationBlendFunction); + + /* Apply particle initializers. */ + { + final ArrayList particleInitializers = this.mParticleInitializers; + for(int i = this.mParticleInitializerCount - 1; i >= 0; i--) { + particleInitializers.get(i).onInitializeParticle(particle); + } + + final ArrayList particleModifiers = this.mParticleModifiers; + for(int i = this.mParticleModifierCount - 1; i >= 0; i--) { + particleModifiers.get(i).onInitializeParticle(particle); + } + } + + this.mParticlesAlive++; + } + } + + private float determineCurrentRate() { + if(this.mRateMinimum == this.mRateMaximum){ + return this.mRateMinimum; + } else { + return (RANDOM.nextFloat() * (this.mRateMaximum - this.mRateMinimum)) + this.mRateMinimum; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseCircleParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseCircleParticleEmitter.java new file mode 100644 index 0000000..3ebd53e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseCircleParticleEmitter.java @@ -0,0 +1,75 @@ +package org.anddev.andengine.entity.particle.emitter; + + +/** + * @author Nicolas Gramlich + * @since 20:14:43 - 01.10.2010 + */ +public abstract class BaseCircleParticleEmitter extends BaseParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mRadiusX; + protected float mRadiusY; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseCircleParticleEmitter(final float pCenterX, final float pCenterY, final float pRadius) { + this(pCenterX, pCenterY, pRadius, pRadius); + } + + public BaseCircleParticleEmitter(final float pCenterX, final float pCenterY, final float pRadiusX, final float pRadiusY) { + super(pCenterX, pCenterY); + this.setRadiusX(pRadiusX); + this.setRadiusY(pRadiusY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getRadiusX() { + return this.mRadiusX; + } + + public void setRadiusX(final float pRadiusX) { + this.mRadiusX = pRadiusX; + } + + public float getRadiusY() { + return this.mRadiusY; + } + + public void setRadiusY(final float pRadiusY) { + this.mRadiusY = pRadiusY; + } + + public void setRadius(final float pRadius) { + this.mRadiusX = pRadius; + this.mRadiusY = pRadius; + } + + public void setRadius(final float pRadiusX, final float pRadiusY) { + this.mRadiusX = pRadiusX; + this.mRadiusY = pRadiusY; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseParticleEmitter.java new file mode 100644 index 0000000..66c0891 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseParticleEmitter.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.entity.particle.emitter; + +/** + * @author Nicolas Gramlich + * @since 15:58:12 - 01.10.2010 + */ +public abstract class BaseParticleEmitter implements IParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mCenterX; + protected float mCenterY; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseParticleEmitter(final float pCenterX, final float pCenterY) { + this.mCenterX = pCenterX; + this.mCenterY = pCenterY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getCenterX() { + return this.mCenterX; + } + + public float getCenterY() { + return this.mCenterY; + } + + public void setCenterX(final float pCenterX) { + this.mCenterX = pCenterX; + } + + public void setCenterY(final float pCenterY) { + this.mCenterY = pCenterY; + } + + public void setCenter(final float pCenterX, final float pCenterY) { + this.mCenterX = pCenterX; + this.mCenterY = pCenterY; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + + } + + @Override + public void reset() { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseRectangleParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseRectangleParticleEmitter.java new file mode 100644 index 0000000..cd5b334 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/BaseRectangleParticleEmitter.java @@ -0,0 +1,69 @@ +package org.anddev.andengine.entity.particle.emitter; + + +/** + * @author Nicolas Gramlich + * @since 18:53:18 - 01.10.2010 + */ +public abstract class BaseRectangleParticleEmitter extends BaseParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mWidth; + protected float mHeight; + protected float mWidthHalf; + protected float mHeightHalf; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseRectangleParticleEmitter(final float pCenterX, final float pCenterY, final float pSize) { + this(pCenterX, pCenterY, pSize, pSize); + } + + public BaseRectangleParticleEmitter(final float pCenterX, final float pCenterY, final float pWidth, final float pHeight) { + super(pCenterX, pCenterY); + this.setWidth(pWidth); + this.setHeight(pHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getWidth() { + return this.mWidth; + } + + public void setWidth(final float pWidth) { + this.mWidth = pWidth; + this.mWidthHalf = pWidth * 0.5f; + } + + public float getHeight() { + return this.mHeight; + } + + public void setHeight(final float pHeight) { + this.mHeight = pHeight; + this.mHeightHalf = pHeight * 0.5f; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/CircleOutlineParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/CircleOutlineParticleEmitter.java new file mode 100644 index 0000000..d292c6a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/CircleOutlineParticleEmitter.java @@ -0,0 +1,58 @@ +package org.anddev.andengine.entity.particle.emitter; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 20:18:41 - 01.10.2010 + */ +public class CircleOutlineParticleEmitter extends BaseCircleParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public CircleOutlineParticleEmitter(final float pCenterX, final float pCenterY, final float pRadius) { + super(pCenterX, pCenterY, pRadius); + } + + public CircleOutlineParticleEmitter(final float pCenterX, final float pCenterY, final float pRadiusX, final float pRadiusY) { + super(pCenterX, pCenterY, pRadiusX, pRadiusY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void getPositionOffset(final float[] pOffset) { + final float random = MathUtils.RANDOM.nextFloat() * MathConstants.PI * 2; + pOffset[VERTEX_INDEX_X] = this.mCenterX + FloatMath.cos(random) * this.mRadiusX; + pOffset[VERTEX_INDEX_Y] = this.mCenterY + FloatMath.sin(random) * this.mRadiusY; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/CircleParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/CircleParticleEmitter.java new file mode 100644 index 0000000..bc1a87b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/CircleParticleEmitter.java @@ -0,0 +1,58 @@ +package org.anddev.andengine.entity.particle.emitter; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 20:18:41 - 01.10.2010 + */ +public class CircleParticleEmitter extends BaseCircleParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public CircleParticleEmitter(final float pCenterX, final float pCenterY, final float pRadius) { + super(pCenterX, pCenterY, pRadius); + } + + public CircleParticleEmitter(final float pCenterX, final float pCenterY, final float pRadiusX, final float pRadiusY) { + super(pCenterX, pCenterY, pRadiusX, pRadiusY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void getPositionOffset(final float[] pOffset) { + final float random = MathUtils.RANDOM.nextFloat() * MathConstants.PI * 2; + pOffset[VERTEX_INDEX_X] = this.mCenterX + FloatMath.cos(random) * this.mRadiusX * MathUtils.RANDOM.nextFloat(); + pOffset[VERTEX_INDEX_Y] = this.mCenterY + FloatMath.sin(random) * this.mRadiusY * MathUtils.RANDOM.nextFloat(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/IParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/IParticleEmitter.java new file mode 100644 index 0000000..6e553b9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/IParticleEmitter.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.entity.particle.emitter; + +import org.anddev.andengine.engine.handler.IUpdateHandler; + +/** + * @author Nicolas Gramlich + * @since 15:48:09 - 01.10.2010 + */ +public interface IParticleEmitter extends IUpdateHandler { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void getPositionOffset(final float[] pOffset); +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/PointParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/PointParticleEmitter.java new file mode 100644 index 0000000..6a76739 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/PointParticleEmitter.java @@ -0,0 +1,48 @@ +package org.anddev.andengine.entity.particle.emitter; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +/** + * @author Nicolas Gramlich + * @since 23:14:42 - 01.10.2010 + */ +public class PointParticleEmitter extends BaseParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public PointParticleEmitter(final float pCenterX, final float pCenterY) { + super(pCenterX, pCenterY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void getPositionOffset(final float[] pOffset) { + pOffset[VERTEX_INDEX_X] = this.mCenterX; + pOffset[VERTEX_INDEX_Y] = this.mCenterY; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/RectangleOutlineParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/RectangleOutlineParticleEmitter.java new file mode 100644 index 0000000..2138c4d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/RectangleOutlineParticleEmitter.java @@ -0,0 +1,50 @@ +package org.anddev.andengine.entity.particle.emitter; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.util.MathUtils; + +/** + * @author Nicolas Gramlich + * @since 15:48:00 - 01.10.2010 + */ +public class RectangleOutlineParticleEmitter extends BaseRectangleParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RectangleOutlineParticleEmitter(final float pCenterX, final float pCenterY, final float pWidth, final float pHeight) { + super(pCenterX, pCenterY, pWidth, pHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void getPositionOffset(final float[] pOffset) { + pOffset[VERTEX_INDEX_X] = this.mCenterX + MathUtils.randomSign() * this.mWidthHalf; + pOffset[VERTEX_INDEX_Y] = this.mCenterY + MathUtils.randomSign() * this.mHeightHalf; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/emitter/RectangleParticleEmitter.java b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/RectangleParticleEmitter.java new file mode 100644 index 0000000..8c5bfaa --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/emitter/RectangleParticleEmitter.java @@ -0,0 +1,50 @@ +package org.anddev.andengine.entity.particle.emitter; + +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_X; +import static org.anddev.andengine.util.constants.Constants.VERTEX_INDEX_Y; + +import org.anddev.andengine.util.MathUtils; + +/** + * @author Nicolas Gramlich + * @since 15:48:00 - 01.10.2010 + */ +public class RectangleParticleEmitter extends BaseRectangleParticleEmitter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RectangleParticleEmitter(final float pCenterX, final float pCenterY, final float pWidth, final float pHeight) { + super(pCenterX, pCenterY, pWidth, pHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void getPositionOffset(final float[] pOffset) { + pOffset[VERTEX_INDEX_X] = this.mCenterX - this.mWidthHalf + MathUtils.RANDOM.nextFloat() * this.mWidth; + pOffset[VERTEX_INDEX_Y] = this.mCenterY - this.mHeightHalf + MathUtils.RANDOM.nextFloat() * this.mHeight; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/AccelerationInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/AccelerationInitializer.java new file mode 100644 index 0000000..fc06834 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/AccelerationInitializer.java @@ -0,0 +1,97 @@ +package org.anddev.andengine.entity.particle.initializer; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 21:21:10 - 14.03.2010 + */ +public class AccelerationInitializer extends BaseDoubleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public AccelerationInitializer(final float pAcceleration) { + this(pAcceleration, pAcceleration); + } + + public AccelerationInitializer(final float pAccelerationX, final float pAccelerationY) { + this(pAccelerationX, pAccelerationX, pAccelerationY, pAccelerationY); + } + + public AccelerationInitializer(final float pMinAccelerationX, final float pMaxAccelerationX, final float pMinAccelerationY, final float pMaxAccelerationY) { + super(pMinAccelerationX, pMaxAccelerationX, pMinAccelerationY, pMaxAccelerationY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getMinAccelerationX() { + return this.mMinValue; + } + + public float getMaxAccelerationX() { + return this.mMaxValue; + } + + public float getMinAccelerationY() { + return this.mMinValueB; + } + + public float getMaxAccelerationY() { + return this.mMaxValueB; + } + + public void setAccelerationX(final float pAccelerationX) { + this.mMinValue = pAccelerationX; + this.mMaxValue = pAccelerationX; + } + + public void setAccelerationY(final float pAccelerationY) { + this.mMinValueB = pAccelerationY; + this.mMaxValueB = pAccelerationY; + } + + public void setAccelerationX(final float pMinAccelerationX, final float pMaxAccelerationX) { + this.mMinValue = pMinAccelerationX; + this.mMaxValue = pMaxAccelerationX; + } + + public void setAccelerationY(final float pMinAccelerationY, final float pMaxAccelerationY) { + this.mMinValueB = pMinAccelerationY; + this.mMaxValueB = pMaxAccelerationY; + } + + public void setAcceleration(final float pMinAccelerationX, final float pMaxAccelerationX, final float pMinAccelerationY, final float pMaxAccelerationY) { + this.mMinValue = pMinAccelerationX; + this.mMaxValue = pMaxAccelerationX; + this.mMinValueB = pMinAccelerationY; + this.mMaxValueB = pMaxAccelerationY; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onInitializeParticle(final Particle pParticle, final float pAccelerationX, final float pAccelerationY) { + pParticle.getPhysicsHandler().accelerate(pAccelerationX, pAccelerationY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/AlphaInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/AlphaInitializer.java new file mode 100644 index 0000000..45f9a79 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/AlphaInitializer.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.particle.initializer; + +import org.anddev.andengine.entity.particle.Particle; + + +/** + * @author Nicolas Gramlich + * @since 18:53:41 - 02.10.2010 + */ +public class AlphaInitializer extends BaseSingleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public AlphaInitializer(final float pAlpha) { + super(pAlpha, pAlpha); + } + + public AlphaInitializer(final float pMinAlpha, final float pMaxAlpha) { + super(pMinAlpha, pMaxAlpha); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onInitializeParticle(final Particle pParticle, final float pAlpha) { + pParticle.setAlpha(pAlpha); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseDoubleValueInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseDoubleValueInitializer.java new file mode 100644 index 0000000..9d2841b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseDoubleValueInitializer.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.entity.particle.initializer; + +import static org.anddev.andengine.util.MathUtils.RANDOM; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 15:58:29 - 04.05.2010 + */ +public abstract class BaseDoubleValueInitializer extends BaseSingleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mMinValueB; + protected float mMaxValueB; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseDoubleValueInitializer(final float pMinValueA, final float pMaxValueA, final float pMinValueB, final float pMaxValueB) { + super(pMinValueA, pMaxValueA); + this.mMinValueB = pMinValueB; + this.mMaxValueB = pMaxValueB; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onInitializeParticle(final Particle pParticle, final float pValueA, final float pValueB); + + @Override + protected final void onInitializeParticle(final Particle pParticle, final float pValueA) { + this.onInitializeParticle(pParticle, pValueA, this.getRandomValueB()); + } + + // =========================================================== + // Methods + // =========================================================== + + private final float getRandomValueB() { + if(this.mMinValueB == this.mMaxValueB) { + return this.mMaxValueB; + } else { + return RANDOM.nextFloat() * (this.mMaxValueB - this.mMinValueB) + this.mMinValueB; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseSingleValueInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseSingleValueInitializer.java new file mode 100644 index 0000000..e4c1c05 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseSingleValueInitializer.java @@ -0,0 +1,62 @@ +package org.anddev.andengine.entity.particle.initializer; + +import static org.anddev.andengine.util.MathUtils.RANDOM; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 10:18:06 - 29.06.2010 + */ +public abstract class BaseSingleValueInitializer implements IParticleInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mMinValue; + protected float mMaxValue; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseSingleValueInitializer(final float pMinValue, final float pMaxValue) { + this.mMinValue = pMinValue; + this.mMaxValue = pMaxValue; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onInitializeParticle(final Particle pParticle, final float pValue); + + @Override + public final void onInitializeParticle(final Particle pParticle) { + this.onInitializeParticle(pParticle, this.getRandomValue()); + } + + // =========================================================== + // Methods + // =========================================================== + + private final float getRandomValue() { + if(this.mMinValue == this.mMaxValue) { + return this.mMaxValue; + } else { + return RANDOM.nextFloat() * (this.mMaxValue - this.mMinValue) + this.mMinValue; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseTripleValueInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseTripleValueInitializer.java new file mode 100644 index 0000000..369f2cf --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/BaseTripleValueInitializer.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.entity.particle.initializer; + +import static org.anddev.andengine.util.MathUtils.RANDOM; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 15:58:29 - 04.05.2010 + */ +public abstract class BaseTripleValueInitializer extends BaseDoubleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mMinValueC; + protected float mMaxValueC; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTripleValueInitializer(final float pMinValueA, final float pMaxValueA, final float pMinValueB, final float pMaxValueB, final float pMinValueC, final float pMaxValueC) { + super(pMinValueA, pMaxValueA, pMinValueB, pMaxValueB); + this.mMinValueC = pMinValueC; + this.mMaxValueC = pMaxValueC; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onInitializeParticle(final Particle pParticle, final float pValueA, final float pValueB, final float pValueC); + + @Override + protected final void onInitializeParticle(final Particle pParticle, final float pValueA, final float pValueB) { + this.onInitializeParticle(pParticle, pValueA, pValueB, this.getRandomValueC()); + } + + // =========================================================== + // Methods + // =========================================================== + + private final float getRandomValueC() { + if(this.mMinValueC == this.mMaxValueC) { + return this.mMaxValueC; + } else { + return RANDOM.nextFloat() * (this.mMaxValueC - this.mMinValueC) + this.mMinValueC; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/ColorInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/ColorInitializer.java new file mode 100644 index 0000000..75c5a7b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/ColorInitializer.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.particle.initializer; + +import org.anddev.andengine.entity.particle.Particle; + + +/** + * @author Nicolas Gramlich + * @since 10:17:42 - 29.06.2010 + */ +public class ColorInitializer extends BaseTripleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ColorInitializer(final float pRed, final float pGreen, final float pBlue) { + super(pRed, pRed, pGreen, pGreen, pBlue, pBlue); + } + + public ColorInitializer(final float pMinRed, final float pMaxRed, final float pMinGreen, final float pMaxGreen, final float pMinBlue, final float pMaxBlue) { + super(pMinRed, pMaxRed, pMinGreen, pMaxGreen, pMinBlue, pMaxBlue); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onInitializeParticle(final Particle pParticle, final float pRed, final float pGreen, final float pBlue) { + pParticle.setColor(pRed, pGreen, pBlue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/GravityInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/GravityInitializer.java new file mode 100644 index 0000000..769447e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/GravityInitializer.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.entity.particle.initializer; + +import android.hardware.SensorManager; + +/** + * @author Nicolas Gramlich + * @since 12:04:00 - 15.03.2010 + */ +public class GravityInitializer extends AccelerationInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public GravityInitializer() { + super(0, SensorManager.GRAVITY_EARTH); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/IParticleInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/IParticleInitializer.java new file mode 100644 index 0000000..dca6467 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/IParticleInitializer.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.entity.particle.initializer; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 10:12:09 - 29.06.2010 + */ +public interface IParticleInitializer { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onInitializeParticle(final Particle pParticle); +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/RotationInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/RotationInitializer.java new file mode 100644 index 0000000..30113d9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/RotationInitializer.java @@ -0,0 +1,68 @@ +package org.anddev.andengine.entity.particle.initializer; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 10:17:42 - 29.06.2010 + */ +public class RotationInitializer extends BaseSingleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RotationInitializer(final float pRotation) { + this(pRotation, pRotation); + } + + public RotationInitializer(final float pMinRotation, final float pMaxRotation) { + super(pMinRotation, pMaxRotation); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getMinRotation() { + return this.mMinValue; + } + + public float getMaxRotation() { + return this.mMaxValue; + } + + public void setRotation(final float pRotation) { + this.mMinValue = pRotation; + this.mMaxValue = pRotation; + } + + public void setRotation(final float pMinRotation, final float pMaxRotation) { + this.mMinValue = pMinRotation; + this.mMaxValue = pMaxRotation; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onInitializeParticle(final Particle pParticle, final float pRotation) { + pParticle.setRotation(pRotation); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/initializer/VelocityInitializer.java b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/VelocityInitializer.java new file mode 100644 index 0000000..fb9f7c2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/initializer/VelocityInitializer.java @@ -0,0 +1,97 @@ +package org.anddev.andengine.entity.particle.initializer; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 21:21:10 - 14.03.2010 + */ +public class VelocityInitializer extends BaseDoubleValueInitializer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public VelocityInitializer(final float pVelocity) { + this(pVelocity, pVelocity, pVelocity, pVelocity); + } + + public VelocityInitializer(final float pVelocityX, final float pVelocityY) { + this(pVelocityX, pVelocityX, pVelocityY, pVelocityY); + } + + public VelocityInitializer(final float pMinVelocityX, final float pMaxVelocityX, final float pMinVelocityY, final float pMaxVelocityY) { + super(pMinVelocityX, pMaxVelocityX, pMinVelocityY, pMaxVelocityY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getMinVelocityX() { + return this.mMinValue; + } + + public float getMaxVelocityX() { + return this.mMaxValue; + } + + public float getMinVelocityY() { + return this.mMinValueB; + } + + public float getMaxVelocityY() { + return this.mMaxValueB; + } + + public void setVelocityX(final float pVelocityX) { + this.mMinValue = pVelocityX; + this.mMaxValue = pVelocityX; + } + + public void setVelocityY(final float pVelocityY) { + this.mMinValueB = pVelocityY; + this.mMaxValueB = pVelocityY; + } + + public void setVelocityX(final float pMinVelocityX, final float pMaxVelocityX) { + this.mMinValue = pMinVelocityX; + this.mMaxValue = pMaxVelocityX; + } + + public void setVelocityY(final float pMinVelocityY, final float pMaxVelocityY) { + this.mMinValueB = pMinVelocityY; + this.mMaxValueB = pMaxVelocityY; + } + + public void setVelocity(final float pMinVelocityX, final float pMaxVelocityX, final float pMinVelocityY, final float pMaxVelocityY) { + this.mMinValue = pMinVelocityX; + this.mMaxValue = pMaxVelocityX; + this.mMinValueB = pMinVelocityY; + this.mMaxValueB = pMaxVelocityY; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onInitializeParticle(final Particle pParticle, final float pVelocityX, final float pVelocityY) { + pParticle.getPhysicsHandler().setVelocity(pVelocityX, pVelocityY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/AlphaModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/AlphaModifier.java new file mode 100644 index 0000000..1529a73 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/AlphaModifier.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 21:21:10 - 14.03.2010 + */ +public class AlphaModifier extends BaseSingleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public AlphaModifier(final float pFromAlpha, final float pToAlpha, final float pFromTime, final float pToTime) { + super(pFromAlpha, pToAlpha, pFromTime, pToTime); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValue(final Particle pParticle, final float pAlpha) { + pParticle.setAlpha(pAlpha); + } + + @Override + protected void onSetValue(final Particle pParticle, final float pAlpha) { + pParticle.setAlpha(pAlpha); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseDoubleValueSpanModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseDoubleValueSpanModifier.java new file mode 100644 index 0000000..7bf67d2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseDoubleValueSpanModifier.java @@ -0,0 +1,71 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 15:19:46 - 29.06.2010 + */ +public abstract class BaseDoubleValueSpanModifier extends BaseSingleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mFromValueB; + private final float mToValueB; + + private final float mSpanValueB; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseDoubleValueSpanModifier(final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final float pFromTime, final float pToTime) { + super(pFromValueA, pToValueA, pFromTime, pToTime); + this.mFromValueB = pFromValueB; + this.mToValueB = pToValueB; + + this.mSpanValueB = this.mToValueB - this.mFromValueB; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + @Deprecated + protected void onSetValue(final Particle pParticle, final float pValue) { } + + protected abstract void onSetInitialValues(final Particle pParticle, final float pValueA, final float pValueB); + protected abstract void onSetValues(final Particle pParticle, final float pValueA, final float pValueB); + + @Override + public void onSetInitialValue(final Particle pParticle, final float pValueA) { + this.onSetInitialValues(pParticle, pValueA, this.mFromValueB); + } + + @Override + protected void onSetValueInternal(final Particle pParticle, final float pPercent) { + this.onSetValues(pParticle, super.calculateValue(pPercent), this.calculateValueB(pPercent)); + } + + // =========================================================== + // Methods + // =========================================================== + + protected final float calculateValueB(final float pPercent) { + return this.mFromValueB + this.mSpanValueB * pPercent; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseSingleValueSpanModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseSingleValueSpanModifier.java new file mode 100644 index 0000000..e701603 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseSingleValueSpanModifier.java @@ -0,0 +1,81 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 16:10:16 - 04.05.2010 + */ +public abstract class BaseSingleValueSpanModifier implements IParticleModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mFromValue; + private final float mToValue; + + private final float mFromTime; + private final float mToTime; + + private final float mDuration; + private final float mSpanValue; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseSingleValueSpanModifier(final float pFromValue, final float pToValue, final float pFromTime, final float pToTime) { + this.mFromValue = pFromValue; + this.mToValue = pToValue; + this.mFromTime = pFromTime; + this.mToTime = pToTime; + + this.mSpanValue = this.mToValue - this.mFromValue; + this.mDuration = this.mToTime - this.mFromTime; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onSetInitialValue(final Particle pParticle, final float pValue); + protected abstract void onSetValue(final Particle pParticle, final float pValue); + + @Override + public void onInitializeParticle(final Particle pParticle) { + this.onSetInitialValue(pParticle, this.mFromValue); + } + + @Override + public void onUpdateParticle(final Particle pParticle) { + final float lifeTime = pParticle.getLifeTime(); + if(lifeTime > this.mFromTime && lifeTime < this.mToTime) { + final float percent = (lifeTime - this.mFromTime) / this.mDuration; + this.onSetValueInternal(pParticle, percent); + } + } + + protected void onSetValueInternal(final Particle pParticle, final float pPercent) { + this.onSetValue(pParticle, this.calculateValue(pPercent)); + } + + protected final float calculateValue(final float pPercent) { + return this.mFromValue + this.mSpanValue * pPercent; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseTripleValueSpanModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseTripleValueSpanModifier.java new file mode 100644 index 0000000..2df6adb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/BaseTripleValueSpanModifier.java @@ -0,0 +1,71 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 15:19:46 - 29.06.2010 + */ +public abstract class BaseTripleValueSpanModifier extends BaseDoubleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mFromValueC; + private final float mToValueC; + + private final float mSpanValueC; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTripleValueSpanModifier(final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final float pFromValueC, final float pToValueC, final float pFromTime, final float pToTime) { + super(pFromValueA, pToValueA, pFromValueB, pToValueB, pFromTime, pToTime); + this.mFromValueC = pFromValueC; + this.mToValueC = pToValueC; + + this.mSpanValueC = this.mToValueC - this.mFromValueC; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onSetInitialValues(final Particle pParticle, final float pValueA, final float pValueB, final float pValueC); + protected abstract void onSetValues(final Particle pParticle, final float pValueA, final float pValueB, final float pValueC); + + @Override + @Deprecated + protected void onSetValues(final Particle pParticle, final float pValueA, final float pValueB) { } + + @Override + public void onSetInitialValues(final Particle pParticle, final float pValueA, final float pValueB) { + this.onSetInitialValues(pParticle, pValueA, pValueB, this.mFromValueC); + } + + @Override + protected void onSetValueInternal(final Particle pParticle, final float pPercent) { + this.onSetValues(pParticle, super.calculateValue(pPercent), super.calculateValueB(pPercent), this.calculateValueC(pPercent)); + } + + // =========================================================== + // Methods + // =========================================================== + + private final float calculateValueC(final float pPercent) { + return this.mFromValueC + this.mSpanValueC * pPercent; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ColorModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ColorModifier.java new file mode 100644 index 0000000..f9ee3f2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ColorModifier.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 15:22:26 - 29.06.2010 + */ +public class ColorModifier extends BaseTripleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ColorModifier(final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final float pFromTime, final float pToTime) { + super(pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, pFromTime, pToTime); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValues(final Particle pParticle, final float pRed, final float pGreen, final float pBlue) { + pParticle.setColor(pRed, pGreen, pBlue); + } + + @Override + protected void onSetValues(final Particle pParticle, final float pRed, final float pGreen, final float pBlue) { + pParticle.setColor(pRed, pGreen, pBlue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ExpireModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ExpireModifier.java new file mode 100644 index 0000000..8ed2b9e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ExpireModifier.java @@ -0,0 +1,79 @@ +package org.anddev.andengine.entity.particle.modifier; + +import static org.anddev.andengine.util.MathUtils.RANDOM; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 21:21:10 - 14.03.2010 + */ +public class ExpireModifier implements IParticleModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mMinLifeTime; + private float mMaxLifeTime; + + // =========================================================== + // Constructors + // =========================================================== + + public ExpireModifier(final float pLifeTime) { + this(pLifeTime, pLifeTime); + } + + public ExpireModifier(final float pMinLifeTime, final float pMaxLifeTime) { + this.mMinLifeTime = pMinLifeTime; + this.mMaxLifeTime = pMaxLifeTime; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getMinLifeTime() { + return this.mMinLifeTime; + } + + public float getMaxLifeTime() { + return this.mMaxLifeTime; + } + + public void setLifeTime(final float pLifeTime) { + this.mMinLifeTime = pLifeTime; + this.mMaxLifeTime = pLifeTime; + } + + public void setLifeTime(final float pMinLifeTime, final float pMaxLifeTime) { + this.mMinLifeTime = pMinLifeTime; + this.mMaxLifeTime = pMaxLifeTime; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onInitializeParticle(final Particle pParticle) { + pParticle.setDeathTime((RANDOM.nextFloat() * (this.mMaxLifeTime - this.mMinLifeTime) + this.mMinLifeTime)); + } + + @Override + public void onUpdateParticle(final Particle pParticle) { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/IParticleModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/IParticleModifier.java new file mode 100644 index 0000000..4903c46 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/IParticleModifier.java @@ -0,0 +1,20 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; +import org.anddev.andengine.entity.particle.initializer.IParticleInitializer; + +/** + * @author Nicolas Gramlich + * @since 20:06:05 - 14.03.2010 + */ +public interface IParticleModifier extends IParticleInitializer { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onUpdateParticle(final Particle pParticle); +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/OffCameraExpireModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/OffCameraExpireModifier.java new file mode 100644 index 0000000..ce01e77 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/OffCameraExpireModifier.java @@ -0,0 +1,61 @@ +package org.anddev.andengine.entity.particle.modifier; + + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 21:21:10 - 14.03.2010 + */ +public class OffCameraExpireModifier implements IParticleModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Camera mCamera; + + // =========================================================== + // Constructors + // =========================================================== + + public OffCameraExpireModifier(final Camera pCamera) { + this.mCamera = pCamera; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Camera getCamera() { + return this.mCamera; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onInitializeParticle(final Particle pParticle) { + + } + + @Override + public void onUpdateParticle(final Particle pParticle) { + if(!this.mCamera.isRectangularShapeVisible(pParticle)) { + pParticle.setDead(true); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/RotationModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/RotationModifier.java new file mode 100644 index 0000000..ba6cd35 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/RotationModifier.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 10:36:18 - 29.06.2010 + */ +public class RotationModifier extends BaseSingleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RotationModifier(final float pFromRotation, final float pToRotation, final float pFromTime, final float pToTime) { + super(pFromRotation, pToRotation, pFromTime, pToTime); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValue(final Particle pParticle, final float pRotation) { + pParticle.setRotation(pRotation); + } + + @Override + protected void onSetValue(final Particle pParticle, final float pRotation) { + pParticle.setRotation(pRotation); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ScaleModifier.java b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ScaleModifier.java new file mode 100644 index 0000000..e824830 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/particle/modifier/ScaleModifier.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.particle.modifier; + +import org.anddev.andengine.entity.particle.Particle; + +/** + * @author Nicolas Gramlich + * @since 20:37:27 - 04.05.2010 + */ +public class ScaleModifier extends BaseDoubleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ScaleModifier(final float pFromScale, final float pToScale, final float pFromTime, final float pToTime) { + this(pFromScale, pToScale, pFromScale, pToScale, pFromTime, pToTime); + } + + public ScaleModifier(final float pFromScaleX, final float pToScaleX, final float pFromScaleY, final float pToScaleY, final float pFromTime, final float pToTime) { + super(pFromScaleX, pToScaleX, pFromScaleY, pToScaleY, pFromTime, pToTime); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValues(final Particle pParticle, final float pScaleX, final float pScaleY) { + pParticle.setScale(pScaleX, pScaleY); + } + + @Override + protected void onSetValues(final Particle pParticle, final float pScaleX, final float pScaleY) { + pParticle.setScale(pScaleX, pScaleY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/primitive/BaseRectangle.java b/AndEngine/src/org/anddev/andengine/entity/primitive/BaseRectangle.java new file mode 100644 index 0000000..e9e2afc --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/primitive/BaseRectangle.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.entity.primitive; + +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.entity.shape.RectangularShape; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 19:05:49 - 11.04.2010 + */ +public abstract class BaseRectangle extends RectangularShape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public BaseRectangle(final float pX, final float pY, final float pWidth, final float pHeight) { + super(pX, pY, pWidth, pHeight, new RectangleVertexBuffer(GL11.GL_STATIC_DRAW)); + this.updateVertexBuffer(); + } + + public BaseRectangle(final float pX, final float pY, final float pWidth, final float pHeight, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pWidth, pHeight, pRectangleVertexBuffer); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public RectangleVertexBuffer getVertexBuffer() { + return (RectangleVertexBuffer)super.getVertexBuffer(); + } + + @Override + protected void onUpdateVertexBuffer(){ + this.getVertexBuffer().update(this.mWidth, this.mHeight); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/primitive/Line.java b/AndEngine/src/org/anddev/andengine/entity/primitive/Line.java new file mode 100644 index 0000000..ba172b5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/primitive/Line.java @@ -0,0 +1,229 @@ +package org.anddev.andengine.entity.primitive; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.collision.LineCollisionChecker; +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.shape.IShape; +import org.anddev.andengine.entity.shape.Shape; +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.opengl.vertex.LineVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 09:50:36 - 04.04.2010 + */ +public class Line extends Shape { + // =========================================================== + // Constants + // =========================================================== + + private static final float LINEWIDTH_DEFAULT = 1.0f; + + // =========================================================== + // Fields + // =========================================================== + + protected float mX2; + protected float mY2; + + private float mLineWidth; + + private final LineVertexBuffer mLineVertexBuffer; + + // =========================================================== + // Constructors + // =========================================================== + + public Line(final float pX1, final float pY1, final float pX2, final float pY2) { + this(pX1, pY1, pX2, pY2, LINEWIDTH_DEFAULT); + } + + public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth) { + super(pX1, pY1); + + this.mX2 = pX2; + this.mY2 = pY2; + + this.mLineWidth = pLineWidth; + + this.mLineVertexBuffer = new LineVertexBuffer(GL11.GL_STATIC_DRAW); + BufferObjectManager.getActiveInstance().loadBufferObject(this.mLineVertexBuffer); + this.updateVertexBuffer(); + + final float width = this.getWidth(); + final float height = this.getHeight(); + + this.mRotationCenterX = width * 0.5f; + this.mRotationCenterY = height * 0.5f; + + this.mScaleCenterX = this.mRotationCenterX; + this.mScaleCenterY = this.mRotationCenterY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * @deprecated Instead use {@link Line#getX1()} or {@link Line#getX2()}. + */ + @Deprecated + @Override + public float getX() { + return super.getX(); + } + + /** + * @deprecatedInstead use {@link Line#getY1()} or {@link Line#getY2()}. + */ + @Deprecated + @Override + public float getY() { + return super.getY(); + } + + public float getX1() { + return super.getX(); + } + + public float getY1() { + return super.getY(); + } + + public float getX2() { + return this.mX2; + } + + public float getY2() { + return this.mY2; + } + + public float getLineWidth() { + return this.mLineWidth; + } + + public void setLineWidth(final float pLineWidth) { + this.mLineWidth = pLineWidth; + } + + @Override + public float getBaseHeight() { + return this.mY2 - this.mY; + } + + @Override + public float getBaseWidth() { + return this.mX2 - this.mX; + } + + @Override + public float getHeight() { + return this.mY2 - this.mY; + } + + @Override + public float getWidth() { + return this.mX2 - this.mX; + } + + /** + * @deprecated Instead use {@link Line#setPosition(float, float, float, float)}. + */ + @Deprecated + @Override + public void setPosition(final float pX, final float pY) { + final float dX = this.mX - pX; + final float dY = this.mY - pY; + + super.setPosition(pX, pY); + + this.mX2 += dX; + this.mY2 += dY; + } + + public void setPosition(final float pX1, final float pY1, final float pX2, final float pY2) { + this.mX2 = pX2; + this.mY2 = pY2; + + super.setPosition(pX1, pY1); + + this.updateVertexBuffer(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected boolean isCulled(final Camera pCamera) { + return false; // TODO + } + + @Override + protected void onInitDraw(final GL10 pGL) { + super.onInitDraw(pGL); + GLHelper.disableTextures(pGL); + GLHelper.disableTexCoordArray(pGL); + GLHelper.lineWidth(pGL, this.mLineWidth); + } + + @Override + public LineVertexBuffer getVertexBuffer() { + return this.mLineVertexBuffer; + } + + @Override + protected void onUpdateVertexBuffer() { + this.mLineVertexBuffer.update(0, 0, this.mX2 - this.mX, this.mY2 - this.mY); + } + + @Override + protected void drawVertices(final GL10 pGL, final Camera pCamera) { + pGL.glDrawArrays(GL10.GL_LINES, 0, LineVertexBuffer.VERTICES_PER_LINE); + } + + @Override + public float[] getSceneCenterCoordinates() { + return null; // TODO + // return convertLocalToSceneCoordinates(this, (this.mX + this.mX2) * 0.5f, (this.mY + this.mY2) * 0.5f); + } + + @Override + @Deprecated + public boolean contains(final float pX, final float pY) { + return false; + } + + @Override + @Deprecated + public float[] convertSceneToLocalCoordinates(final float pX, final float pY) { + return null; + } + + @Override + @Deprecated + public float[] convertLocalToSceneCoordinates(final float pX, final float pY) { + return null; + } + + @Override + public boolean collidesWith(final IShape pOtherShape) { + if(pOtherShape instanceof Line) { + final Line otherLine = (Line)pOtherShape; + return LineCollisionChecker.checkLineCollision(this.mX, this.mY, this.mX2, this.mY2, otherLine.mX, otherLine.mY, otherLine.mX2, otherLine.mY2); + } else { + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/primitive/Rectangle.java b/AndEngine/src/org/anddev/andengine/entity/primitive/Rectangle.java new file mode 100644 index 0000000..ade3177 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/primitive/Rectangle.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.primitive; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 12:18:49 - 13.03.2010 + */ +public class Rectangle extends BaseRectangle { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public Rectangle(final float pX, final float pY, final float pWidth, final float pHeight) { + super(pX, pY, pWidth, pHeight); + } + + public Rectangle(final float pX, final float pY, final float pWidth, final float pHeight, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pWidth, pHeight, pRectangleVertexBuffer); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onInitDraw(final GL10 pGL) { + super.onInitDraw(pGL); + GLHelper.disableTextures(pGL); + GLHelper.disableTexCoordArray(pGL); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/CameraScene.java b/AndEngine/src/org/anddev/andengine/entity/scene/CameraScene.java new file mode 100644 index 0000000..ce1a4a5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/CameraScene.java @@ -0,0 +1,125 @@ +package org.anddev.andengine.entity.scene; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.shape.Shape; +import org.anddev.andengine.input.touch.TouchEvent; + +/** + * @author Nicolas Gramlich + * @since 15:35:53 - 29.03.2010 + */ +public class CameraScene extends Scene { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected Camera mCamera; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * {@link CameraScene#setCamera(Camera)} needs to be called manually. Otherwise nothing will be drawn. + */ + public CameraScene(final int pLayerCount) { + this(pLayerCount, null); + } + + public CameraScene(final int pLayerCount, final Camera pCamera) { + super(pLayerCount); + this.mCamera = pCamera; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Camera getCamera() { + return this.mCamera; + } + + public void setCamera(final Camera pCamera) { + this.mCamera = pCamera; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onSceneTouchEvent(final TouchEvent pSceneTouchEvent) { + if(this.mCamera == null) { + return false; + } else { + this.mCamera.convertSceneToCameraSceneTouchEvent(pSceneTouchEvent); + + final boolean handled = super.onSceneTouchEvent(pSceneTouchEvent); + + if(handled) { + return true; + } else { + this.mCamera.convertCameraSceneToSceneTouchEvent(pSceneTouchEvent); + return false; + } + } + } + + @Override + protected boolean onChildSceneTouchEvent(final TouchEvent pSceneTouchEvent) { + final boolean childIsCameraScene = this.mChildScene instanceof CameraScene; + if(childIsCameraScene) { + this.mCamera.convertCameraSceneToSceneTouchEvent(pSceneTouchEvent); + final boolean result = super.onChildSceneTouchEvent(pSceneTouchEvent); + this.mCamera.convertSceneToCameraSceneTouchEvent(pSceneTouchEvent); + return result; + } else { + return super.onChildSceneTouchEvent(pSceneTouchEvent); + } + } + + @Override + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + if(this.mCamera != null) { + pGL.glMatrixMode(GL10.GL_PROJECTION); + this.mCamera.onApplyCameraSceneMatrix(pGL); + { + pGL.glMatrixMode(GL10.GL_MODELVIEW); + pGL.glPushMatrix(); + pGL.glLoadIdentity(); + + super.onManagedDraw(pGL, pCamera); + + pGL.glPopMatrix(); + } + pGL.glMatrixMode(GL10.GL_PROJECTION); + } + } + + // =========================================================== + // Methods + // =========================================================== + + public void centerShapeInCamera(final Shape pShape) { + final Camera camera = this.mCamera; + pShape.setPosition((camera.getWidth() - pShape.getWidth()) * 0.5f, (camera.getHeight() - pShape.getHeight()) * 0.5f); + } + + public void centerShapeInCameraHorizontally(final Shape pShape) { + pShape.setPosition((this.mCamera.getWidth() - pShape.getWidth()) * 0.5f, pShape.getY()); + } + + public void centerShapeInCameraVertically(final Shape pShape) { + pShape.setPosition(pShape.getX(), (this.mCamera.getHeight() - pShape.getHeight()) * 0.5f); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/Scene.java b/AndEngine/src/org/anddev/andengine/entity/scene/Scene.java new file mode 100644 index 0000000..61fbc4b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/Scene.java @@ -0,0 +1,485 @@ +package org.anddev.andengine.entity.scene; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.handler.runnable.RunnableHandler; +import org.anddev.andengine.entity.Entity; +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.entity.layer.Layer; +import org.anddev.andengine.entity.layer.ZIndexSorter; +import org.anddev.andengine.entity.scene.Scene.ITouchArea.ITouchAreaMatcher; +import org.anddev.andengine.entity.scene.background.ColorBackground; +import org.anddev.andengine.entity.scene.background.IBackground; +import org.anddev.andengine.entity.shape.Shape; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.util.IMatcher; +import org.anddev.andengine.util.SmartList; +import org.anddev.andengine.util.constants.Constants; + +import android.util.SparseArray; +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 12:47:39 - 08.03.2010 + */ +public class Scene extends Entity { + // =========================================================== + // Constants + // =========================================================== + + private static final int TOUCHAREAS_CAPACITY_DEFAULT = 4; + + // =========================================================== + // Fields + // =========================================================== + + private float mSecondsElapsedTotal; + + protected Scene mParentScene; + protected Scene mChildScene; + private boolean mChildSceneModalDraw; + private boolean mChildSceneModalUpdate; + private boolean mChildSceneModalTouch; + + protected SmartList mTouchAreas = new SmartList(TOUCHAREAS_CAPACITY_DEFAULT); + + private final RunnableHandler mRunnableHandler = new RunnableHandler(); + + private IOnSceneTouchListener mOnSceneTouchListener; + + private IOnAreaTouchListener mOnAreaTouchListener; + + private IBackground mBackground = new ColorBackground(0, 0, 0); // Black + private boolean mBackgroundEnabled = true; + + private boolean mOnAreaTouchTraversalBackToFront = true; + + private boolean mTouchAreaBindingEnabled = false; + private final SparseArray mTouchAreaBindings = new SparseArray(); + + // =========================================================== + // Constructors + // =========================================================== + + public Scene(final int pLayerCount) { + super(0, 0); + for(int i = pLayerCount - 1; i >= 0; i--) { + this.attachChild(new Layer()); + } + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getSecondsElapsedTotal() { + return this.mSecondsElapsedTotal; + } + + public IBackground getBackground() { + return this.mBackground; + } + + public void setBackground(final IBackground pBackground) { + this.mBackground = pBackground; + } + + /** + * @deprecated Instead use {@link Scene#getChild(int)}. + */ + @Deprecated + public Layer getLayer(final int pLayerIndex) throws ArrayIndexOutOfBoundsException { + return (Layer) this.getChild(pLayerIndex); + } + + /** + * @deprecated Instead use {@link Scene#getChildCount()}. + */ + @Deprecated + public int getLayerCount() { + return this.getChildCount(); + } + + /** + * @deprecated Instead use {@link Scene#getFirstChild()} + */ + @Deprecated + public Layer getBottomLayer() { + return (Layer) this.getFirstChild(); + } + + /** + * @deprecated Instead use {@link Scene#getLastChild()}. + */ + @Deprecated + public Layer getTopLayer() { + return (Layer) this.getLastChild(); + } + + /** + * Sorts the {@link Layer} based on their ZIndex. Sort is stable. + */ + public void sortLayers() { + ZIndexSorter.getInstance().sort(this.mChildren); + } + + public boolean isBackgroundEnabled() { + return this.mBackgroundEnabled; + } + + public void setBackgroundEnabled(final boolean pEnabled) { + this.mBackgroundEnabled = pEnabled; + } + + public void setOnSceneTouchListener(final IOnSceneTouchListener pOnSceneTouchListener) { + this.mOnSceneTouchListener = pOnSceneTouchListener; + } + + public IOnSceneTouchListener getOnSceneTouchListener() { + return this.mOnSceneTouchListener; + } + + public boolean hasOnSceneTouchListener() { + return this.mOnSceneTouchListener != null; + } + + public void setOnAreaTouchListener(final IOnAreaTouchListener pOnAreaTouchListener) { + this.mOnAreaTouchListener = pOnAreaTouchListener; + } + + public IOnAreaTouchListener getOnAreaTouchListener() { + return this.mOnAreaTouchListener; + } + + public boolean hasOnAreaTouchListener() { + return this.mOnAreaTouchListener != null; + } + + private void setParentScene(final Scene pParentScene) { + this.mParentScene = pParentScene; + } + + public boolean hasChildScene() { + return this.mChildScene != null; + } + + public Scene getChildScene() { + return this.mChildScene; + } + + public void setChildSceneModal(final Scene pChildScene) { + this.setChildScene(pChildScene, true, true, true); + } + + public void setChildScene(final Scene pChildScene) { + this.setChildScene(pChildScene, false, false, false); + } + + public void setChildScene(final Scene pChildScene, final boolean pModalDraw, final boolean pModalUpdate, final boolean pModalTouch) { + pChildScene.setParentScene(this); + this.mChildScene = pChildScene; + this.mChildSceneModalDraw = pModalDraw; + this.mChildSceneModalUpdate = pModalUpdate; + this.mChildSceneModalTouch = pModalTouch; + } + + public void clearChildScene() { + this.mChildScene = null; + } + + public void setOnAreaTouchTraversalBackToFront() { + this.mOnAreaTouchTraversalBackToFront = true; + } + + public void setOnAreaTouchTraversalFrontToBack() { + this.mOnAreaTouchTraversalBackToFront = false; + } + + /** + * Enable or disable the binding of TouchAreas to PointerIDs (fingers). + * When enabled: TouchAreas get bound to a PointerID (finger) when returning true in + * {@link Shape#onAreaTouched(TouchEvent, float, float)} or + * {@link IOnAreaTouchListener#onAreaTouched(TouchEvent, ITouchArea, float, float)} + * with {@link MotionEvent#ACTION_DOWN}, they will receive all subsequent {@link TouchEvent}s + * that are made with the same PointerID (finger) + * even if the {@link TouchEvent} is outside of the actual {@link ITouchArea}! + * + * @param pTouchAreaBindingEnabled + */ + public void setTouchAreaBindingEnabled(final boolean pTouchAreaBindingEnabled) { + if(this.mTouchAreaBindingEnabled && !pTouchAreaBindingEnabled) { + this.mTouchAreaBindings.clear(); + } + this.mTouchAreaBindingEnabled = pTouchAreaBindingEnabled; + } + + public boolean isTouchAreaBindingEnabled() { + return this.mTouchAreaBindingEnabled; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + final Scene childScene = this.mChildScene; + + if(childScene == null || !this.mChildSceneModalDraw) { + if(this.mBackgroundEnabled) { + pCamera.onApplyPositionIndependentMatrix(pGL); + GLHelper.setModelViewIdentityMatrix(pGL); + + this.mBackground.onDraw(pGL, pCamera); + } + + pCamera.onApplyMatrix(pGL); + GLHelper.setModelViewIdentityMatrix(pGL); + + super.onManagedDraw(pGL, pCamera); + } + + if(childScene != null) { + childScene.onDraw(pGL, pCamera); + } + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + this.mSecondsElapsedTotal += pSecondsElapsed; + + this.mRunnableHandler.onUpdate(pSecondsElapsed); + + final Scene childScene = this.mChildScene; + if(childScene == null || !this.mChildSceneModalUpdate) { + this.mBackground.onUpdate(pSecondsElapsed); + super.onManagedUpdate(pSecondsElapsed); + } + + if(childScene != null) { + childScene.onUpdate(pSecondsElapsed); + } + } + + public boolean onSceneTouchEvent(final TouchEvent pSceneTouchEvent) { + final int action = pSceneTouchEvent.getAction(); + final boolean isActionDown = pSceneTouchEvent.isActionDown(); + + if(this.mTouchAreaBindingEnabled && !isActionDown) { + final SparseArray touchAreaBindings = this.mTouchAreaBindings; + final ITouchArea boundTouchArea = touchAreaBindings.get(pSceneTouchEvent.getPointerID()); + /* In the case a ITouchArea has been bound to this PointerID, + * we'll pass this this TouchEvent to the same ITouchArea. */ + if(boundTouchArea != null) { + final float sceneTouchEventX = pSceneTouchEvent.getX(); + final float sceneTouchEventY = pSceneTouchEvent.getY(); + + /* Check if boundTouchArea needs to be removed. */ + switch(action) { + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + touchAreaBindings.remove(pSceneTouchEvent.getPointerID()); + } + final Boolean handled = this.onAreaTouchEvent(pSceneTouchEvent, sceneTouchEventX, sceneTouchEventY, boundTouchArea); + if(handled != null && handled) { + return true; + } + } + } + + final Scene childScene = this.mChildScene; + if(childScene != null) { + final boolean handledByChild = this.onChildSceneTouchEvent(pSceneTouchEvent); + if(handledByChild) { + return true; + } else if(this.mChildSceneModalTouch) { + return false; + } + } + + final float sceneTouchEventX = pSceneTouchEvent.getX(); + final float sceneTouchEventY = pSceneTouchEvent.getY(); + + final ArrayList touchAreas = this.mTouchAreas; + if(touchAreas != null) { + final int touchAreaCount = touchAreas.size(); + if(touchAreaCount > 0) { + if(this.mOnAreaTouchTraversalBackToFront) { /* Back to Front. */ + for(int i = 0; i < touchAreaCount; i++) { + final ITouchArea touchArea = touchAreas.get(i); + if(touchArea.contains(sceneTouchEventX, sceneTouchEventY)) { + final Boolean handled = this.onAreaTouchEvent(pSceneTouchEvent, sceneTouchEventX, sceneTouchEventY, touchArea); + if(handled != null && handled) { + /* If binding of ITouchAreas is enabled and this is an ACTION_DOWN event, + * bind this ITouchArea to the PointerID. */ + if(this.mTouchAreaBindingEnabled && isActionDown) { + this.mTouchAreaBindings.put(pSceneTouchEvent.getPointerID(), touchArea); + } + return true; + } + } + } + } else { /* Front to back. */ + for(int i = touchAreaCount - 1; i >= 0; i--) { + final ITouchArea touchArea = touchAreas.get(i); + if(touchArea.contains(sceneTouchEventX, sceneTouchEventY)) { + final Boolean handled = this.onAreaTouchEvent(pSceneTouchEvent, sceneTouchEventX, sceneTouchEventY, touchArea); + if(handled != null && handled) { + /* If binding of ITouchAreas is enabled and this is an ACTION_DOWN event, + * bind this ITouchArea to the PointerID. */ + if(this.mTouchAreaBindingEnabled && isActionDown) { + this.mTouchAreaBindings.put(pSceneTouchEvent.getPointerID(), touchArea); + } + return true; + } + } + } + } + } + } + /* If no area was touched, the Scene itself was touched as a fallback. */ + if(this.mOnSceneTouchListener != null){ + return this.mOnSceneTouchListener.onSceneTouchEvent(this, pSceneTouchEvent); + } else { + return false; + } + } + + private Boolean onAreaTouchEvent(final TouchEvent pSceneTouchEvent, final float sceneTouchEventX, final float sceneTouchEventY, final ITouchArea touchArea) { + final float[] touchAreaLocalCoordinates = touchArea.convertSceneToLocalCoordinates(sceneTouchEventX, sceneTouchEventY); + final float touchAreaLocalX = touchAreaLocalCoordinates[Constants.VERTEX_INDEX_X]; + final float touchAreaLocalY = touchAreaLocalCoordinates[Constants.VERTEX_INDEX_Y]; + + final boolean handledSelf = touchArea.onAreaTouched(pSceneTouchEvent, touchAreaLocalX, touchAreaLocalY); + if(handledSelf) { + return Boolean.TRUE; + } else if(this.mOnAreaTouchListener != null) { + return this.mOnAreaTouchListener.onAreaTouched(pSceneTouchEvent, touchArea, touchAreaLocalX, touchAreaLocalY); + } else { + return null; + } + } + + protected boolean onChildSceneTouchEvent(final TouchEvent pSceneTouchEvent) { + return this.mChildScene.onSceneTouchEvent(pSceneTouchEvent); + } + + @Override + public void reset() { + super.reset(); + + this.clearChildScene(); + } + + @Override + public void setParent(final IEntity pEntity) { + // super.setParent(pEntity); + } + + // =========================================================== + // Methods + // =========================================================== + + public void postRunnable(final Runnable pRunnable) { + this.mRunnableHandler.postRunnable(pRunnable); + } + + public void registerTouchArea(final ITouchArea pTouchArea) { + this.mTouchAreas.add(pTouchArea); + } + + public boolean unregisterTouchArea(final ITouchArea pTouchArea) { + return this.mTouchAreas.remove(pTouchArea); + } + + public boolean unregisterTouchAreas(final ITouchAreaMatcher pTouchAreaMatcher) { + return this.mTouchAreas.removeAll(pTouchAreaMatcher); + } + + public void clearTouchAreas() { + this.mTouchAreas.clear(); + } + + public ArrayList getTouchAreas() { + return this.mTouchAreas; + } + + public void back() { + this.clearChildScene(); + + if(this.mParentScene != null) { + this.mParentScene.clearChildScene(); + this.mParentScene = null; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface ITouchArea { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean contains(final float pX, final float pY); + + public float[] convertSceneToLocalCoordinates(final float pX, final float pY); + public float[] convertLocalToSceneCoordinates(final float pX, final float pY); + + /** + * This method only fires if this {@link ITouchArea} is registered to the {@link Scene} via {@link Scene#registerTouchArea(ITouchArea)}. + * @param pSceneTouchEvent + * @return true if the event was handled (that means {@link IOnAreaTouchListener} of the {@link Scene} will not be fired!), otherwise false. + */ + public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY); + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ITouchAreaMatcher extends IMatcher { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } + } + + public static interface IOnAreaTouchListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final ITouchArea pTouchArea, final float pTouchAreaLocalX, final float pTouchAreaLocalY); + } + + public static interface IOnSceneTouchListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent); + } + +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/SplashScene.java b/AndEngine/src/org/anddev/andengine/entity/scene/SplashScene.java new file mode 100644 index 0000000..b476882 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/SplashScene.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.entity.scene; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.modifier.ScaleModifier; +import org.anddev.andengine.entity.sprite.Sprite; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 09:45:02 - 03.05.2010 + */ +public class SplashScene extends Scene { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SplashScene(final Camera pCamera, final TextureRegion pTextureRegion) { + this(pCamera, pTextureRegion, -1, 1, 1); + } + + public SplashScene(final Camera pCamera, final TextureRegion pTextureRegion, final float pDuration, final float pScaleFrom, final float pScaleTo) { + super(1); + + final Sprite loadingScreenSprite = new Sprite(pCamera.getMinX(), pCamera.getMinY(), pCamera.getWidth(), pCamera.getHeight(), pTextureRegion); + if(pScaleFrom != 1 || pScaleTo != 1) { + loadingScreenSprite.setScale(pScaleFrom); + loadingScreenSprite.registerEntityModifier(new ScaleModifier(pDuration, pScaleFrom, pScaleTo, IEaseFunction.DEFAULT)); + } + + this.getLastChild().attachChild(loadingScreenSprite); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/AutoParallaxBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/AutoParallaxBackground.java new file mode 100644 index 0000000..a6aa497 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/AutoParallaxBackground.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.entity.scene.background; + + + +/** + * @author Nicolas Gramlich + * @since 19:44:31 - 19.07.2010 + */ +public class AutoParallaxBackground extends ParallaxBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mParallaxChangePerSecond; + + // =========================================================== + // Constructors + // =========================================================== + + public AutoParallaxBackground(final float pRed, final float pGreen, final float pBlue, final float pParallaxChangePerSecond) { + super(pRed, pGreen, pBlue); + this.mParallaxChangePerSecond = pParallaxChangePerSecond; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + super.onUpdate(pSecondsElapsed); + + this.mParallaxValue += this.mParallaxChangePerSecond * pSecondsElapsed; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/BaseBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/BaseBackground.java new file mode 100644 index 0000000..b59e94d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/BaseBackground.java @@ -0,0 +1,67 @@ +package org.anddev.andengine.entity.scene.background; + +import org.anddev.andengine.util.modifier.IModifier; +import org.anddev.andengine.util.modifier.ModifierList; + + + +/** + * @author Nicolas Gramlich + * @since 14:08:17 - 19.07.2010 + */ +public abstract class BaseBackground implements IBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ModifierList mBackgroundModifiers = new ModifierList(this); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void addBackgroundModifier(final IModifier pBackgroundModifier) { + this.mBackgroundModifiers.add(pBackgroundModifier); + } + + @Override + public boolean removeBackgroundModifier(final IModifier pBackgroundModifier) { + return this.mBackgroundModifiers.remove(pBackgroundModifier); + } + + @Override + public void clearBackgroundModifiers() { + this.mBackgroundModifiers.clear(); + } + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mBackgroundModifiers.onUpdate(pSecondsElapsed); + } + + @Override + public void reset() { + this.mBackgroundModifiers.reset(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/ColorBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/ColorBackground.java new file mode 100644 index 0000000..43c251a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/ColorBackground.java @@ -0,0 +1,127 @@ +package org.anddev.andengine.entity.scene.background; + +import static org.anddev.andengine.util.constants.ColorConstants.COLOR_FACTOR_INT_TO_FLOAT; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; + +/** + * @author Nicolas Gramlich + * @since 13:45:24 - 19.07.2010 + */ +public class ColorBackground extends BaseBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mRed = 0.0f; + private float mGreen = 0.0f; + private float mBlue = 0.0f; + private float mAlpha = 1.0f; + + private boolean mColorEnabled = true; + + // =========================================================== + // Constructors + // =========================================================== + + protected ColorBackground() { + + } + + public ColorBackground(final float pRed, final float pGreen, final float pBlue) { + this.mRed = pRed; + this.mGreen = pGreen; + this.mBlue = pBlue; + } + + public ColorBackground(final float pRed, final float pGreen, final float pBlue, final float pAlpha) { + this.mRed = pRed; + this.mGreen = pGreen; + this.mBlue = pBlue; + this.mAlpha = pAlpha; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * Sets the color using the arithmetic scheme (0.0f - 1.0f RGB triple). + * @param pRed The red color value. Should be between 0.0 and 1.0, inclusive. + * @param pGreen The green color value. Should be between 0.0 and 1.0, inclusive. + * @param pBlue The blue color value. Should be between 0.0 and 1.0, inclusive. + */ + @Override + public void setColor(final float pRed, final float pGreen, final float pBlue) { + this.mRed = pRed; + this.mGreen = pGreen; + this.mBlue = pBlue; + } + + /** + * Sets the color using the arithmetic scheme (0.0f - 1.0f RGB quadruple). + * @param pRed The red color value. Should be between 0.0 and 1.0, inclusive. + * @param pGreen The green color value. Should be between 0.0 and 1.0, inclusive. + * @param pBlue The blue color value. Should be between 0.0 and 1.0, inclusive. + * @param pAlpha The alpha color value. Should be between 0.0 and 1.0, inclusive. + */ + @Override + public void setColor(final float pRed, final float pGreen, final float pBlue, final float pAlpha) { + this.setColor(pRed, pGreen, pBlue); + this.mAlpha = pAlpha; + } + + /** + * Sets the color using the digital 8-bit per channel scheme (0 - 255 RGB triple). + * @param pRed The red color value. Should be between 0 and 255, inclusive. + * @param pGreen The green color value. Should be between 0 and 255, inclusive. + * @param pBlue The blue color value. Should be between 0 and 255, inclusive. + */ + public void setColor(final int pRed, final int pGreen, final int pBlue) throws IllegalArgumentException { + this.setColor(pRed / COLOR_FACTOR_INT_TO_FLOAT, pGreen / COLOR_FACTOR_INT_TO_FLOAT, pBlue / COLOR_FACTOR_INT_TO_FLOAT); + } + + /** + * Sets the color using the digital 8-bit per channel scheme (0 - 255 RGB quadruple). + * @param pRed The red color value. Should be between 0 and 255, inclusive. + * @param pGreen The green color value. Should be between 0 and 255, inclusive. + * @param pBlue The blue color value. Should be between 0 and 255, inclusive. + */ + public void setColor(final int pRed, final int pGreen, final int pBlue, final int pAlpha) throws IllegalArgumentException { + this.setColor(pRed / COLOR_FACTOR_INT_TO_FLOAT, pGreen / COLOR_FACTOR_INT_TO_FLOAT, pBlue / COLOR_FACTOR_INT_TO_FLOAT, pAlpha / COLOR_FACTOR_INT_TO_FLOAT); + } + + public void setColorEnabled(final boolean pColorEnabled) { + this.mColorEnabled = pColorEnabled; + } + + public boolean isColorEnabled() { + return this.mColorEnabled; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDraw(final GL10 pGL, final Camera pCamera) { + if(this.mColorEnabled) { + pGL.glClearColor(this.mRed, this.mGreen, this.mBlue, this.mAlpha); + pGL.glClear(GL10.GL_COLOR_BUFFER_BIT); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/EntityBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/EntityBackground.java new file mode 100644 index 0000000..527883e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/EntityBackground.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.entity.scene.background; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.IEntity; + +/** + * @author Nicolas Gramlich + * @since 18:25:10 - 21.07.2010 + */ +public class EntityBackground extends ColorBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected IEntity mEntity; + + // =========================================================== + // Constructors + // =========================================================== + + public EntityBackground(final IEntity pEntity) { + this.mEntity = pEntity; + } + + public EntityBackground(final float pRed, final float pGreen, final float pBlue, final IEntity pEntity) { + super(pRed, pGreen, pBlue); + this.mEntity = pEntity; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDraw(final GL10 pGL, final Camera pCamera) { + super.onDraw(pGL, pCamera); + this.mEntity.onDraw(pGL, pCamera); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/IBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/IBackground.java new file mode 100644 index 0000000..f64b6d9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/IBackground.java @@ -0,0 +1,26 @@ +package org.anddev.andengine.entity.scene.background; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.opengl.IDrawable; +import org.anddev.andengine.util.modifier.IModifier; + +/** + * @author Nicolas Gramlich + * @since 13:47:41 - 19.07.2010 + */ +public interface IBackground extends IDrawable, IUpdateHandler { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void addBackgroundModifier(final IModifier pBackgroundModifier); + public boolean removeBackgroundModifier(final IModifier pBackgroundModifier); + public void clearBackgroundModifiers(); + + public void setColor(final float pRed, final float pGreen, final float pBlue); + public void setColor(final float pRed, final float pGreen, final float pBlue, final float pAlpha); +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/ParallaxBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/ParallaxBackground.java new file mode 100644 index 0000000..f828953 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/ParallaxBackground.java @@ -0,0 +1,142 @@ +package org.anddev.andengine.entity.scene.background; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.shape.Shape; + +/** + * @author Nicolas Gramlich + * @since 15:36:26 - 19.07.2010 + */ +public class ParallaxBackground extends ColorBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mParallaxEntities = new ArrayList(); + private int mParallaxEntityCount; + + protected float mParallaxValue; + + // =========================================================== + // Constructors + // =========================================================== + + public ParallaxBackground(final float pRed, final float pGreen, final float pBlue) { + super(pRed, pGreen, pBlue); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void setParallaxValue(final float pParallaxValue) { + this.mParallaxValue = pParallaxValue; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDraw(final GL10 pGL, final Camera pCamera) { + super.onDraw(pGL, pCamera); + + final float parallaxValue = this.mParallaxValue; + final ArrayList parallaxEntities = this.mParallaxEntities; + + for(int i = 0; i < this.mParallaxEntityCount; i++) { + parallaxEntities.get(i).onDraw(pGL, parallaxValue, pCamera); + } + } + + // =========================================================== + // Methods + // =========================================================== + + public void attachParallaxEntity(final ParallaxEntity pParallaxEntity) { + this.mParallaxEntities.add(pParallaxEntity); + this.mParallaxEntityCount++; + } + + public boolean detachParallaxEntity(final ParallaxEntity pParallaxEntity) { + this.mParallaxEntityCount--; + final boolean success = this.mParallaxEntities.remove(pParallaxEntity); + if(success == false) { + this.mParallaxEntityCount++; + } + return success; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class ParallaxEntity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + final float mParallaxFactor; + final Shape mShape; + + // =========================================================== + // Constructors + // =========================================================== + + public ParallaxEntity(final float pParallaxFactor, final Shape pShape) { + this.mParallaxFactor = pParallaxFactor; + this.mShape = pShape; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onDraw(final GL10 pGL, final float pParallaxValue, final Camera pCamera) { + pGL.glPushMatrix(); + { + final float cameraWidth = pCamera.getWidth(); + final float shapeWidthScaled = this.mShape.getWidthScaled(); + float baseOffset = (pParallaxValue * this.mParallaxFactor) % shapeWidthScaled; + + while(baseOffset > 0) { + baseOffset -= shapeWidthScaled; + } + pGL.glTranslatef(baseOffset, 0, 0); + + float currentMaxX = baseOffset; + + do { + this.mShape.onDraw(pGL, pCamera); + pGL.glTranslatef(shapeWidthScaled, 0, 0); + currentMaxX += shapeWidthScaled; + } while(currentMaxX < cameraWidth); + } + pGL.glPopMatrix(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/RepeatingSpriteBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/RepeatingSpriteBackground.java new file mode 100644 index 0000000..a32d43e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/RepeatingSpriteBackground.java @@ -0,0 +1,84 @@ +package org.anddev.andengine.entity.scene.background; + +import org.anddev.andengine.entity.sprite.Sprite; +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.TextureManager; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.texture.region.TextureRegionFactory; +import org.anddev.andengine.opengl.texture.source.ITextureSource; + +/** + * @author Nicolas Gramlich + * @since 15:11:10 - 19.07.2010 + */ +public class RepeatingSpriteBackground extends SpriteBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private Texture mTexture; + private final float mScale; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * @param pCameraWidth + * @param pCameraHeight + * @param pTextureManager + * @param pTextureSource needs to be a power of two as otherwise the repeating feature doesn't work. + */ + public RepeatingSpriteBackground(final float pCameraWidth, final float pCameraHeight, final TextureManager pTextureManager, final ITextureSource pTextureSource) throws IllegalArgumentException { + this(pCameraWidth, pCameraHeight, pTextureManager, pTextureSource, 1); + } + + public RepeatingSpriteBackground(final float pCameraWidth, final float pCameraHeight, final TextureManager pTextureManager, final ITextureSource pTextureSource, final float pScale) throws IllegalArgumentException { + super(null); + this.mScale = pScale; + this.mEntity = this.loadSprite(pCameraWidth, pCameraHeight, pTextureManager, pTextureSource); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Texture getTexture() { + return this.mTexture; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + private Sprite loadSprite(final float pCameraWidth, final float pCameraHeight, final TextureManager pTextureManager, final ITextureSource pTextureSource) throws IllegalArgumentException { + this.mTexture = new Texture(pTextureSource.getWidth(), pTextureSource.getHeight(), TextureOptions.REPEATING_PREMULTIPLYALPHA); + final TextureRegion textureRegion = TextureRegionFactory.createFromSource(this.mTexture, pTextureSource, 0, 0); + + final int width = Math.round(pCameraWidth / this.mScale); + final int height = Math.round(pCameraHeight / this.mScale); + + textureRegion.setWidth(width); + textureRegion.setHeight(height); + + pTextureManager.loadTexture(this.mTexture); + + final Sprite sprite = new Sprite(0, 0, width, height, textureRegion); + sprite.setScaleCenter(0, 0); + sprite.setScale(this.mScale); + return sprite; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/SpriteBackground.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/SpriteBackground.java new file mode 100644 index 0000000..8417dc1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/SpriteBackground.java @@ -0,0 +1,45 @@ +package org.anddev.andengine.entity.scene.background; + +import org.anddev.andengine.entity.sprite.BaseSprite; + +/** + * @author Nicolas Gramlich + * @since 14:01:43 - 19.07.2010 + */ +public class SpriteBackground extends EntityBackground { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SpriteBackground(final BaseSprite pBaseSprite) { + super(pBaseSprite); + } + + public SpriteBackground(final float pRed, final float pGreen, final float pBlue, final BaseSprite pBaseSprite) { + super(pRed, pGreen, pBlue, pBaseSprite); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/ColorModifier.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/ColorModifier.java new file mode 100644 index 0000000..75eebc9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/ColorModifier.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.entity.scene.background.modifier; + +import org.anddev.andengine.entity.scene.background.IBackground; +import org.anddev.andengine.util.modifier.BaseTripleValueSpanModifier; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 14:51:03 - 03.09.2010 + */ +public class ColorModifier extends BaseTripleValueSpanModifier implements IBackgroundModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue) { + this(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, null, IEaseFunction.DEFAULT); + } + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final IEaseFunction pEaseFunction) { + this(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, null, pEaseFunction); + } + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final IBackgroundModifierListener pBackgroundModifierListener) { + super(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, pBackgroundModifierListener, IEaseFunction.DEFAULT); + } + + public ColorModifier(final float pDuration, final float pFromRed, final float pToRed, final float pFromGreen, final float pToGreen, final float pFromBlue, final float pToBlue, final IBackgroundModifierListener pBackgroundModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromRed, pToRed, pFromGreen, pToGreen, pFromBlue, pToBlue, pBackgroundModifierListener, pEaseFunction); + } + + protected ColorModifier(final ColorModifier pColorModifier) { + super(pColorModifier); + } + + @Override + public ColorModifier clone(){ + return new ColorModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onSetInitialValues(final IBackground pBackground, final float pRed, final float pGreen, final float pBlue) { + pBackground.setColor(pRed, pGreen, pBlue); + } + + @Override + protected void onSetValues(final IBackground pBackground, final float pPerctentageDone, final float pRed, final float pGreen, final float pBlue) { + pBackground.setColor(pRed, pGreen, pBlue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/IBackgroundModifier.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/IBackgroundModifier.java new file mode 100644 index 0000000..336cb0c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/IBackgroundModifier.java @@ -0,0 +1,32 @@ +package org.anddev.andengine.entity.scene.background.modifier; + +import org.anddev.andengine.entity.scene.background.IBackground; +import org.anddev.andengine.util.modifier.IModifier; + +/** + * @author Nicolas Gramlich + * @since 14:55:54 - 03.09.2010 + */ +public interface IBackgroundModifier extends IModifier { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IBackgroundModifierListener extends IModifierListener{ + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/LoopBackgroundModifier.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/LoopBackgroundModifier.java new file mode 100644 index 0000000..6c7271c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/LoopBackgroundModifier.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.scene.background.modifier; + +import org.anddev.andengine.entity.scene.background.IBackground; +import org.anddev.andengine.util.modifier.LoopModifier; + +/** + * @author Nicolas Gramlich + * @since 15:03:53 - 03.09.2010 + */ +public class LoopBackgroundModifier extends LoopModifier implements IBackgroundModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public LoopBackgroundModifier(final IBackgroundModifier pBackgroundModifier) { + super(pBackgroundModifier); + } + + public LoopBackgroundModifier(final IBackgroundModifierListener pBackgroundModifierListener, final int pLoopCount, final ILoopBackgroundModifierListener pLoopModifierListener, final IBackgroundModifier pBackgroundModifier) { + super(pBackgroundModifierListener, pLoopCount, pLoopModifierListener, pBackgroundModifier); + } + + public LoopBackgroundModifier(final IBackgroundModifierListener pBackgroundModifierListener, final int pLoopCount, final IBackgroundModifier pBackgroundModifier) { + super(pBackgroundModifierListener, pLoopCount, pBackgroundModifier); + } + + public LoopBackgroundModifier(final int pLoopCount, final IBackgroundModifier pBackgroundModifier) { + super(pLoopCount, pBackgroundModifier); + } + + protected LoopBackgroundModifier(final LoopBackgroundModifier pLoopBackgroundModifier) { + super(pLoopBackgroundModifier); + } + + @Override + public LoopBackgroundModifier clone() { + return new LoopBackgroundModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ILoopBackgroundModifierListener extends ILoopModifierListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/ParallelBackgroundModifier.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/ParallelBackgroundModifier.java new file mode 100644 index 0000000..dcaabfd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/ParallelBackgroundModifier.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.entity.scene.background.modifier; + +import org.anddev.andengine.entity.scene.background.IBackground; +import org.anddev.andengine.util.modifier.ParallelModifier; + +/** + * @author Nicolas Gramlich + * @since 15:03:57 - 03.09.2010 + */ +public class ParallelBackgroundModifier extends ParallelModifier implements IBackgroundModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public ParallelBackgroundModifier(final IBackgroundModifier... pBackgroundModifiers) throws IllegalArgumentException { + super(pBackgroundModifiers); + } + + public ParallelBackgroundModifier(final IBackgroundModifierListener pBackgroundModifierListener, final IBackgroundModifier... pBackgroundModifiers) throws IllegalArgumentException { + super(pBackgroundModifierListener, pBackgroundModifiers); + } + + protected ParallelBackgroundModifier(final ParallelBackgroundModifier pParallelBackgroundModifier) { + super(pParallelBackgroundModifier); + } + + @Override + public ParallelBackgroundModifier clone() { + return new ParallelBackgroundModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/SequenceBackgroundModifier.java b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/SequenceBackgroundModifier.java new file mode 100644 index 0000000..df2ab10 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/background/modifier/SequenceBackgroundModifier.java @@ -0,0 +1,69 @@ +package org.anddev.andengine.entity.scene.background.modifier; + +import org.anddev.andengine.entity.scene.background.IBackground; +import org.anddev.andengine.util.modifier.SequenceModifier; + +/** + * @author Nicolas Gramlich + * @since 15:04:02 - 03.09.2010 + */ +public class SequenceBackgroundModifier extends SequenceModifier implements IBackgroundModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SequenceBackgroundModifier(final IBackgroundModifier... pBackgroundModifiers) throws IllegalArgumentException { + super(pBackgroundModifiers); + } + + public SequenceBackgroundModifier(final IBackgroundModifierListener pBackgroundModifierListener, final IBackgroundModifier... pBackgroundModifiers) throws IllegalArgumentException { + super(pBackgroundModifierListener, pBackgroundModifiers); + } + + public SequenceBackgroundModifier(final IBackgroundModifierListener pBackgroundModifierListener, final ISubSequenceBackgroundModifierListener pSubSequenceBackgroundModifierListener, final IBackgroundModifier... pBackgroundModifiers) throws IllegalArgumentException { + super(pBackgroundModifierListener, pSubSequenceBackgroundModifierListener, pBackgroundModifiers); + } + + protected SequenceBackgroundModifier(final SequenceBackgroundModifier pSequenceBackgroundModifier) { + super(pSequenceBackgroundModifier); + } + + @Override + public SequenceBackgroundModifier clone() { + return new SequenceBackgroundModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ISubSequenceBackgroundModifierListener extends ISubSequenceModifierListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/MenuScene.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/MenuScene.java new file mode 100644 index 0000000..bb1186b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/MenuScene.java @@ -0,0 +1,206 @@ +package org.anddev.andengine.entity.scene.menu; + +import java.util.ArrayList; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.scene.CameraScene; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.entity.scene.Scene.IOnAreaTouchListener; +import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener; +import org.anddev.andengine.entity.scene.menu.animator.IMenuAnimator; +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; +import org.anddev.andengine.input.touch.TouchEvent; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 20:06:51 - 01.04.2010 + */ +public class MenuScene extends CameraScene implements IOnAreaTouchListener, IOnSceneTouchListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mMenuItems = new ArrayList(); + + private IOnMenuItemClickListener mOnMenuItemClickListener; + + private IMenuAnimator mMenuAnimator = IMenuAnimator.DEFAULT; + + private IMenuItem mSelectedMenuItem; + + // =========================================================== + // Constructors + // =========================================================== + + public MenuScene() { + this(null, null); + } + + public MenuScene(final IOnMenuItemClickListener pOnMenuItemClickListener) { + this(null, pOnMenuItemClickListener); + } + + public MenuScene(final Camera pCamera) { + this(pCamera, null); + } + + public MenuScene(final Camera pCamera, final IOnMenuItemClickListener pOnMenuItemClickListener) { + super(1, pCamera); + this.mOnMenuItemClickListener = pOnMenuItemClickListener; + this.setOnSceneTouchListener(this); + this.setOnAreaTouchListener(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public IOnMenuItemClickListener getOnMenuItemClickListener() { + return this.mOnMenuItemClickListener; + } + + public void setOnMenuItemClickListener(final IOnMenuItemClickListener pOnMenuItemClickListener) { + this.mOnMenuItemClickListener = pOnMenuItemClickListener; + } + + public int getMenuItemCount() { + return this.mMenuItems.size(); + } + + public void addMenuItem(final IMenuItem pMenuItem) { + this.mMenuItems.add(pMenuItem); + this.getFirstChild().attachChild(pMenuItem); + this.registerTouchArea(pMenuItem); + } + + @Override + public MenuScene getChildScene() { + return (MenuScene)super.getChildScene(); + } + + @Override + public void setChildScene(final Scene pChildScene, final boolean pModalDraw, final boolean pModalUpdate, final boolean pModalTouch) throws IllegalArgumentException { + if(pChildScene instanceof MenuScene) { + super.setChildScene(pChildScene, pModalDraw, pModalUpdate, pModalTouch); + } else { + throw new IllegalArgumentException("MenuScene accepts only MenuScenes as a ChildScene."); + } + } + + @Override + public void clearChildScene() { + if(this.getChildScene() != null) { + this.getChildScene().reset(); + super.clearChildScene(); + } + } + + public void setMenuAnimator(final IMenuAnimator pMenuAnimator) { + this.mMenuAnimator = pMenuAnimator; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final ITouchArea pTouchArea, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + final IMenuItem menuItem = ((IMenuItem)pTouchArea); + + switch(pSceneTouchEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_MOVE: + if(this.mSelectedMenuItem != null && this.mSelectedMenuItem != menuItem) { + this.mSelectedMenuItem.onUnselected(); + } + this.mSelectedMenuItem = menuItem; + this.mSelectedMenuItem.onSelected(); + break; + case MotionEvent.ACTION_UP: + if(this.mOnMenuItemClickListener != null) { + final boolean handled = this.mOnMenuItemClickListener.onMenuItemClicked(this, menuItem, pTouchAreaLocalX, pTouchAreaLocalY); + menuItem.onUnselected(); + this.mSelectedMenuItem = null; + return handled; + } + break; + case MotionEvent.ACTION_CANCEL: + menuItem.onUnselected(); + this.mSelectedMenuItem = null; + break; + } + return true; + } + + @Override + public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) { + if(this.mSelectedMenuItem != null) { + this.mSelectedMenuItem.onUnselected(); + this.mSelectedMenuItem = null; + } + return false; + } + + @Override + public void back() { + super.back(); + + this.reset(); + } + + @Override + public void reset() { + super.reset(); + + final ArrayList menuItems = this.mMenuItems; + for(int i = menuItems.size() - 1; i >= 0; i--) { + menuItems.get(i).reset(); + } + + this.prepareAnimations(); + } + + // =========================================================== + // Methods + // =========================================================== + + public void closeMenuScene() { + this.back(); + } + + public void buildAnimations() { + this.prepareAnimations(); + + final float cameraHeight = this.mCamera.getHeight(); + final float cameraWidth = this.mCamera.getWidth(); + this.mMenuAnimator.buildAnimations(this.mMenuItems, cameraWidth, cameraHeight); + } + + public void prepareAnimations() { + final float cameraHeight = this.mCamera.getHeight(); + final float cameraWidth = this.mCamera.getWidth(); + this.mMenuAnimator.prepareAnimations(this.mMenuItems, cameraWidth, cameraHeight); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IOnMenuItemClickListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean onMenuItemClicked(final MenuScene pMenuScene, final IMenuItem pMenuItem, final float pMenuItemLocalX, final float pMenuItemLocalY); + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/AlphaMenuAnimator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/AlphaMenuAnimator.java new file mode 100644 index 0000000..39f31de --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/AlphaMenuAnimator.java @@ -0,0 +1,124 @@ +package org.anddev.andengine.entity.scene.menu.animator; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.modifier.AlphaModifier; +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; +import org.anddev.andengine.util.HorizontalAlign; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 11:04:35 - 02.04.2010 + */ +public class AlphaMenuAnimator extends BaseMenuAnimator { + // =========================================================== + // Constants + // =========================================================== + + private static final float ALPHA_FROM = 0.0f; + private static final float ALPHA_TO = 1.0f; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public AlphaMenuAnimator(){ + super(); + } + + public AlphaMenuAnimator(final IEaseFunction pEaseFunction) { + super(pEaseFunction); + } + + public AlphaMenuAnimator(final HorizontalAlign pHorizontalAlign) { + super(pHorizontalAlign); + } + + public AlphaMenuAnimator(final HorizontalAlign pHorizontalAlign, final IEaseFunction pEaseFunction) { + super(pHorizontalAlign, pEaseFunction); + } + + public AlphaMenuAnimator(final float pMenuItemSpacing) { + super(pMenuItemSpacing); + } + + public AlphaMenuAnimator(final float pMenuItemSpacing, final IEaseFunction pEaseFunction) { + super(pMenuItemSpacing, pEaseFunction); + } + + public AlphaMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing) { + super(pHorizontalAlign, pMenuItemSpacing); + } + + public AlphaMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing, final IEaseFunction pEaseFunction) { + super(pHorizontalAlign, pMenuItemSpacing, pEaseFunction); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void buildAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight) { + final IEaseFunction easeFunction = this.mEaseFunction; + final int menuItemCount = pMenuItems.size(); + for(int i = menuItemCount - 1; i >= 0; i--) { + final AlphaModifier alphaModifier = new AlphaModifier(DURATION, ALPHA_FROM, ALPHA_TO, easeFunction); + alphaModifier.setRemoveWhenFinished(false); + pMenuItems.get(i).registerEntityModifier(alphaModifier); + } + } + + @Override + public void prepareAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight) { + final float maximumWidth = this.getMaximumWidth(pMenuItems); + final float overallHeight = this.getOverallHeight(pMenuItems); + + final float baseX = (pCameraWidth - maximumWidth) * 0.5f; + final float baseY = (pCameraHeight - overallHeight) * 0.5f; + + final float menuItemSpacing = this.mMenuItemSpacing; + + float offsetY = 0; + final int menuItemCount = pMenuItems.size(); + for(int i = 0; i < menuItemCount; i++) { + final IMenuItem menuItem = pMenuItems.get(i); + + final float offsetX; + switch(this.mHorizontalAlign) { + case LEFT: + offsetX = 0; + break; + case RIGHT: + offsetX = maximumWidth - menuItem.getWidthScaled(); + break; + case CENTER: + default: + offsetX = (maximumWidth - menuItem.getWidthScaled()) * 0.5f; + break; + } + menuItem.setPosition(baseX + offsetX , baseY + offsetY); + + menuItem.setAlpha(ALPHA_FROM); + + offsetY += menuItem.getHeight() + menuItemSpacing; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/BaseMenuAnimator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/BaseMenuAnimator.java new file mode 100644 index 0000000..8bd7e3c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/BaseMenuAnimator.java @@ -0,0 +1,105 @@ +package org.anddev.andengine.entity.scene.menu.animator; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; +import org.anddev.andengine.util.HorizontalAlign; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 11:17:32 - 02.04.2010 + */ +public abstract class BaseMenuAnimator implements IMenuAnimator { + // =========================================================== + // Constants + // =========================================================== + + protected static final float DURATION = 1.0f; + + private static final float MENUITEMSPACING_DEFAULT = 1.0f; + + private static final HorizontalAlign HORIZONTALALIGN_DEFAULT = HorizontalAlign.CENTER; + + // =========================================================== + // Fields + // =========================================================== + + protected final float mMenuItemSpacing; + protected final HorizontalAlign mHorizontalAlign; + protected final IEaseFunction mEaseFunction; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseMenuAnimator() { + this(MENUITEMSPACING_DEFAULT); + } + + public BaseMenuAnimator(final IEaseFunction pEaseFunction) { + this(MENUITEMSPACING_DEFAULT, pEaseFunction); + } + + public BaseMenuAnimator(final float pMenuItemSpacing) { + this(HORIZONTALALIGN_DEFAULT, pMenuItemSpacing); + } + + public BaseMenuAnimator(final float pMenuItemSpacing, final IEaseFunction pEaseFunction) { + this(HORIZONTALALIGN_DEFAULT, pMenuItemSpacing, pEaseFunction); + } + + public BaseMenuAnimator(final HorizontalAlign pHorizontalAlign) { + this(pHorizontalAlign, MENUITEMSPACING_DEFAULT); + } + + public BaseMenuAnimator(final HorizontalAlign pHorizontalAlign, final IEaseFunction pEaseFunction) { + this(pHorizontalAlign, MENUITEMSPACING_DEFAULT, pEaseFunction); + } + + public BaseMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing) { + this(pHorizontalAlign, pMenuItemSpacing, IEaseFunction.DEFAULT); + } + + public BaseMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing, final IEaseFunction pEaseFunction) { + this.mHorizontalAlign = pHorizontalAlign; + this.mMenuItemSpacing = pMenuItemSpacing; + this.mEaseFunction = pEaseFunction; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + protected float getMaximumWidth(final ArrayList pMenuItems) { + float maximumWidth = Float.MIN_VALUE; + for(int i = pMenuItems.size() - 1; i >= 0; i--) { + final IMenuItem menuItem = pMenuItems.get(i); + maximumWidth = Math.max(maximumWidth, menuItem.getWidthScaled()); + } + return maximumWidth; + } + + protected float getOverallHeight(final ArrayList pMenuItems) { + float overallHeight = 0; + for(int i = pMenuItems.size() - 1; i >= 0; i--) { + final IMenuItem menuItem = pMenuItems.get(i); + overallHeight += menuItem.getHeight(); + } + + overallHeight += (pMenuItems.size() - 1) * this.mMenuItemSpacing; + return overallHeight; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/DirectMenuAnimator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/DirectMenuAnimator.java new file mode 100644 index 0000000..e098aef --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/DirectMenuAnimator.java @@ -0,0 +1,95 @@ +package org.anddev.andengine.entity.scene.menu.animator; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; +import org.anddev.andengine.util.HorizontalAlign; + +/** + * @author Nicolas Gramlich + * @since 10:46:34 - 14.05.2010 + */ +public class DirectMenuAnimator extends BaseMenuAnimator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public DirectMenuAnimator(){ + super(); + } + + public DirectMenuAnimator(final HorizontalAlign pHorizontalAlign) { + super(pHorizontalAlign); + } + + public DirectMenuAnimator(final float pMenuItemSpacing) { + super(pMenuItemSpacing); + } + + public DirectMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing) { + super(pHorizontalAlign, pMenuItemSpacing); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void buildAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight) { + + } + + @Override + public void prepareAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight) { + final float maximumWidth = this.getMaximumWidth(pMenuItems); + final float overallHeight = this.getOverallHeight(pMenuItems); + + final float baseX = (pCameraWidth - maximumWidth) * 0.5f; + final float baseY = (pCameraHeight - overallHeight) * 0.5f; + + final float menuItemSpacing = this.mMenuItemSpacing; + + float offsetY = 0; + final int menuItemCount = pMenuItems.size(); + for(int i = 0; i < menuItemCount; i++) { + final IMenuItem menuItem = pMenuItems.get(i); + + final float offsetX; + switch(this.mHorizontalAlign) { + case LEFT: + offsetX = 0; + break; + case RIGHT: + offsetX = maximumWidth - menuItem.getWidthScaled(); + break; + case CENTER: + default: + offsetX = (maximumWidth - menuItem.getWidthScaled()) * 0.5f; + break; + } + menuItem.setPosition(baseX + offsetX , baseY + offsetY); + + offsetY += menuItem.getHeight() + menuItemSpacing; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/IMenuAnimator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/IMenuAnimator.java new file mode 100644 index 0000000..1930dce --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/IMenuAnimator.java @@ -0,0 +1,24 @@ +package org.anddev.andengine.entity.scene.menu.animator; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; + +/** + * @author Nicolas Gramlich + * @since 10:50:36 - 02.04.2010 + */ +public interface IMenuAnimator { + // =========================================================== + // Constants + // =========================================================== + + public static final IMenuAnimator DEFAULT = new AlphaMenuAnimator(); + + // =========================================================== + // Methods + // =========================================================== + + public void prepareAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight); + public void buildAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight); +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/SlideMenuAnimator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/SlideMenuAnimator.java new file mode 100644 index 0000000..78bbd60 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/animator/SlideMenuAnimator.java @@ -0,0 +1,130 @@ +package org.anddev.andengine.entity.scene.menu.animator; + +import java.util.ArrayList; + +import org.anddev.andengine.entity.modifier.MoveModifier; +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; +import org.anddev.andengine.util.HorizontalAlign; +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 11:04:35 - 02.04.2010 + */ +public class SlideMenuAnimator extends BaseMenuAnimator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SlideMenuAnimator(){ + super(); + } + + public SlideMenuAnimator(final IEaseFunction pEaseFunction) { + super(pEaseFunction); + } + + public SlideMenuAnimator(final HorizontalAlign pHorizontalAlign) { + super(pHorizontalAlign); + } + + public SlideMenuAnimator(final HorizontalAlign pHorizontalAlign, final IEaseFunction pEaseFunction) { + super(pHorizontalAlign, pEaseFunction); + } + + public SlideMenuAnimator(final float pMenuItemSpacing) { + super(pMenuItemSpacing); + } + + public SlideMenuAnimator(final float pMenuItemSpacing, final IEaseFunction pEaseFunction) { + super(pMenuItemSpacing, pEaseFunction); + } + + public SlideMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing) { + super(pHorizontalAlign, pMenuItemSpacing); + } + + public SlideMenuAnimator(final HorizontalAlign pHorizontalAlign, final float pMenuItemSpacing, final IEaseFunction pEaseFunction) { + super(pHorizontalAlign, pMenuItemSpacing, pEaseFunction); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void buildAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight) { + final IEaseFunction easeFunction = this.mEaseFunction; + final float maximumWidth = this.getMaximumWidth(pMenuItems); + final float overallHeight = this.getOverallHeight(pMenuItems); + + final float baseX = (pCameraWidth - maximumWidth) * 0.5f; + final float baseY = (pCameraHeight - overallHeight) * 0.5f; + + float offsetY = 0; + final int menuItemCount = pMenuItems.size(); + for(int i = 0; i < menuItemCount; i++) { + final IMenuItem menuItem = pMenuItems.get(i); + + final float offsetX; + switch(this.mHorizontalAlign) { + case LEFT: + offsetX = 0; + break; + case RIGHT: + offsetX = maximumWidth - menuItem.getWidthScaled(); + break; + case CENTER: + default: + offsetX = (maximumWidth - menuItem.getWidthScaled()) * 0.5f; + break; + } + + final MoveModifier moveModifier = new MoveModifier(DURATION, -maximumWidth, baseX + offsetX, baseY + offsetY, baseY + offsetY, easeFunction); + moveModifier.setRemoveWhenFinished(false); + menuItem.registerEntityModifier(moveModifier); + + offsetY += menuItem.getHeight() + this.mMenuItemSpacing; + } + } + + @Override + public void prepareAnimations(final ArrayList pMenuItems, final float pCameraWidth, final float pCameraHeight) { + final float maximumWidth = this.getMaximumWidth(pMenuItems); + final float overallHeight = this.getOverallHeight(pMenuItems); + + final float baseY = (pCameraHeight - overallHeight) * 0.5f; + + final float menuItemSpacing = this.mMenuItemSpacing; + + float offsetY = 0; + final int menuItemCount = pMenuItems.size(); + for(int i = 0; i < menuItemCount; i++) { + final IMenuItem menuItem = pMenuItems.get(i); + + menuItem.setPosition(-maximumWidth, baseY + offsetY); + + offsetY += menuItem.getHeight() + menuItemSpacing; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/AnimatedSpriteMenuItem.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/AnimatedSpriteMenuItem.java new file mode 100644 index 0000000..5449118 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/AnimatedSpriteMenuItem.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.entity.scene.menu.item; + +import org.anddev.andengine.entity.sprite.AnimatedSprite; +import org.anddev.andengine.opengl.texture.region.TiledTextureRegion; + +/** + * @author Nicolas Gramlich + * @since 15:44:39 - 07.07.2010 + */ +public class AnimatedSpriteMenuItem extends AnimatedSprite implements IMenuItem { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mID; + + // =========================================================== + // Constructors + // =========================================================== + + public AnimatedSpriteMenuItem(final int pID, final TiledTextureRegion pTiledTextureRegion) { + super(0, 0, pTiledTextureRegion); + this.mID = pID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public int getID() { + return this.mID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onSelected() { + /* Nothing. */ + } + + @Override + public void onUnselected() { + /* Nothing. */ + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/IMenuItem.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/IMenuItem.java new file mode 100644 index 0000000..cece578 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/IMenuItem.java @@ -0,0 +1,21 @@ +package org.anddev.andengine.entity.scene.menu.item; + +import org.anddev.andengine.entity.shape.IShape; + +/** + * @author Nicolas Gramlich + * @since 13:27:16 - 07.07.2010 + */ +public interface IMenuItem extends IShape { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public int getID(); + public abstract void onSelected(); + public abstract void onUnselected(); +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/SpriteMenuItem.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/SpriteMenuItem.java new file mode 100644 index 0000000..6522686 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/SpriteMenuItem.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.entity.scene.menu.item; + +import org.anddev.andengine.entity.sprite.Sprite; +import org.anddev.andengine.opengl.texture.region.TextureRegion; + +/** + * @author Nicolas Gramlich + * @since 20:15:20 - 01.04.2010 + */ +public class SpriteMenuItem extends Sprite implements IMenuItem { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mID; + + // =========================================================== + // Constructors + // =========================================================== + + public SpriteMenuItem(final int pID, final TextureRegion pTextureRegion) { + super(0, 0, pTextureRegion); + this.mID = pID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public int getID() { + return this.mID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onSelected() { + /* Nothing. */ + } + + @Override + public void onUnselected() { + /* Nothing. */ + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/TextMenuItem.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/TextMenuItem.java new file mode 100644 index 0000000..79d382d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/TextMenuItem.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.entity.scene.menu.item; + +import org.anddev.andengine.entity.text.Text; +import org.anddev.andengine.opengl.font.Font; + +/** + * @author Nicolas Gramlich + * @since 20:15:20 - 01.04.2010 + */ +public class TextMenuItem extends Text implements IMenuItem{ + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mID; + + // =========================================================== + // Constructors + // =========================================================== + + public TextMenuItem(final int pID, final Font pFont, final String pText) { + super(0, 0, pFont, pText); + this.mID = pID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public int getID() { + return this.mID; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onSelected() { + /* Nothing. */ + } + + @Override + public void onUnselected() { + /* Nothing. */ + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/BaseMenuItemDecorator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/BaseMenuItemDecorator.java new file mode 100644 index 0000000..8c4c11c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/BaseMenuItemDecorator.java @@ -0,0 +1,507 @@ +package org.anddev.andengine.entity.scene.menu.item.decorator; + +import java.util.Comparator; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.entity.modifier.IEntityModifier; +import org.anddev.andengine.entity.modifier.IEntityModifier.IEntityModifierMatcher; +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; +import org.anddev.andengine.entity.shape.IShape; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.util.Transformation; + +/** + * @author Nicolas Gramlich + * @since 15:05:44 - 18.11.2010 + */ +public abstract class BaseMenuItemDecorator implements IMenuItem { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final IMenuItem mMenuItem; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseMenuItemDecorator(final IMenuItem pMenuItem) { + this.mMenuItem = pMenuItem; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onMenuItemSelected(final IMenuItem pMenuItem); + protected abstract void onMenuItemUnselected(final IMenuItem pMenuItem); + protected abstract void onMenuItemReset(final IMenuItem pMenuItem); + + @Override + public int getID() { + return this.mMenuItem.getID(); + } + + @Override + public final void onSelected() { + this.mMenuItem.onSelected(); + this.onMenuItemSelected(this.mMenuItem); + } + + @Override + public final void onUnselected() { + this.mMenuItem.onUnselected(); + this.onMenuItemUnselected(this.mMenuItem); + } + + @Override + public float getX() { + return this.mMenuItem.getX(); + } + + @Override + public float getY() { + return this.mMenuItem.getY(); + } + + @Override + public void setPosition(final IEntity pOtherEntity) { + this.mMenuItem.setPosition(pOtherEntity); + } + + @Override + public void setPosition(final float pX, final float pY) { + this.mMenuItem.setPosition(pX, pY); + } + + @Override + public float getBaseWidth() { + return this.mMenuItem.getBaseWidth(); + } + + @Override + public float getBaseHeight() { + return this.mMenuItem.getBaseHeight(); + } + + @Override + public float getWidth() { + return this.mMenuItem.getWidth(); + } + + @Override + public float getWidthScaled() { + return this.mMenuItem.getWidthScaled(); + } + + @Override + public float getHeight() { + return this.mMenuItem.getHeight(); + } + + @Override + public float getHeightScaled() { + return this.mMenuItem.getHeightScaled(); + } + + @Override + public float getInitialX() { + return this.mMenuItem.getInitialX(); + } + + @Override + public float getInitialY() { + return this.mMenuItem.getInitialY(); + } + + @Override + public float getRed() { + return this.mMenuItem.getRed(); + } + + @Override + public float getGreen() { + return this.mMenuItem.getGreen(); + } + + @Override + public float getBlue() { + return this.mMenuItem.getBlue(); + } + + @Override + public float getAlpha() { + return this.mMenuItem.getAlpha(); + } + + @Override + public void setAlpha(final float pAlpha) { + this.mMenuItem.setAlpha(pAlpha); + } + + @Override + public void setColor(final float pRed, final float pGreen, final float pBlue) { + this.mMenuItem.setColor(pRed, pGreen, pBlue); + } + + @Override + public void setColor(final float pRed, final float pGreen, final float pBlue, final float pAlpha) { + this.mMenuItem.setColor(pRed, pGreen, pBlue, pAlpha); + } + + @Override + public float getRotation() { + return this.mMenuItem.getRotation(); + } + + @Override + public void setRotation(final float pRotation) { + this.mMenuItem.setRotation(pRotation); + } + + @Override + public float getRotationCenterX() { + return this.mMenuItem.getRotationCenterX(); + } + + @Override + public float getRotationCenterY() { + return this.mMenuItem.getRotationCenterY(); + } + + @Override + public void setRotationCenterX(final float pRotationCenterX) { + this.mMenuItem.setRotationCenterX(pRotationCenterX); + } + + @Override + public void setRotationCenterY(final float pRotationCenterY) { + this.mMenuItem.setRotationCenterY(pRotationCenterY); + } + + @Override + public void setRotationCenter(final float pRotationCenterX, final float pRotationCenterY) { + this.mMenuItem.setRotationCenter(pRotationCenterX, pRotationCenterY); + } + + @Override + public boolean isScaled() { + return this.mMenuItem.isScaled(); + } + + @Override + public float getScaleX() { + return this.mMenuItem.getScaleX(); + } + + @Override + public float getScaleY() { + return this.mMenuItem.getScaleY(); + } + + @Override + public void setScale(final float pScale) { + this.mMenuItem.setScale(pScale); + } + + @Override + public void setScale(final float pScaleX, final float pScaleY) { + this.mMenuItem.setScale(pScaleX, pScaleY); + } + + @Override + public void setScaleX(final float pScaleX) { + this.mMenuItem.setScaleX(pScaleX); + } + + @Override + public void setScaleY(final float pScaleY) { + this.mMenuItem.setScaleY(pScaleY); + } + + @Override + public float getScaleCenterX() { + return this.mMenuItem.getScaleCenterX(); + } + + @Override + public float getScaleCenterY() { + return this.mMenuItem.getScaleCenterY(); + } + + @Override + public void setScaleCenterX(final float pScaleCenterX) { + this.mMenuItem.setScaleCenterX(pScaleCenterX); + } + + @Override + public void setScaleCenterY(final float pScaleCenterY) { + this.mMenuItem.setScaleCenterY(pScaleCenterY); + } + + @Override + public void setScaleCenter(final float pScaleCenterX, final float pScaleCenterY) { + this.mMenuItem.setScaleCenter(pScaleCenterX, pScaleCenterY); + } + + @Override + public boolean collidesWith(final IShape pOtherShape) { + return this.mMenuItem.collidesWith(pOtherShape); + } + + @Override + public float[] getSceneCenterCoordinates() { + return this.mMenuItem.getSceneCenterCoordinates(); + } + + @Override + public boolean isCullingEnabled() { + return this.mMenuItem.isCullingEnabled(); + } + + @Override + public void registerEntityModifier(final IEntityModifier pEntityModifier) { + this.mMenuItem.registerEntityModifier(pEntityModifier); + } + + @Override + public boolean unregisterEntityModifier(final IEntityModifier pEntityModifier) { + return this.mMenuItem.unregisterEntityModifier(pEntityModifier); + } + + @Override + public boolean unregisterEntityModifiers(final IEntityModifierMatcher pEntityModifierMatcher) { + return this.mMenuItem.unregisterEntityModifiers(pEntityModifierMatcher); + } + + @Override + public void clearEntityModifiers() { + this.mMenuItem.clearEntityModifiers(); + } + + @Override + public void setInitialPosition() { + this.mMenuItem.setInitialPosition(); + } + + @Override + public void setBlendFunction(final int pSourceBlendFunction, final int pDestinationBlendFunction) { + this.mMenuItem.setBlendFunction(pSourceBlendFunction, pDestinationBlendFunction); + } + + @Override + public void setCullingEnabled(final boolean pCullingEnabled) { + this.mMenuItem.setCullingEnabled(pCullingEnabled); + } + + @Override + public int getZIndex() { + return this.mMenuItem.getZIndex(); + } + + @Override + public void setZIndex(final int pZIndex) { + this.mMenuItem.setZIndex(pZIndex); + } + + @Override + public void onDraw(final GL10 pGL, final Camera pCamera) { + this.mMenuItem.onDraw(pGL, pCamera); + } + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mMenuItem.onUpdate(pSecondsElapsed); + } + + @Override + public void reset() { + this.mMenuItem.reset(); + this.onMenuItemReset(this.mMenuItem); + } + + @Override + public boolean contains(final float pX, final float pY) { + return this.mMenuItem.contains(pX, pY); + } + + @Override + public float[] convertLocalToSceneCoordinates(final float pX, final float pY) { + return this.mMenuItem.convertLocalToSceneCoordinates(pX, pY); + } + + @Override + public float[] convertSceneToLocalCoordinates(final float pX, final float pY) { + return this.mMenuItem.convertSceneToLocalCoordinates(pX, pY); + } + + @Override + public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + return this.mMenuItem.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY); + } + + @Override + public int getChildCount() { + return this.mMenuItem.getChildCount(); + } + + @Override + public void attachChild(final IEntity pEntity) { + this.mMenuItem.attachChild(pEntity); + } + + @Override + public IEntity getFirstChild() { + return this.mMenuItem.getFirstChild(); + } + + @Override + public IEntity getLastChild() { + return this.mMenuItem.getLastChild(); + } + + @Override + public IEntity getChild(final int pIndex) { + return this.mMenuItem.getChild(pIndex); + } + + @Override + public IEntity findChild(final IEntityMatcher pEntityMatcher) { + return this.mMenuItem.findChild(pEntityMatcher); + } + + @Override + public void sortChildren() { + this.mMenuItem.sortChildren(); + } + + @Override + public void sortChildren(final Comparator pEntityComparator) { + this.mMenuItem.sortChildren(pEntityComparator); + } + + @Override + public boolean detachSelf() { + return this.mMenuItem.detachSelf(); + } + + @Override + public boolean detachChild(final IEntity pEntity) { + return this.mMenuItem.detachChild(pEntity); + } + + @Override + public IEntity detachChild(final IEntityMatcher pEntityMatcher) { + return this.mMenuItem.detachChild(pEntityMatcher); + } + + @Override + public boolean detachChildren(final IEntityMatcher pEntityMatcher) { + return this.mMenuItem.detachChildren(pEntityMatcher); + } + + @Override + public void detachChildren() { + this.mMenuItem.detachChildren(); + } + + @Override + public Transformation getLocalToSceneTransformation() { + return this.mMenuItem.getLocalToSceneTransformation(); + } + + @Override + public Transformation getSceneToLocalTransformation() { + return this.mMenuItem.getSceneToLocalTransformation(); + } + + @Override + public IEntity getParent() { + return this.mMenuItem.getParent(); + } + + @Override + public void setParent(final IEntity pEntity) { + this.mMenuItem.setParent(pEntity); + } + + @Override + public boolean isVisible() { + return this.mMenuItem.isVisible(); + } + + @Override + public void setVisible(final boolean pVisible) { + this.mMenuItem.setVisible(pVisible); + } + + @Override + public boolean isIgnoreUpdate() { + return this.mMenuItem.isIgnoreUpdate(); + } + + @Override + public void setIgnoreUpdate(final boolean pIgnoreUpdate) { + this.mMenuItem.setIgnoreUpdate(pIgnoreUpdate); + } + + @Override + public void setUserData(final Object pUserData) { + this.mMenuItem.setUserData(pUserData); + } + + @Override + public Object getUserData() { + return this.mMenuItem.getUserData(); + } + + @Override + public void onAttached() { + this.mMenuItem.onAttached(); + } + + @Override + public void onDetached() { + this.mMenuItem.onDetached(); + } + + @Override + public void registerUpdateHandler(final IUpdateHandler pUpdateHandler) { + this.mMenuItem.registerUpdateHandler(pUpdateHandler); + } + + @Override + public boolean unregisterUpdateHandler(final IUpdateHandler pUpdateHandler) { + return this.mMenuItem.unregisterUpdateHandler(pUpdateHandler); + } + + @Override + public void clearUpdateHandlers() { + this.mMenuItem.clearUpdateHandlers(); + } + + @Override + public boolean unregisterUpdateHandlers(final IUpdateHandlerMatcher pUpdateHandlerMatcher) { + return this.mMenuItem.unregisterUpdateHandlers(pUpdateHandlerMatcher); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/ColorMenuItemDecorator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/ColorMenuItemDecorator.java new file mode 100644 index 0000000..11afff8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/ColorMenuItemDecorator.java @@ -0,0 +1,77 @@ +package org.anddev.andengine.entity.scene.menu.item.decorator; + +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; + +/** + * @author Nicolas Gramlich + * @since 14:25:35 - 07.07.2010 + */ +public class ColorMenuItemDecorator extends BaseMenuItemDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mSelectedRed; + private final float mSelectedGreen; + private final float mSelectedBlue; + private final float mUnselectedRed; + private final float mUnselectedGreen; + private final float mUnselectedBlue; + + // =========================================================== + // Constructors + // =========================================================== + + public ColorMenuItemDecorator(final IMenuItem pMenuItem, final float pSelectedRed, final float pSelectedGreen, final float pSelectedBlue, final float pUnselectedRed, final float pUnselectedGreen, final float pUnselectedBlue) { + super(pMenuItem); + + this.mSelectedRed = pSelectedRed; + this.mSelectedGreen = pSelectedGreen; + this.mSelectedBlue = pSelectedBlue; + + this.mUnselectedRed = pUnselectedRed; + this.mUnselectedGreen = pUnselectedGreen; + this.mUnselectedBlue = pUnselectedBlue; + + pMenuItem.setColor(this.mUnselectedRed, this.mUnselectedGreen, this.mUnselectedBlue); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onMenuItemSelected(final IMenuItem pMenuItem) { + pMenuItem.setColor(this.mSelectedRed, this.mSelectedGreen, this.mSelectedBlue); + } + + @Override + public void onMenuItemUnselected(final IMenuItem pMenuItem) { + pMenuItem.setColor(this.mUnselectedRed, this.mUnselectedGreen, this.mUnselectedBlue); + } + + @Override + public void onMenuItemReset(final IMenuItem pMenuItem) { + pMenuItem.setColor(this.mUnselectedRed, this.mUnselectedGreen, this.mUnselectedBlue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/ScaleMenuItemDecorator.java b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/ScaleMenuItemDecorator.java new file mode 100644 index 0000000..c49274b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/menu/item/decorator/ScaleMenuItemDecorator.java @@ -0,0 +1,68 @@ +package org.anddev.andengine.entity.scene.menu.item.decorator; + +import org.anddev.andengine.entity.scene.menu.item.IMenuItem; + +/** + * @author Nicolas Gramlich + * @since 15:04:29 - 18.11.2010 + */ +public class ScaleMenuItemDecorator extends BaseMenuItemDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mSelectedScale; + private final float mUnselectedScale; + + // =========================================================== + // Constructors + // =========================================================== + + public ScaleMenuItemDecorator(final IMenuItem pMenuItem, final float pSelectedScale, final float pUnselectedScale) { + super(pMenuItem); + + this.mSelectedScale = pSelectedScale; + this.mUnselectedScale = pUnselectedScale; + + pMenuItem.setScale(pUnselectedScale); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onMenuItemSelected(final IMenuItem pMenuItem) { + this.setScale(this.mSelectedScale); + } + + @Override + public void onMenuItemUnselected(final IMenuItem pMenuItem) { + this.setScale(this.mUnselectedScale); + } + + @Override + public void onMenuItemReset(final IMenuItem pMenuItem) { + this.setScale(this.mUnselectedScale); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/popup/PopupScene.java b/AndEngine/src/org/anddev/andengine/entity/scene/popup/PopupScene.java new file mode 100644 index 0000000..a9142a8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/popup/PopupScene.java @@ -0,0 +1,63 @@ +package org.anddev.andengine.entity.scene.popup; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.handler.timer.ITimerCallback; +import org.anddev.andengine.engine.handler.timer.TimerHandler; +import org.anddev.andengine.entity.scene.CameraScene; +import org.anddev.andengine.entity.scene.Scene; + +/** + * @author Nicolas Gramlich + * @since 16:36:51 - 03.08.2010 + */ +public class PopupScene extends CameraScene { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public PopupScene(final Camera pCamera, final Scene pParentScene, final float pDurationSeconds) { + this(pCamera, pParentScene, pDurationSeconds, null); + } + + public PopupScene(final Camera pCamera, final Scene pParentScene, final float pDurationSeconds, final Runnable pRunnable) { + super(1, pCamera); + this.setBackgroundEnabled(false); + + pParentScene.setChildScene(this, false, true, true); + + this.registerUpdateHandler(new TimerHandler(pDurationSeconds, new ITimerCallback() { + @Override + public void onTimePassed(final TimerHandler pTimerHandler) { + PopupScene.this.unregisterUpdateHandler(pTimerHandler); + pParentScene.clearChildScene(); + if(pRunnable != null) { + pRunnable.run(); + } + } + })); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/scene/popup/TextPopupScene.java b/AndEngine/src/org/anddev/andengine/entity/scene/popup/TextPopupScene.java new file mode 100644 index 0000000..900a1bf --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/scene/popup/TextPopupScene.java @@ -0,0 +1,73 @@ +package org.anddev.andengine.entity.scene.popup; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.modifier.IEntityModifier; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.entity.text.Text; +import org.anddev.andengine.opengl.font.Font; +import org.anddev.andengine.util.HorizontalAlign; + +/** + * @author Nicolas Gramlich + * @since 17:19:30 - 03.08.2010 + */ +public class TextPopupScene extends PopupScene { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Text mText; + + // =========================================================== + // Constructors + // =========================================================== + + public TextPopupScene(final Camera pCamera, final Scene pParentScene, final Font pFont, final String pText, final float pDurationSeconds) { + this(pCamera, pParentScene, pFont, pText, pDurationSeconds, null, null); + } + + public TextPopupScene(final Camera pCamera, final Scene pParentScene, final Font pFont, final String pText, final float pDurationSeconds, final IEntityModifier pShapeModifier) { + this(pCamera, pParentScene, pFont, pText, pDurationSeconds, pShapeModifier, null); + } + + public TextPopupScene(final Camera pCamera, final Scene pParentScene, final Font pFont, final String pText, final float pDurationSeconds, final Runnable pRunnable) { + this(pCamera, pParentScene, pFont, pText, pDurationSeconds, null, pRunnable); + } + + public TextPopupScene(final Camera pCamera, final Scene pParentScene, final Font pFont, final String pText, final float pDurationSeconds, final IEntityModifier pShapeModifier, final Runnable pRunnable) { + super(pCamera, pParentScene, pDurationSeconds, pRunnable); + + this.mText = new Text(0, 0, pFont, pText, HorizontalAlign.CENTER); + this.centerShapeInCamera(this.mText); + + if(pShapeModifier != null) { + this.mText.registerEntityModifier(pShapeModifier); + } + + this.getLastChild().attachChild(this.mText); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Text getText() { + return this.mText; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/shape/IShape.java b/AndEngine/src/org/anddev/andengine/entity/shape/IShape.java new file mode 100644 index 0000000..b66c5c8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/shape/IShape.java @@ -0,0 +1,34 @@ +package org.anddev.andengine.entity.shape; + +import org.anddev.andengine.entity.IEntity; +import org.anddev.andengine.entity.scene.Scene.ITouchArea; + +/** + * @author Nicolas Gramlich + * @since 13:32:52 - 07.07.2010 + */ +public interface IShape extends IEntity, ITouchArea { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean isCullingEnabled(); + public void setCullingEnabled(final boolean pCullingEnabled); + + public float getWidth(); + public float getHeight(); + + public float getBaseWidth(); + public float getBaseHeight(); + + public float getWidthScaled(); + public float getHeightScaled(); + + public boolean collidesWith(final IShape pOtherShape); + + public void setBlendFunction(final int pSourceBlendFunction, final int pDestinationBlendFunction); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/entity/shape/RectangularShape.java b/AndEngine/src/org/anddev/andengine/entity/shape/RectangularShape.java new file mode 100644 index 0000000..b113159 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/shape/RectangularShape.java @@ -0,0 +1,169 @@ +package org.anddev.andengine.entity.shape; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.collision.RectangularShapeCollisionChecker; +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.vertex.VertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 11:37:50 - 04.04.2010 + */ +public abstract class RectangularShape extends Shape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mBaseWidth; + protected float mBaseHeight; + + protected float mWidth; + protected float mHeight; + + private final VertexBuffer mVertexBuffer; + + // =========================================================== + // Constructors + // =========================================================== + + public RectangularShape(final float pX, final float pY, final float pWidth, final float pHeight, final VertexBuffer pVertexBuffer) { + super(pX, pY); + + this.mBaseWidth = pWidth; + this.mBaseHeight = pHeight; + + this.mWidth = pWidth; + this.mHeight = pHeight; + + this.mVertexBuffer = pVertexBuffer; + BufferObjectManager.getActiveInstance().loadBufferObject(this.mVertexBuffer); + + this.mRotationCenterX = pWidth * 0.5f; + this.mRotationCenterY = pHeight * 0.5f; + + this.mScaleCenterX = this.mRotationCenterX; + this.mScaleCenterY = this.mRotationCenterY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public VertexBuffer getVertexBuffer() { + return this.mVertexBuffer; + } + + @Override + public float getWidth() { + return this.mWidth; + } + + @Override + public float getHeight() { + return this.mHeight; + } + + @Override + public float getBaseWidth() { + return this.mBaseWidth; + } + + @Override + public float getBaseHeight() { + return this.mBaseHeight; + } + + public void setWidth(final float pWidth) { + this.mWidth = pWidth; + this.updateVertexBuffer(); + } + + public void setHeight(final float pHeight) { + this.mHeight = pHeight; + this.updateVertexBuffer(); + } + + public void setSize(final float pWidth, final float pHeight) { + this.mWidth = pWidth; + this.mHeight = pHeight; + this.updateVertexBuffer(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public void setBaseSize() { + if(this.mWidth != this.mBaseWidth || this.mHeight != this.mBaseHeight) { + this.mWidth = this.mBaseWidth; + this.mHeight = this.mBaseHeight; + this.updateVertexBuffer(); + } + } + + @Override + protected boolean isCulled(final Camera pCamera) { + final float x = this.mX; + final float y = this.mY; + return x > pCamera.getMaxX() + || y > pCamera.getMaxY() + || x + this.getWidth() < pCamera.getMinX() + || y + this.getHeight() < pCamera.getMinY(); + } + + @Override + protected void drawVertices(final GL10 pGL, final Camera pCamera) { + pGL.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); + } + + @Override + public void reset() { + super.reset(); + this.setBaseSize(); + + final float baseWidth = this.getBaseWidth(); + final float baseHeight = this.getBaseHeight(); + + this.mRotationCenterX = baseWidth * 0.5f; + this.mRotationCenterY = baseHeight * 0.5f; + + this.mScaleCenterX = this.mRotationCenterX; + this.mScaleCenterY = this.mRotationCenterY; + } + + @Override + public boolean contains(final float pX, final float pY) { + return RectangularShapeCollisionChecker.checkContains(this, pX, pY); + } + + @Override + public float[] getSceneCenterCoordinates() { + return this.convertLocalToSceneCoordinates(this.mWidth * 0.5f, this.mHeight * 0.5f); + } + + @Override + public boolean collidesWith(final IShape pOtherShape) { + if(pOtherShape instanceof RectangularShape) { + final RectangularShape pOtherRectangularShape = (RectangularShape) pOtherShape; + + return RectangularShapeCollisionChecker.checkCollision(this, pOtherRectangularShape); + } else { + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/shape/Shape.java b/AndEngine/src/org/anddev/andengine/entity/shape/Shape.java new file mode 100644 index 0000000..ec8c03f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/shape/Shape.java @@ -0,0 +1,145 @@ +package org.anddev.andengine.entity.shape; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.Entity; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.opengl.vertex.VertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 11:51:27 - 13.03.2010 + */ +public abstract class Shape extends Entity implements IShape { + // =========================================================== + // Constants + // =========================================================== + + public static final int BLENDFUNCTION_SOURCE_DEFAULT = GL10.GL_SRC_ALPHA; + public static final int BLENDFUNCTION_DESTINATION_DEFAULT = GL10.GL_ONE_MINUS_SRC_ALPHA; + + public static final int BLENDFUNCTION_SOURCE_PREMULTIPLYALPHA_DEFAULT = GL10.GL_ONE; + public static final int BLENDFUNCTION_DESTINATION_PREMULTIPLYALPHA_DEFAULT = GL10.GL_ONE_MINUS_SRC_ALPHA; + + // =========================================================== + // Fields + // =========================================================== + + protected int mSourceBlendFunction = BLENDFUNCTION_SOURCE_DEFAULT; + protected int mDestinationBlendFunction = BLENDFUNCTION_DESTINATION_DEFAULT; + + private boolean mCullingEnabled = false; + + // =========================================================== + // Constructors + // =========================================================== + + public Shape(final float pX, final float pY) { + super(pX, pY); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public void setBlendFunction(final int pSourceBlendFunction, final int pDestinationBlendFunction) { + this.mSourceBlendFunction = pSourceBlendFunction; + this.mDestinationBlendFunction = pDestinationBlendFunction; + } + + @Override + public boolean isCullingEnabled() { + return this.mCullingEnabled; + } + + @Override + public void setCullingEnabled(final boolean pCullingEnabled) { + this.mCullingEnabled = pCullingEnabled; + } + + @Override + public float getWidthScaled() { + return this.getWidth() * this.mScaleX; + } + + @Override + public float getHeightScaled() { + return this.getHeight() * this.mScaleY; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onUpdateVertexBuffer(); + protected abstract VertexBuffer getVertexBuffer(); + + protected abstract void drawVertices(final GL10 pGL, final Camera pCamera); + + @Override + protected void doDraw(final GL10 pGL, final Camera pCamera) { + this.onInitDraw(pGL); + this.onApplyVertices(pGL); + this.drawVertices(pGL, pCamera); + } + + @Override + public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { + return false; + } + + /** + * Will only be performed if {@link Shape#isCullingEnabled()} is true. + * @param pCamera + * @return true when this object is visible by the {@link Camera}, false otherwise. + */ + protected abstract boolean isCulled(final Camera pCamera); + + @Override + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + if(this.mCullingEnabled == false || this.isCulled(pCamera) == false) { + super.onManagedDraw(pGL, pCamera); + } + } + + @Override + public void reset() { + super.reset(); + this.mSourceBlendFunction = BLENDFUNCTION_SOURCE_DEFAULT; + this.mDestinationBlendFunction = BLENDFUNCTION_DESTINATION_DEFAULT; + } + + // =========================================================== + // Methods + // =========================================================== + + protected void onInitDraw(final GL10 pGL) { + GLHelper.setColor(pGL, this.mRed, this.mGreen, this.mBlue, this.mAlpha); + + GLHelper.enableVertexArray(pGL); + GLHelper.blendFunction(pGL, this.mSourceBlendFunction, this.mDestinationBlendFunction); + } + + protected void onApplyVertices(final GL10 pGL) { + if(GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS) { + final GL11 gl11 = (GL11)pGL; + + this.getVertexBuffer().selectOnHardware(gl11); + GLHelper.vertexZeroPointer(gl11); + } else { + GLHelper.vertexPointer(pGL, this.getVertexBuffer().getFloatBuffer()); + } + } + + protected void updateVertexBuffer() { + this.onUpdateVertexBuffer(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/sprite/AnimatedSprite.java b/AndEngine/src/org/anddev/andengine/entity/sprite/AnimatedSprite.java new file mode 100644 index 0000000..5bbdc47 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/sprite/AnimatedSprite.java @@ -0,0 +1,256 @@ +package org.anddev.andengine.entity.sprite; + +import java.util.Arrays; + +import org.anddev.andengine.opengl.texture.region.TiledTextureRegion; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.constants.TimeConstants; + +public class AnimatedSprite extends TiledSprite implements TimeConstants { + // =========================================================== + // Constants + // =========================================================== + + private static final int LOOP_CONTINUOUS = -1; + + // =========================================================== + // Fields + // =========================================================== + + private boolean mAnimationRunning; + + private long mAnimationProgress; + private long mAnimationDuration; + private long[] mFrameEndsInNanoseconds; + + private int mFirstTileIndex; + private int mInitialLoopCount; + private int mLoopCount; + private IAnimationListener mAnimationListener; + + private int mFrameCount; + private int[] mFrames; + + // =========================================================== + // Constructors + // =========================================================== + + public AnimatedSprite(final float pX, final float pY, final TiledTextureRegion pTiledTextureRegion) { + super(pX, pY, pTiledTextureRegion); + } + + public AnimatedSprite(final float pX, final float pY, final float pTileWidth, final float pTileHeight, final TiledTextureRegion pTiledTextureRegion) { + super(pX, pY, pTileWidth, pTileHeight, pTiledTextureRegion); + } + + public AnimatedSprite(final float pX, final float pY, final TiledTextureRegion pTiledTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pTiledTextureRegion, pRectangleVertexBuffer); + } + + public AnimatedSprite(final float pX, final float pY, final float pTileWidth, final float pTileHeight, final TiledTextureRegion pTiledTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pTileWidth, pTileHeight, pTiledTextureRegion, pRectangleVertexBuffer); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isAnimationRunning() { + return this.mAnimationRunning; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + super.onManagedUpdate(pSecondsElapsed); + if(this.mAnimationRunning) { + final long nanoSecondsElapsed = (long) (pSecondsElapsed * TimeConstants.NANOSECONDSPERSECOND); + this.mAnimationProgress += nanoSecondsElapsed; + + if(this.mAnimationProgress > this.mAnimationDuration) { + this.mAnimationProgress %= this.mAnimationDuration; + if(this.mInitialLoopCount != AnimatedSprite.LOOP_CONTINUOUS) { + this.mLoopCount--; + } + } + + if(this.mInitialLoopCount == AnimatedSprite.LOOP_CONTINUOUS || this.mLoopCount >= 0) { + final int currentFrameIndex = this.calculateCurrentFrameIndex(); + + if(this.mFrames == null) { + this.setCurrentTileIndex(this.mFirstTileIndex + currentFrameIndex); + } else { + this.setCurrentTileIndex(this.mFrames[currentFrameIndex]); + } + } else { + this.mAnimationRunning = false; + if(this.mAnimationListener != null) { + this.mAnimationListener.onAnimationEnd(this); + } + } + } + } + + // =========================================================== + // Methods + // =========================================================== + + public void stopAnimation() { + this.mAnimationRunning = false; + } + + public void stopAnimation(final int pTileIndex) { + this.mAnimationRunning = false; + this.setCurrentTileIndex(pTileIndex); + } + + private int calculateCurrentFrameIndex() { + final long animationProgress = this.mAnimationProgress; + final long[] frameEnds = this.mFrameEndsInNanoseconds; + final int frameCount = this.mFrameCount; + for(int i = 0; i < frameCount; i++) { + if(frameEnds[i] > animationProgress) { + return i; + } + } + + return frameCount - 1; + } + + public AnimatedSprite animate(final long pFrameDurationEach) { + return this.animate(pFrameDurationEach, true); + } + + public AnimatedSprite animate(final long pFrameDurationEach, final boolean pLoop) { + return this.animate(pFrameDurationEach, (pLoop) ? AnimatedSprite.LOOP_CONTINUOUS : 0, null); + } + + public AnimatedSprite animate(final long pFrameDurationEach, final int pLoopCount) { + return this.animate(pFrameDurationEach, pLoopCount, null); + } + + public AnimatedSprite animate(final long pFrameDurationEach, final boolean pLoop, final IAnimationListener pAnimationListener) { + return this.animate(pFrameDurationEach, (pLoop) ? AnimatedSprite.LOOP_CONTINUOUS : 0, pAnimationListener); + } + + public AnimatedSprite animate(final long pFrameDurationEach, final int pLoopCount, final IAnimationListener pAnimationListener) { + final long[] frameDurations = new long[this.getTextureRegion().getTileCount()]; + Arrays.fill(frameDurations, pFrameDurationEach); + return this.animate(frameDurations, pLoopCount, pAnimationListener); + } + + public AnimatedSprite animate(final long[] pFrameDurations) { + return this.animate(pFrameDurations, true); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final boolean pLoop) { + return this.animate(pFrameDurations, (pLoop) ? AnimatedSprite.LOOP_CONTINUOUS : 0, null); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final int pLoopCount) { + return this.animate(pFrameDurations, pLoopCount, null); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final boolean pLoop, final IAnimationListener pAnimationListener) { + return this.animate(pFrameDurations, (pLoop) ? AnimatedSprite.LOOP_CONTINUOUS : 0, pAnimationListener); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final int pLoopCount, final IAnimationListener pAnimationListener) { + return this.animate(pFrameDurations, 0, this.getTextureRegion().getTileCount() - 1, pLoopCount, pAnimationListener); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final int pFirstTileIndex, final int pLastTileIndex, final boolean pLoop) { + return this.animate(pFrameDurations, pFirstTileIndex, pLastTileIndex, (pLoop) ? AnimatedSprite.LOOP_CONTINUOUS : 0, null); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final int pFirstTileIndex, final int pLastTileIndex, final int pLoopCount) { + return this.animate(pFrameDurations, pFirstTileIndex, pLastTileIndex, pLoopCount, null); + } + + public AnimatedSprite animate(final long[] pFrameDurations, final int[] pFrames, final int pLoopCount) { + return this.animate(pFrameDurations, pFrames, pLoopCount, null); + } + + /** + * Animate specifics frames + * + * @param pFrameDurations must have the same length as pFrames. + * @param pFrames indices of the frames to animate. + * @param pLoopCount + * @param pAnimationListener + */ + public AnimatedSprite animate(final long[] pFrameDurations, final int[] pFrames, final int pLoopCount, final IAnimationListener pAnimationListener) { + final int frameCount = pFrames.length; + if(pFrameDurations.length != frameCount) { + throw new IllegalArgumentException("pFrameDurations must have the same length as pFrames."); + } + + return this.init(pFrameDurations, frameCount, pFrames, 0, pLoopCount, pAnimationListener); + } + + /** + * @param pFrameDurations + * must have the same length as pFirstTileIndex to + * pLastTileIndex. + * @param pFirstTileIndex + * @param pLastTileIndex + * @param pLoopCount + * @param pAnimationListener + */ + public AnimatedSprite animate(final long[] pFrameDurations, final int pFirstTileIndex, final int pLastTileIndex, final int pLoopCount, final IAnimationListener pAnimationListener) { + if(pLastTileIndex - pFirstTileIndex < 1) { + throw new IllegalArgumentException("An animation needs at least two tiles to animate between."); + } + + final int frameCount = (pLastTileIndex - pFirstTileIndex) + 1; + if(pFrameDurations.length != frameCount) { + throw new IllegalArgumentException("pFrameDurations must have the same length as pFirstTileIndex to pLastTileIndex."); + } + + return this.init(pFrameDurations, frameCount, null, pFirstTileIndex, pLoopCount, pAnimationListener); + } + + private AnimatedSprite init(final long[] pFrameDurations, final int frameCount, final int[] pFrames, final int pFirstTileIndex, final int pLoopCount, final IAnimationListener pAnimationListener) { + this.mFrameCount = frameCount; + this.mAnimationListener = pAnimationListener; + this.mInitialLoopCount = pLoopCount; + this.mLoopCount = pLoopCount; + this.mFrames = pFrames; + this.mFirstTileIndex = pFirstTileIndex; + + if(this.mFrameEndsInNanoseconds == null || this.mFrameCount > this.mFrameEndsInNanoseconds.length) { + this.mFrameEndsInNanoseconds = new long[this.mFrameCount]; + } + + final long[] frameEndsInNanoseconds = this.mFrameEndsInNanoseconds; + MathUtils.arraySumInto(pFrameDurations, frameEndsInNanoseconds, TimeConstants.NANOSECONDSPERMILLISECOND); + + final long lastFrameEnd = frameEndsInNanoseconds[this.mFrameCount - 1]; + this.mAnimationDuration = lastFrameEnd; + + this.mAnimationProgress = 0; + this.mAnimationRunning = true; + + return this; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IAnimationListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public void onAnimationEnd(final AnimatedSprite pAnimatedSprite); + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/sprite/BaseSprite.java b/AndEngine/src/org/anddev/andengine/entity/sprite/BaseSprite.java new file mode 100644 index 0000000..59f2c4e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/sprite/BaseSprite.java @@ -0,0 +1,89 @@ +package org.anddev.andengine.entity.sprite; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.entity.primitive.BaseRectangle; +import org.anddev.andengine.opengl.texture.region.BaseTextureRegion; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 11:38:53 - 08.03.2010 + */ +public abstract class BaseSprite extends BaseRectangle { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final BaseTextureRegion mTextureRegion; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseSprite(final float pX, final float pY, final float pWidth, final float pHeight, final BaseTextureRegion pTextureRegion) { + super(pX, pY, pWidth, pHeight); + + this.mTextureRegion = pTextureRegion; + this.initBlendFunction(); + } + + public BaseSprite(final float pX, final float pY, final float pWidth, final float pHeight, final BaseTextureRegion pTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pWidth, pHeight, pRectangleVertexBuffer); + + this.mTextureRegion = pTextureRegion; + this.initBlendFunction(); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public BaseTextureRegion getTextureRegion() { + return this.mTextureRegion; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void reset() { + super.reset(); + + this.initBlendFunction(); + } + + @Override + protected void onInitDraw(final GL10 pGL) { + super.onInitDraw(pGL); + GLHelper.enableTextures(pGL); + GLHelper.enableTexCoordArray(pGL); + } + + @Override + protected void onApplyTransformations(final GL10 pGL) { + super.onApplyTransformations(pGL); + + this.mTextureRegion.onApply(pGL); + } + + // =========================================================== + // Methods + // =========================================================== + + private void initBlendFunction() { + if(this.mTextureRegion.getTexture().getTextureOptions().mPreMultipyAlpha) { + this.setBlendFunction(BLENDFUNCTION_SOURCE_PREMULTIPLYALPHA_DEFAULT, BLENDFUNCTION_DESTINATION_PREMULTIPLYALPHA_DEFAULT); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/sprite/Sprite.java b/AndEngine/src/org/anddev/andengine/entity/sprite/Sprite.java new file mode 100644 index 0000000..b10b406 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/sprite/Sprite.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.entity.sprite; + +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 19:22:38 - 09.03.2010 + */ +public class Sprite extends BaseSprite { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public Sprite(final float pX, final float pY, final TextureRegion pTextureRegion) { + super(pX, pY, pTextureRegion.getWidth(), pTextureRegion.getHeight(), pTextureRegion); + } + + public Sprite(final float pX, final float pY, final float pWidth, final float pHeight, final TextureRegion pTextureRegion) { + super(pX, pY, pWidth, pHeight, pTextureRegion); + } + + public Sprite(final float pX, final float pY, final TextureRegion pTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pTextureRegion.getWidth(), pTextureRegion.getHeight(), pTextureRegion, pRectangleVertexBuffer); + } + + public Sprite(final float pX, final float pY, final float pWidth, final float pHeight, final TextureRegion pTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pWidth, pHeight, pTextureRegion, pRectangleVertexBuffer); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public TextureRegion getTextureRegion() { + return (TextureRegion)this.mTextureRegion; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/sprite/TiledSprite.java b/AndEngine/src/org/anddev/andengine/entity/sprite/TiledSprite.java new file mode 100644 index 0000000..ca4e773 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/sprite/TiledSprite.java @@ -0,0 +1,75 @@ +package org.anddev.andengine.entity.sprite; + +import org.anddev.andengine.opengl.texture.region.TiledTextureRegion; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; + +/** + * @author Nicolas Gramlich + * @since 19:30:13 - 09.03.2010 + */ +public class TiledSprite extends BaseSprite { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TiledSprite(final float pX, final float pY, final TiledTextureRegion pTiledTextureRegion) { + super(pX, pY, pTiledTextureRegion.getTileWidth(), pTiledTextureRegion.getTileHeight(), pTiledTextureRegion); + } + + public TiledSprite(final float pX, final float pY, final float pTileWidth, final float pTileHeight, final TiledTextureRegion pTiledTextureRegion) { + super(pX, pY, pTileWidth, pTileHeight, pTiledTextureRegion); + } + + public TiledSprite(final float pX, final float pY, final TiledTextureRegion pTiledTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pTiledTextureRegion.getTileWidth(), pTiledTextureRegion.getTileHeight(), pTiledTextureRegion, pRectangleVertexBuffer); + } + + public TiledSprite(final float pX, final float pY, final float pTileWidth, final float pTileHeight, final TiledTextureRegion pTiledTextureRegion, final RectangleVertexBuffer pRectangleVertexBuffer) { + super(pX, pY, pTileWidth, pTileHeight, pTiledTextureRegion, pRectangleVertexBuffer); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public TiledTextureRegion getTextureRegion() { + return (TiledTextureRegion)super.getTextureRegion(); + } + + // =========================================================== + // Methods + // =========================================================== + + public int getCurrentTileIndex() { + return this.getTextureRegion().getCurrentTileIndex(); + } + + public void setCurrentTileIndex(final int pTileIndex) { + this.getTextureRegion().setCurrentTileIndex(pTileIndex); + } + + public void setCurrentTileIndex(final int pTileColumn, final int pTileRow) { + this.getTextureRegion().setCurrentTileIndex(pTileColumn, pTileRow); + } + + public void nextTile() { + this.getTextureRegion().nextTile(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/text/ChangeableText.java b/AndEngine/src/org/anddev/andengine/entity/text/ChangeableText.java new file mode 100644 index 0000000..c7512bd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/text/ChangeableText.java @@ -0,0 +1,90 @@ +package org.anddev.andengine.entity.text; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.opengl.font.Font; +import org.anddev.andengine.opengl.vertex.TextVertexBuffer; +import org.anddev.andengine.util.HorizontalAlign; +import org.anddev.andengine.util.StringUtils; + +/** + * @author Nicolas Gramlich + * @since 18:07:06 - 08.07.2010 + */ +public class ChangeableText extends Text { + // =========================================================== + // Constants + // =========================================================== + + private static final String ELLIPSIS = "..."; + private static final int ELLIPSIS_CHARACTER_COUNT = ELLIPSIS.length(); + + // =========================================================== + // Fields + // =========================================================== + + private int mCharacterCountCurrentText; + + // =========================================================== + // Constructors + // =========================================================== + + public ChangeableText(final float pX, final float pY, final Font pFont, final String pText) { + this(pX, pY, pFont, pText, pText.length() - StringUtils.countOccurrences(pText, '\n')); + } + + public ChangeableText(final float pX, final float pY, final Font pFont, final String pText, final int pCharactersMaximum) { + this(pX, pY, pFont, pText, HorizontalAlign.LEFT, pCharactersMaximum); + } + + public ChangeableText(final float pX, final float pY, final Font pFont, final String pText, final HorizontalAlign pHorizontalAlign, final int pCharactersMaximum) { + super(pX, pY, pFont, pText, pHorizontalAlign, pCharactersMaximum); + this.mCharacterCountCurrentText = pText.length() - StringUtils.countOccurrences(pText, '\n'); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void setText(final String pText) { + this.setText(pText, false); + } + + /** + * @param pText + * @param pAllowEllipsis in the case pText is longer than pCharactersMaximum, + * which was passed to the constructor, the displayed text will end with an ellipsis ("..."). + */ + public void setText(final String pText, final boolean pAllowEllipsis) { + final int textCharacterCount = pText.length() - StringUtils.countOccurrences(pText, '\n'); + if(textCharacterCount > this.mCharactersMaximum) { + if(pAllowEllipsis && this.mCharactersMaximum > ELLIPSIS_CHARACTER_COUNT) { + this.updateText(pText.substring(0, this.mCharactersMaximum - ELLIPSIS_CHARACTER_COUNT).concat(ELLIPSIS)); // TODO This allocation could maybe be avoided... + } else { + this.updateText(pText.substring(0, this.mCharactersMaximum)); // TODO This allocation could be avoided... + } + this.mCharacterCountCurrentText = this.mCharactersMaximum; + } else { + this.updateText(pText); + this.mCharacterCountCurrentText = textCharacterCount; + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void drawVertices(final GL10 pGL, final Camera pCamera) { + pGL.glDrawArrays(GL10.GL_TRIANGLES, 0, this.mCharacterCountCurrentText * TextVertexBuffer.VERTICES_PER_CHARACTER); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/text/Text.java b/AndEngine/src/org/anddev/andengine/entity/text/Text.java new file mode 100644 index 0000000..391c3af --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/text/Text.java @@ -0,0 +1,179 @@ +package org.anddev.andengine.entity.text; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.shape.RectangularShape; +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.font.Font; +import org.anddev.andengine.opengl.texture.buffer.TextTextureBuffer; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.opengl.vertex.TextVertexBuffer; +import org.anddev.andengine.util.HorizontalAlign; +import org.anddev.andengine.util.StringUtils; + +/** + * @author Nicolas Gramlich + * @since 10:54:59 - 03.04.2010 + */ +public class Text extends RectangularShape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final TextTextureBuffer mTextTextureBuffer; + + private String mText; + private String[] mLines; + private int[] mWidths; + + private final Font mFont; + + private int mMaximumLineWidth; + + protected final int mCharactersMaximum; + protected final int mVertexCount; + + // =========================================================== + // Constructors + // =========================================================== + + public Text(final float pX, final float pY, final Font pFont, final String pText) { + this(pX, pY, pFont, pText, HorizontalAlign.LEFT); + } + + public Text(final float pX, final float pY, final Font pFont, final String pText, final HorizontalAlign pHorizontalAlign) { + this(pX, pY, pFont, pText, pHorizontalAlign, pText.length() - StringUtils.countOccurrences(pText, '\n')); + } + + protected Text(final float pX, final float pY, final Font pFont, final String pText, final HorizontalAlign pHorizontalAlign, final int pCharactersMaximum) { + super(pX, pY, 0, 0, new TextVertexBuffer(pCharactersMaximum, pHorizontalAlign, GL11.GL_STATIC_DRAW)); + + this.mCharactersMaximum = pCharactersMaximum; + this.mVertexCount = TextVertexBuffer.VERTICES_PER_CHARACTER * this.mCharactersMaximum; + + this.mTextTextureBuffer = new TextTextureBuffer(2 * this.mVertexCount, GL11.GL_STATIC_DRAW); + BufferObjectManager.getActiveInstance().loadBufferObject(this.mTextTextureBuffer); + this.mFont = pFont; + + this.updateText(pText); + + this.initBlendFunction(); + } + + protected void updateText(final String pText) { + this.mText = pText; + final Font font = this.mFont; + + this.mLines = StringUtils.split(this.mText, '\n', this.mLines); + final String[] lines = this.mLines; + + final int lineCount = lines.length; + final boolean widthsReusable = this.mWidths != null && this.mWidths.length == lineCount; + if(widthsReusable == false) { + this.mWidths = new int[lineCount]; + } + final int[] widths = this.mWidths; + + int maximumLineWidth = 0; + + for (int i = lineCount - 1; i >= 0; i--) { + widths[i] = font.getStringWidth(lines[i]); + maximumLineWidth = Math.max(maximumLineWidth, widths[i]); + } + this.mMaximumLineWidth = maximumLineWidth; + + super.mWidth = this.mMaximumLineWidth; + final float width = super.mWidth; + super.mBaseWidth = width; + + super.mHeight = lineCount * font.getLineHeight() + (lineCount - 1) * font.getLineGap(); + final float height = super.mHeight; + super.mBaseHeight = height; + + this.mRotationCenterX = width * 0.5f; + this.mRotationCenterY = height * 0.5f; + + this.mScaleCenterX = this.mRotationCenterX; + this.mScaleCenterY = this.mRotationCenterY; + + this.mTextTextureBuffer.update(font, lines); + this.updateVertexBuffer(); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getCharacterCount() { + return this.mCharactersMaximum; + } + + @Override + public TextVertexBuffer getVertexBuffer() { + return (TextVertexBuffer)super.getVertexBuffer(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onInitDraw(final GL10 pGL) { + super.onInitDraw(pGL); + GLHelper.enableTextures(pGL); + GLHelper.enableTexCoordArray(pGL); + } + + @Override + protected void drawVertices(final GL10 pGL, final Camera pCamera) { + pGL.glDrawArrays(GL10.GL_TRIANGLES, 0, this.mVertexCount); + } + + @Override + protected void onUpdateVertexBuffer() { + final Font font = this.mFont; + if(font != null) { + this.getVertexBuffer().update(font, this.mMaximumLineWidth, this.mWidths, this.mLines); + } + } + + @Override + protected void onApplyTransformations(final GL10 pGL) { + super.onApplyTransformations(pGL); + this.applyTexture(pGL); + } + + // =========================================================== + // Methods + // =========================================================== + + private void initBlendFunction() { + if(this.mFont.getTexture().getTextureOptions().mPreMultipyAlpha) { + this.setBlendFunction(BLENDFUNCTION_SOURCE_PREMULTIPLYALPHA_DEFAULT, BLENDFUNCTION_DESTINATION_PREMULTIPLYALPHA_DEFAULT); + } + } + + private void applyTexture(final GL10 pGL) { + if(GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS) { + final GL11 gl11 = (GL11)pGL; + + this.mTextTextureBuffer.selectOnHardware(gl11); + + GLHelper.bindTexture(pGL, this.mFont.getTexture().getHardwareTextureID()); + GLHelper.texCoordZeroPointer(gl11); + } else { + GLHelper.bindTexture(pGL, this.mFont.getTexture().getHardwareTextureID()); + GLHelper.texCoordPointer(pGL, this.mTextTextureBuffer.getFloatBuffer()); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/entity/text/TickerText.java b/AndEngine/src/org/anddev/andengine/entity/text/TickerText.java new file mode 100644 index 0000000..79b34a5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/text/TickerText.java @@ -0,0 +1,107 @@ +package org.anddev.andengine.entity.text; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.opengl.font.Font; +import org.anddev.andengine.opengl.vertex.TextVertexBuffer; +import org.anddev.andengine.util.HorizontalAlign; + +/** + * @author Nicolas Gramlich + * @since 10:02:04 - 05.05.2010 + */ +public class TickerText extends Text { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mCharactersPerSecond; + + private int mCharactersVisible = 0; + private float mSecondsElapsed = 0; + + private boolean mReverse = false; + + private float mDuration; + + // =========================================================== + // Constructors + // =========================================================== + + public TickerText(final float pX, final float pY, final Font pFont, final String pText, final HorizontalAlign pHorizontalAlign, final float pCharactersPerSecond) { + super(pX, pY, pFont, pText, pHorizontalAlign); + this.setCharactersPerSecond(pCharactersPerSecond); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isReverse() { + return this.mReverse; + } + + public void setReverse(final boolean pReverse) { + this.mReverse = pReverse; + } + + public float getCharactersPerSecond() { + return this.mCharactersPerSecond; + } + + public void setCharactersPerSecond(final float pCharactersPerSecond) { + this.mCharactersPerSecond = pCharactersPerSecond; + this.mDuration = this.mCharactersMaximum * this.mCharactersPerSecond; + } + + public int getCharactersVisible() { + return this.mCharactersVisible; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + super.onManagedUpdate(pSecondsElapsed); + if(this.mReverse){ + if(this.mCharactersVisible < this.mCharactersMaximum){ + this.mSecondsElapsed = Math.max(0, this.mSecondsElapsed - pSecondsElapsed); + this.mCharactersVisible = (int)(this.mSecondsElapsed * this.mCharactersPerSecond); + } + } else { + if(this.mCharactersVisible < this.mCharactersMaximum){ + this.mSecondsElapsed = Math.min(this.mDuration, this.mSecondsElapsed + pSecondsElapsed); + this.mCharactersVisible = (int)(this.mSecondsElapsed * this.mCharactersPerSecond); + } + } + } + + @Override + protected void drawVertices(final GL10 pGL, final Camera pCamera) { + pGL.glDrawArrays(GL10.GL_TRIANGLES, 0, this.mCharactersVisible * TextVertexBuffer.VERTICES_PER_CHARACTER); + } + + @Override + public void reset() { + super.reset(); + + this.mCharactersVisible = 0; + this.mSecondsElapsed = 0; + this.mReverse = false; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/AverageFPSCounter.java b/AndEngine/src/org/anddev/andengine/entity/util/AverageFPSCounter.java new file mode 100644 index 0000000..67e8bba --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/AverageFPSCounter.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.entity.util; + +import org.anddev.andengine.util.constants.TimeConstants; + + +/** + * @author Nicolas Gramlich + * @since 19:52:31 - 09.03.2010 + */ +public abstract class AverageFPSCounter extends FPSCounter implements TimeConstants { + // =========================================================== + // Constants + // =========================================================== + + private static final float AVERAGE_DURATION_DEFAULT = 5; + + // =========================================================== + // Fields + // =========================================================== + + protected final float mAverageDuration; + + // =========================================================== + // Constructors + // =========================================================== + + public AverageFPSCounter() { + this(AVERAGE_DURATION_DEFAULT); + } + + public AverageFPSCounter(final float pAverageDuration) { + this.mAverageDuration = pAverageDuration; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onHandleAverageDurationElapsed(final float pFPS); + + @Override + public void onUpdate(final float pSecondsElapsed) { + super.onUpdate(pSecondsElapsed); + + if(this.mSecondsElapsed > this.mAverageDuration){ + this.onHandleAverageDurationElapsed(this.getFPS()); + + this.mSecondsElapsed -= this.mAverageDuration; + this.mFrames = 0; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/FPSCounter.java b/AndEngine/src/org/anddev/andengine/entity/util/FPSCounter.java new file mode 100644 index 0000000..ca7c451 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/FPSCounter.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.entity.util; + +import org.anddev.andengine.engine.handler.IUpdateHandler; + +/** + * @author Nicolas Gramlich + * @since 19:52:31 - 09.03.2010 + */ +public class FPSCounter implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mSecondsElapsed; + + protected int mFrames; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getFPS() { + return this.mFrames / this.mSecondsElapsed; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mFrames++; + this.mSecondsElapsed += pSecondsElapsed; + } + + @Override + public void reset() { + this.mFrames = 0; + this.mSecondsElapsed = 0; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/FPSLogger.java b/AndEngine/src/org/anddev/andengine/entity/util/FPSLogger.java new file mode 100644 index 0000000..9fff9a6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/FPSLogger.java @@ -0,0 +1,79 @@ +package org.anddev.andengine.entity.util; + +import org.anddev.andengine.util.Debug; + +/** + * @author Nicolas Gramlich + * @since 19:52:31 - 09.03.2010 + */ +public class FPSLogger extends AverageFPSCounter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected float mShortestFrame = Float.MAX_VALUE; + protected float mLongestFrame = Float.MIN_VALUE; + + // =========================================================== + // Constructors + // =========================================================== + + public FPSLogger() { + super(); + } + + public FPSLogger(final float pAverageDuration) { + super(pAverageDuration); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onHandleAverageDurationElapsed(final float pFPS) { + this.onLogFPS(); + + this.mLongestFrame = Float.MIN_VALUE; + this.mShortestFrame = Float.MAX_VALUE; + } + + @Override + public void onUpdate(final float pSecondsElapsed) { + super.onUpdate(pSecondsElapsed); + + this.mShortestFrame = Math.min(this.mShortestFrame, pSecondsElapsed); + this.mLongestFrame = Math.max(this.mLongestFrame, pSecondsElapsed); + } + + @Override + public void reset() { + super.reset(); + + this.mShortestFrame = Float.MAX_VALUE; + this.mLongestFrame = Float.MIN_VALUE; + } + + // =========================================================== + // Methods + // =========================================================== + + protected void onLogFPS() { + Debug.d(String.format("FPS: %.2f (MIN: %.0f ms | MAX: %.0f ms)", + this.mFrames / this.mSecondsElapsed, + this.mShortestFrame * MILLISECONDSPERSECOND, + this.mLongestFrame * MILLISECONDSPERSECOND)); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/FrameCountCrasher.java b/AndEngine/src/org/anddev/andengine/entity/util/FrameCountCrasher.java new file mode 100644 index 0000000..34b7cee --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/FrameCountCrasher.java @@ -0,0 +1,69 @@ +package org.anddev.andengine.entity.util; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.constants.TimeConstants; + +/** + * @author Nicolas Gramlich + * @since 19:52:31 - 09.03.2010 + */ +public class FrameCountCrasher implements IUpdateHandler, TimeConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private int mFramesLeft; + + private final float[] mFrameLengths; + + // =========================================================== + // Constructors + // =========================================================== + + public FrameCountCrasher(final int pFrameCount) { + this.mFramesLeft = pFrameCount; + this.mFrameLengths = new float[pFrameCount]; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mFramesLeft--; + + final float[] frameLengths = this.mFrameLengths; + if(this.mFramesLeft >= 0) { + frameLengths[this.mFramesLeft] = pSecondsElapsed; + } else { + for(int i = frameLengths.length - 1; i >= 0; i--) { + Debug.d("Elapsed: " + frameLengths[i]); + } + + throw new RuntimeException(); + } + } + + @Override + public void reset() { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/FrameCounter.java b/AndEngine/src/org/anddev/andengine/entity/util/FrameCounter.java new file mode 100644 index 0000000..a96509f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/FrameCounter.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.entity.util; + +import org.anddev.andengine.engine.handler.IUpdateHandler; + +/** + * @author Nicolas Gramlich + * @since 11:00:55 - 22.06.2010 + */ +public class FrameCounter implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private int mFrames; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getFrames() { + return this.mFrames; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mFrames++; + } + + @Override + public void reset() { + this.mFrames = 0; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/ScreenCapture.java b/AndEngine/src/org/anddev/andengine/entity/util/ScreenCapture.java new file mode 100644 index 0000000..7ee0382 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/ScreenCapture.java @@ -0,0 +1,121 @@ +package org.anddev.andengine.entity.util; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.Entity; +import org.anddev.andengine.entity.util.ScreenGrabber.IScreenGrabberCallback; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.StreamUtils; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; + +/** + * @author Nicolas Gramlich + * @since 15:11:50 - 15.03.2010 + */ +public class ScreenCapture extends Entity implements IScreenGrabberCallback { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private String mFilePath; + + private final ScreenGrabber mScreenGrabber = new ScreenGrabber(); + + private IScreenCaptureCallback mScreenCaptureCallback; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + this.mScreenGrabber.onManagedDraw(pGL, pCamera); + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + /* Nothing */ + } + + @Override + public void reset() { + /* Nothing */ + } + + @Override + public void onScreenGrabbed(final Bitmap pBitmap) { + try { + ScreenCapture.saveCapture(pBitmap, this.mFilePath); + this.mScreenCaptureCallback.onScreenCaptured(this.mFilePath); + } catch (final FileNotFoundException e) { + this.mScreenCaptureCallback.onScreenCaptureFailed(this.mFilePath, e); + } + } + + @Override + public void onScreenGrabFailed(final Exception pException) { + this.mScreenCaptureCallback.onScreenCaptureFailed(this.mFilePath, pException); + } + + // =========================================================== + // Methods + // =========================================================== + + public void capture(final int pCaptureWidth, final int pCaptureHeight, final String pFilePath, final IScreenCaptureCallback pScreenCaptureCallback) { + this.capture(0, 0, pCaptureWidth, pCaptureHeight, pFilePath, pScreenCaptureCallback); + } + + public void capture(final int pCaptureX, final int pCaptureY, final int pCaptureWidth, final int pCaptureHeight, final String pFilePath, final IScreenCaptureCallback pScreencaptureCallback) { + this.mFilePath = pFilePath; + this.mScreenCaptureCallback = pScreencaptureCallback; + this.mScreenGrabber.grab(pCaptureX, pCaptureY, pCaptureWidth, pCaptureHeight, this); + } + + private static void saveCapture(final Bitmap pBitmap, final String pFilePath) throws FileNotFoundException { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(pFilePath); + pBitmap.compress(CompressFormat.PNG, 100, fos); + + } catch (final FileNotFoundException e) { + StreamUtils.flushCloseStream(fos); + Debug.e("Error saving file to: " + pFilePath, e); + throw e; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IScreenCaptureCallback { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onScreenCaptured(final String pFilePath); + public void onScreenCaptureFailed(final String pFilePath, final Exception pException); + } +} diff --git a/AndEngine/src/org/anddev/andengine/entity/util/ScreenGrabber.java b/AndEngine/src/org/anddev/andengine/entity/util/ScreenGrabber.java new file mode 100644 index 0000000..7219944 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/entity/util/ScreenGrabber.java @@ -0,0 +1,132 @@ +package org.anddev.andengine.entity.util; + +import java.nio.IntBuffer; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.entity.Entity; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; + +/** + * @author Nicolas Gramlich + * @since 15:27:22 - 10.01.2011 + */ +public class ScreenGrabber extends Entity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private int mGrabX; + private int mGrabY; + private int mGrabWidth; + private int mGrabHeight; + + private boolean mScreenGrabPending = false; + private IScreenGrabberCallback mScreenGrabCallback; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onManagedDraw(final GL10 pGL, final Camera pCamera) { + if(this.mScreenGrabPending) { + try { + final Bitmap screenGrab = ScreenGrabber.grab(this.mGrabX, this.mGrabY, this.mGrabWidth, this.mGrabHeight, pGL); + + this.mScreenGrabCallback.onScreenGrabbed(screenGrab); + } catch (final Exception e) { + this.mScreenGrabCallback.onScreenGrabFailed(e); + } + + this.mScreenGrabPending = false; + } + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed) { + /* Nothing */ + } + + @Override + public void reset() { + /* Nothing */ + } + + // =========================================================== + // Methods + // =========================================================== + + public void grab(final int pGrabWidth, final int pGrabHeight, final IScreenGrabberCallback pScreenGrabCallback) { + this.grab(0, 0, pGrabWidth, pGrabHeight, pScreenGrabCallback); + } + + public void grab(final int pGrabX, final int pGrabY, final int pGrabWidth, final int pGrabHeight, final IScreenGrabberCallback pScreenGrabCallback) { + this.mGrabX = pGrabX; + this.mGrabY = pGrabY; + this.mGrabWidth = pGrabWidth; + this.mGrabHeight = pGrabHeight; + this.mScreenGrabCallback = pScreenGrabCallback; + + this.mScreenGrabPending = true; + } + + private static Bitmap grab(final int pGrabX, final int pGrabY, final int pGrabWidth, final int pGrabHeight, final GL10 pGL) { + final int[] source = new int[pGrabWidth * (pGrabY + pGrabHeight)]; + final IntBuffer sourceBuffer = IntBuffer.wrap(source); + sourceBuffer.position(0); + + // TODO Check availability of OpenGL and GL10.GL_RGBA combinations that require less conversion operations. + // Note: There is (said to be) a bug with glReadPixels when 'y != 0', so we simply read starting from 'y == 0'. + pGL.glReadPixels(pGrabX, 0, pGrabWidth, pGrabY + pGrabHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, sourceBuffer); + + final int[] pixels = new int[pGrabWidth * pGrabHeight]; + + // Convert from RGBA_8888 (Which is actually ABGR as the whole buffer seems to be inverted) --> ARGB_8888 + for (int y = 0; y < pGrabHeight; y++) { + for (int x = 0; x < pGrabWidth; x++) { + final int pixel = source[x + ((pGrabY + y) * pGrabWidth)]; + + final int blue = (pixel & 0x00FF0000) >> 16; + final int red = (pixel & 0x000000FF) << 16; + final int greenAlpha = pixel & 0xFF00FF00; + + pixels[x + ((pGrabHeight - y - 1) * pGrabWidth)] = greenAlpha | red | blue; + } + } + + return Bitmap.createBitmap(pixels, pGrabWidth, pGrabHeight, Config.ARGB_8888); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IScreenGrabberCallback { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onScreenGrabbed(final Bitmap pBitmap); + public void onScreenGrabFailed(final Exception pException); + } +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/FixedStepPhysicsWorld.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/FixedStepPhysicsWorld.java new file mode 100644 index 0000000..4d9f59b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/FixedStepPhysicsWorld.java @@ -0,0 +1,89 @@ +package org.anddev.andengine.extension.physics.box2d; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.World; + +/** + * A subclass of {@link PhysicsWorld} that tries to achieve a specific amount of steps per second. + * When the time since the last step is bigger long the steplength, additional steps are executed. + * + * @author Nicolas Gramlich + * @since 12:39:42 - 25.07.2010 + */ +public class FixedStepPhysicsWorld extends PhysicsWorld { + // =========================================================== + // Constants + // =========================================================== + + public static final int STEPSPERSECOND_DEFAULT = 60; + + // =========================================================== + // Fields + // =========================================================== + + private final float mTimeStep; + private final int mMaximumStepsPerUpdate; + private float mSecondsElapsedAccumulator; + + // =========================================================== + // Constructors + // =========================================================== + + public FixedStepPhysicsWorld(final int pStepsPerSecond, final Vector2 pGravity, final boolean pAllowSleep) { + this(pStepsPerSecond, Integer.MAX_VALUE, pGravity, pAllowSleep); + } + + public FixedStepPhysicsWorld(final int pStepsPerSecond, final int pMaximumStepsPerUpdate, final Vector2 pGravity, final boolean pAllowSleep) { + super(pGravity, pAllowSleep); + this.mTimeStep = 1.0f / pStepsPerSecond; + this.mMaximumStepsPerUpdate = pMaximumStepsPerUpdate; + } + + public FixedStepPhysicsWorld(final int pStepsPerSecond, final Vector2 pGravity, final boolean pAllowSleep, final int pVelocityIterations, final int pPositionIterations) { + this(pStepsPerSecond, Integer.MAX_VALUE, pGravity, pAllowSleep, pVelocityIterations, pPositionIterations); + } + + public FixedStepPhysicsWorld(final int pStepsPerSecond, final int pMaximumStepsPerUpdate, final Vector2 pGravity, final boolean pAllowSleep, final int pVelocityIterations, final int pPositionIterations) { + super(pGravity, pAllowSleep, pVelocityIterations, pPositionIterations); + this.mTimeStep = 1.0f / pStepsPerSecond; + this.mMaximumStepsPerUpdate = pMaximumStepsPerUpdate; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mRunnableHandler.onUpdate(pSecondsElapsed); + this.mSecondsElapsedAccumulator += pSecondsElapsed; + + final int velocityIterations = this.mVelocityIterations; + final int positionIterations = this.mPositionIterations; + + final World world = this.mWorld; + final float stepLength = this.mTimeStep; + + int stepsAllowed = this.mMaximumStepsPerUpdate; + + while(this.mSecondsElapsedAccumulator >= stepLength && stepsAllowed > 0) { + world.step(stepLength, velocityIterations, positionIterations); + this.mSecondsElapsedAccumulator -= stepLength; + stepsAllowed--; + } + + this.mPhysicsConnectorManager.onUpdate(pSecondsElapsed); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsConnector.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsConnector.java new file mode 100644 index 0000000..06f11ef --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsConnector.java @@ -0,0 +1,123 @@ +package org.anddev.andengine.extension.physics.box2d; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.entity.shape.IShape; +import org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants; +import org.anddev.andengine.util.MathUtils; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; + +/** + * @author Nicolas Gramlich + * @since 18:51:22 - 05.07.2010 + */ +public class PhysicsConnector implements IUpdateHandler, PhysicsConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final IShape mShape; + protected final Body mBody; + + protected final float mShapeHalfBaseWidth; + protected final float mShapeHalfBaseHeight; + + protected boolean mUpdatePosition; + protected boolean mUpdateRotation; + protected final float mPixelToMeterRatio; + + // =========================================================== + // Constructors + // =========================================================== + + public PhysicsConnector(final IShape pShape, final Body pBody) { + this(pShape, pBody, true, true); + } + + public PhysicsConnector(final IShape pShape, final Body pBody, final float pPixelToMeterRatio) { + this(pShape, pBody, true, true, pPixelToMeterRatio); + } + + public PhysicsConnector(final IShape pShape, final Body pBody, final boolean pUdatePosition, final boolean pUpdateRotation) { + this(pShape, pBody, pUdatePosition, pUpdateRotation, PIXEL_TO_METER_RATIO_DEFAULT); + } + + public PhysicsConnector(final IShape pShape, final Body pBody, final boolean pUdatePosition, final boolean pUpdateRotation, final float pPixelToMeterRatio) { + this.mShape = pShape; + this.mBody = pBody; + + this.mUpdatePosition = pUdatePosition; + this.mUpdateRotation = pUpdateRotation; + this.mPixelToMeterRatio = pPixelToMeterRatio; + + this.mShapeHalfBaseWidth = pShape.getBaseWidth() * 0.5f; + this.mShapeHalfBaseHeight = pShape.getBaseHeight() * 0.5f; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public IShape getShape() { + return this.mShape; + } + + public Body getBody() { + return this.mBody; + } + + public boolean isUpdatePosition() { + return this.mUpdatePosition; + } + + public boolean isUpdateRotation() { + return this.mUpdateRotation; + } + + public void setUpdatePosition(final boolean pUpdatePosition) { + this.mUpdatePosition = pUpdatePosition; + } + + public void setUpdateRotation(final boolean pUpdateRotation) { + this.mUpdateRotation = pUpdateRotation; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + final IShape shape = this.mShape; + final Body body = this.mBody; + + if(this.mUpdatePosition) { + final Vector2 position = body.getPosition(); + final float pixelToMeterRatio = this.mPixelToMeterRatio; + shape.setPosition(position.x * pixelToMeterRatio - this.mShapeHalfBaseWidth, position.y * pixelToMeterRatio - this.mShapeHalfBaseHeight); + } + + if(this.mUpdateRotation) { + final float angle = body.getAngle(); + shape.setRotation(MathUtils.radToDeg(angle)); + } + } + + @Override + public void reset() { + + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsConnectorManager.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsConnectorManager.java new file mode 100644 index 0000000..d7a0d1f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsConnectorManager.java @@ -0,0 +1,86 @@ +package org.anddev.andengine.extension.physics.box2d; + +import java.util.ArrayList; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.entity.shape.IShape; + +import com.badlogic.gdx.physics.box2d.Body; + +/** + * @author Nicolas Gramlich + * @since 15:52:27 - 15.07.2010 + */ +public class PhysicsConnectorManager extends ArrayList implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 412969510084261799L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + PhysicsConnectorManager() { + + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + final ArrayList physicsConnectors = this; + for(int i = physicsConnectors.size() - 1; i >= 0; i--) { + physicsConnectors.get(i).onUpdate(pSecondsElapsed); + } + } + + @Override + public void reset() { + final ArrayList physicsConnectors = this; + for(int i = physicsConnectors.size() - 1; i >= 0; i--) { + physicsConnectors.get(i).reset(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + public Body findBodyByShape(final IShape pShape) { + final ArrayList physicsConnectors = this; + for(int i = physicsConnectors.size() - 1; i >= 0; i--) { + final PhysicsConnector physicsConnector = physicsConnectors.get(i); + if(physicsConnector.mShape == pShape){ + return physicsConnector.mBody; + } + } + return null; + } + + public PhysicsConnector findPhysicsConnectorByShape(final IShape pShape) { + final ArrayList physicsConnectors = this; + for(int i = physicsConnectors.size() - 1; i >= 0; i--) { + final PhysicsConnector physicsConnector = physicsConnectors.get(i); + if(physicsConnector.mShape == pShape){ + return physicsConnector; + } + } + return null; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsFactory.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsFactory.java new file mode 100644 index 0000000..f986970 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsFactory.java @@ -0,0 +1,260 @@ +package org.anddev.andengine.extension.physics.box2d; + + +import static org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT; + +import java.util.List; + +import org.anddev.andengine.entity.primitive.Line; +import org.anddev.andengine.entity.shape.IShape; +import org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants; +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.constants.Constants; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.BodyDef.BodyType; +import com.badlogic.gdx.physics.box2d.CircleShape; +import com.badlogic.gdx.physics.box2d.Filter; +import com.badlogic.gdx.physics.box2d.Fixture; +import com.badlogic.gdx.physics.box2d.FixtureDef; +import com.badlogic.gdx.physics.box2d.PolygonShape; + +/** + * @author Nicolas Gramlich + * @since 13:59:03 - 15.07.2010 + */ +public class PhysicsFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction) { + return PhysicsFactory.createFixtureDef(pDensity, pElasticity, pFriction, false); + } + + public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction, final boolean pSensor) { + final FixtureDef fixtureDef = new FixtureDef(); + fixtureDef.density = pDensity; + fixtureDef.restitution = pElasticity; + fixtureDef.friction = pFriction; + fixtureDef.isSensor = pSensor; + return fixtureDef; + } + + public static FixtureDef createFixtureDef(final float pDensity, final float pElasticity, final float pFriction, final boolean pSensor, final short pCategoryBits, final short pMaskBits, final short pGroupIndex) { + final FixtureDef fixtureDef = new FixtureDef(); + fixtureDef.density = pDensity; + fixtureDef.restitution = pElasticity; + fixtureDef.friction = pFriction; + fixtureDef.isSensor = pSensor; + final Filter filter = fixtureDef.filter; + filter.categoryBits = pCategoryBits; + filter.maskBits = pMaskBits; + filter.groupIndex = pGroupIndex; + return fixtureDef; + } + + public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final BodyType pBodyType, final FixtureDef pFixtureDef) { + return PhysicsFactory.createBoxBody(pPhysicsWorld, pIShape, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); + } + + public static Body createBoxBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { + final BodyDef boxBodyDef = new BodyDef(); + boxBodyDef.type = pBodyType; + + final float[] sceneCenterCoordinates = pIShape.getSceneCenterCoordinates(); + boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; + boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; + + final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); + + final PolygonShape boxPoly = new PolygonShape(); + + final float halfWidth = pIShape.getWidthScaled() * 0.5f / pPixelToMeterRatio; + final float halfHeight = pIShape.getHeightScaled() * 0.5f / pPixelToMeterRatio; + + boxPoly.setAsBox(halfWidth, halfHeight); + pFixtureDef.shape = boxPoly; + + boxBody.createFixture(pFixtureDef); + + boxPoly.dispose(); + + boxBody.setTransform(boxBody.getWorldCenter(), MathUtils.degToRad(pIShape.getRotation())); + + return boxBody; + } + + public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final BodyType pBodyType, final FixtureDef pFixtureDef) { + return PhysicsFactory.createCircleBody(pPhysicsWorld, pIShape, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); + } + + public static Body createCircleBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { + + final BodyDef circleBodyDef = new BodyDef(); + circleBodyDef.type = pBodyType; + + final float[] sceneCenterCoordinates = pIShape.getSceneCenterCoordinates(); + circleBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; + circleBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; + + circleBodyDef.angle = MathUtils.degToRad(pIShape.getRotation()); + + final Body circleBody = pPhysicsWorld.createBody(circleBodyDef); + + final CircleShape circlePoly = new CircleShape(); + pFixtureDef.shape = circlePoly; + + final float radius = pIShape.getWidthScaled() * 0.5f / pPixelToMeterRatio; + circlePoly.setRadius(radius); + + circleBody.createFixture(pFixtureDef); + + circlePoly.dispose(); + + return circleBody; + } + + public static Body createLineBody(final PhysicsWorld pPhysicsWorld, final Line pLine, final FixtureDef pFixtureDef) { + return PhysicsFactory.createLineBody(pPhysicsWorld, pLine, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); + } + + public static Body createLineBody(final PhysicsWorld pPhysicsWorld, final Line pLine, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { + final BodyDef lineBodyDef = new BodyDef(); + lineBodyDef.type = BodyType.StaticBody; + + final Body boxBody = pPhysicsWorld.createBody(lineBodyDef); + + final PolygonShape linePoly = new PolygonShape(); + + linePoly.setAsEdge(new Vector2(pLine.getX1() / pPixelToMeterRatio, pLine.getY1() / pPixelToMeterRatio), new Vector2(pLine.getX2() / pPixelToMeterRatio, pLine.getY2() / pPixelToMeterRatio)); + pFixtureDef.shape = linePoly; + + boxBody.createFixture(pFixtureDef); + + linePoly.dispose(); + + return boxBody; + } + + /** + * @param pPhysicsWorld + * @param pIShape + * @param pVertices are to be defined relative to the center of the pIShape and have the {@link PhysicsConstants#PIXEL_TO_METER_RATIO_DEFAULT} applied. + * @param pBodyType + * @param pFixtureDef + * @return + */ + public static Body createPolygonBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final Vector2[] pVertices, final BodyType pBodyType, final FixtureDef pFixtureDef) { + return PhysicsFactory.createPolygonBody(pPhysicsWorld, pIShape, pVertices, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); + } + + /** + * @param pPhysicsWorld + * @param pIShape + * @param pVertices are to be defined relative to the center of the pIShape. + * @param pBodyType + * @param pFixtureDef + * @return + */ + public static Body createPolygonBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final Vector2[] pVertices, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { + final BodyDef boxBodyDef = new BodyDef(); + boxBodyDef.type = pBodyType; + + final float[] sceneCenterCoordinates = pIShape.getSceneCenterCoordinates(); + boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; + boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; + + final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); + + final PolygonShape boxPoly = new PolygonShape(); + + boxPoly.set(pVertices); + pFixtureDef.shape = boxPoly; + + boxBody.createFixture(pFixtureDef); + + boxPoly.dispose(); + + return boxBody; + } + + + /** + * @param pPhysicsWorld + * @param pIShape + * @param pTriangleVertices are to be defined relative to the center of the pIShape and have the {@link PhysicsConstants#PIXEL_TO_METER_RATIO_DEFAULT} applied. + * @param pBodyType + * @param pFixtureDef + * @return + */ + public static Body createTrianglulatedBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final List pTriangleVertices, final BodyType pBodyType, final FixtureDef pFixtureDef) { + return PhysicsFactory.createTrianglulatedBody(pPhysicsWorld, pIShape, pTriangleVertices, pBodyType, pFixtureDef, PIXEL_TO_METER_RATIO_DEFAULT); + } + + /** + * @param pPhysicsWorld + * @param pIShape + * @param pTriangleVertices are to be defined relative to the center of the pIShape and have the {@link PhysicsConstants#PIXEL_TO_METER_RATIO_DEFAULT} applied. + * The vertices will be triangulated and for each triangle a {@link Fixture} will be created. + * @param pBodyType + * @param pFixtureDef + * @return + */ + public static Body createTrianglulatedBody(final PhysicsWorld pPhysicsWorld, final IShape pIShape, final List pTriangleVertices, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { + final Vector2[] TMP_TRIANGLE = new Vector2[3]; + + final BodyDef boxBodyDef = new BodyDef(); + boxBodyDef.type = pBodyType; + + final float[] sceneCenterCoordinates = pIShape.getSceneCenterCoordinates(); + boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; + boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; + + final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); + + final int vertexCount = pTriangleVertices.size(); + for(int i = 0; i < vertexCount; /* */) { + final PolygonShape boxPoly = new PolygonShape(); + + TMP_TRIANGLE[2] = pTriangleVertices.get(i++); + TMP_TRIANGLE[1] = pTriangleVertices.get(i++); + TMP_TRIANGLE[0] = pTriangleVertices.get(i++); + + boxPoly.set(TMP_TRIANGLE); + pFixtureDef.shape = boxPoly; + + boxBody.createFixture(pFixtureDef); + + boxPoly.dispose(); + } + + return boxBody; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsWorld.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsWorld.java new file mode 100644 index 0000000..b92a62b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/PhysicsWorld.java @@ -0,0 +1,228 @@ +package org.anddev.andengine.extension.physics.box2d; + +import java.util.List; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.engine.handler.runnable.RunnableHandler; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.Contact; +import com.badlogic.gdx.physics.box2d.ContactFilter; +import com.badlogic.gdx.physics.box2d.ContactListener; +import com.badlogic.gdx.physics.box2d.DestructionListener; +import com.badlogic.gdx.physics.box2d.Joint; +import com.badlogic.gdx.physics.box2d.JointDef; +import com.badlogic.gdx.physics.box2d.QueryCallback; +import com.badlogic.gdx.physics.box2d.World; + +/** + * @author Nicolas Gramlich + * @since 15:18:19 - 15.07.2010 + */ +public class PhysicsWorld implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + static { + System.loadLibrary( "andenginephysicsbox2dextension" ); + } + + public static final int VELOCITY_ITERATIONS_DEFAULT = 8; + public static final int POSITION_ITERATIONS_DEFAULT = 8; + + // =========================================================== + // Fields + // =========================================================== + + protected final PhysicsConnectorManager mPhysicsConnectorManager = new PhysicsConnectorManager(); + protected final RunnableHandler mRunnableHandler = new RunnableHandler(); + protected final World mWorld; + + protected int mVelocityIterations = VELOCITY_ITERATIONS_DEFAULT; + protected int mPositionIterations = POSITION_ITERATIONS_DEFAULT; + + // =========================================================== + // Constructors + // =========================================================== + + public PhysicsWorld(final Vector2 pGravity, final boolean pAllowSleep) { + this(pGravity, pAllowSleep, VELOCITY_ITERATIONS_DEFAULT, POSITION_ITERATIONS_DEFAULT); + } + + public PhysicsWorld(final Vector2 pGravity, final boolean pAllowSleep, final int pVelocityIterations, final int pPositionIterations) { + this.mWorld = new World(pGravity, pAllowSleep); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // public World getWorld() { + // return this.mWorld; + // } + + public int getPositionIterations() { + return this.mPositionIterations; + } + + public void setPositionIterations(final int pPositionIterations) { + this.mPositionIterations = pPositionIterations; + } + + public int getVelocityIterations() { + return this.mVelocityIterations; + } + + public void setVelocityIterations(final int pVelocityIterations) { + this.mVelocityIterations = pVelocityIterations; + } + + public PhysicsConnectorManager getPhysicsConnectorManager() { + return this.mPhysicsConnectorManager; + } + + public void clearPhysicsConnectors() { + this.mPhysicsConnectorManager.clear(); + } + + public void registerPhysicsConnector(final PhysicsConnector pPhysicsConnector) { + this.mPhysicsConnectorManager.add(pPhysicsConnector); + } + + public void unregisterPhysicsConnector(final PhysicsConnector pPhysicsConnector) { + this.mPhysicsConnectorManager.remove(pPhysicsConnector); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mRunnableHandler.onUpdate(pSecondsElapsed); + this.mWorld.step(pSecondsElapsed, this.mVelocityIterations, this.mPositionIterations); + this.mPhysicsConnectorManager.onUpdate(pSecondsElapsed); + } + + @Override + public void reset() { + // TODO Reset all native physics objects !?!??! + this.mPhysicsConnectorManager.reset(); + this.mRunnableHandler.reset(); + } + + // =========================================================== + // Methods + // =========================================================== + + public void postRunnable(final Runnable pRunnable) { + this.mRunnableHandler.postRunnable(pRunnable); + } + + public void clearForces() { + this.mWorld.clearForces(); + } + + public Body createBody(final BodyDef pDef) { + return this.mWorld.createBody(pDef); + } + + public Joint createJoint(final JointDef pDef) { + return this.mWorld.createJoint(pDef); + } + + public void destroyBody(final Body pBody) { + this.mWorld.destroyBody(pBody); + } + + public void destroyJoint(final Joint pJoint) { + this.mWorld.destroyJoint(pJoint); + } + + public void dispose() { + this.mWorld.dispose(); + } + + public boolean getAutoClearForces() { + return this.mWorld.getAutoClearForces(); + } + + public Iterable getBodies() { + return this.mWorld.getBodies(); + } + + public int getBodyCount() { + return this.mWorld.getBodyCount(); + } + + public int getContactCount() { + return this.mWorld.getContactCount(); + } + + public List getContactList() { + return this.mWorld.getContactList(); + } + + public Vector2 getGravity() { + return this.mWorld.getGravity(); + } + + public Iterable getJoints() { + return this.mWorld.getJoints(); + } + + public int getJointCount() { + return this.mWorld.getJointCount(); + } + + public int getProxyCount() { + return this.mWorld.getProxyCount(); + } + + public boolean isLocked() { + return this.mWorld.isLocked(); + } + + public void QueryAABB(final QueryCallback pCallback, final float pLowerX, final float pLowerY, final float pUpperX, final float pUpperY) { + this.mWorld.QueryAABB(pCallback, pLowerX, pLowerY, pUpperX, pUpperY); + } + + public void setAutoClearForces(final boolean pFlag) { + this.mWorld.setAutoClearForces(pFlag); + } + + public void setContactFilter(final ContactFilter pFilter) { + this.mWorld.setContactFilter(pFilter); + } + + public void setContactListener(final ContactListener pListener) { + this.mWorld.setContactListener(pListener); + } + + public void setContinuousPhysics(final boolean pFlag) { + this.mWorld.setContinuousPhysics(pFlag); + } + + public void setDestructionListener(final DestructionListener pListener) { + this.mWorld.setDestructionListener(pListener); + } + + public void setGravity(final Vector2 pGravity) { + this.mWorld.setGravity(pGravity); + } + + public void setWarmStarting(final boolean pFlag) { + this.mWorld.setWarmStarting(pFlag); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/Vector2Pool.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/Vector2Pool.java new file mode 100644 index 0000000..d861cb5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/Vector2Pool.java @@ -0,0 +1,62 @@ +package org.anddev.andengine.extension.physics.box2d.util; + +import org.anddev.andengine.util.pool.GenericPool; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 16:22:23 - 14.09.2010 + */ +public class Vector2Pool { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static final GenericPool POOL = new GenericPool() { + @Override + protected Vector2 onAllocatePoolItem() { + return new Vector2(); + } + }; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public static Vector2 obtain() { + return POOL.obtainPoolItem(); + } + + public static Vector2 obtain(final Vector2 pCopyFrom) { + return POOL.obtainPoolItem().set(pCopyFrom); + } + + public static Vector2 obtain(final float pX, final float pY) { + return POOL.obtainPoolItem().set(pX, pY); + } + + public static void recycle(final Vector2 pVector2) { + POOL.recyclePoolItem(pVector2); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/constants/PhysicsConstants.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/constants/PhysicsConstants.java new file mode 100644 index 0000000..92530fd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/constants/PhysicsConstants.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.extension.physics.box2d.util.constants; + +/** + * @author Nicolas Gramlich + * @since 13:01:50 - 28.07.2010 + */ +public interface PhysicsConstants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final float PIXEL_TO_METER_RATIO_DEFAULT = 32.0f; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/BaseHullAlgorithm.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/BaseHullAlgorithm.java new file mode 100644 index 0000000..18beb9b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/BaseHullAlgorithm.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 14:05:51 - 14.09.2010 + */ +public abstract class BaseHullAlgorithm implements IHullAlgorithm { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected Vector2[] mVertices; + protected int mVertexCount; + protected int mHullVertexCount; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + protected int indexOfLowestVertex() { + final Vector2[] vertices = this.mVertices; + final int vertexCount = this.mVertexCount; + + int min = 0; + for(int i = 1; i < vertexCount; i++) { + final float dY = vertices[i].y - vertices[min].y; + final float dX = vertices[i].x - vertices[min].x; + if(dY < 0 || dY == 0 && dX < 0) { + min = i; + } + } + return min; + } + + protected void swap(final int pIndexA, final int pIndexB) { + final Vector2[] vertices = this.mVertices; + + final Vector2 tmp = vertices[pIndexA]; + vertices[pIndexA] = vertices[pIndexB]; + vertices[pIndexB] = tmp; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/GrahamScan.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/GrahamScan.java new file mode 100644 index 0000000..f512c36 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/GrahamScan.java @@ -0,0 +1,113 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 14:00:50 - 14.09.2010 + * @see http://www.iti.fh-flensburg.de/lang/algorithmen/geo/ + */ +public class GrahamScan extends BaseHullAlgorithm { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int computeHull(final Vector2[] pVertices) { + this.mVertices = pVertices; + this.mVertexCount = pVertices.length; + if(this.mVertexCount < 3) { + return this.mVertexCount; + } + this.mHullVertexCount = 0; + this.grahamScan(); + return this.mHullVertexCount; + } + + // =========================================================== + // Methods + // =========================================================== + + private void grahamScan() { + this.swap(0, this.indexOfLowestVertex()); + final Vector2 pl = new Vector2(this.mVertices[0]); + this.makeAllVerticesRelativeTo(pl); + this.sort(); + this.makeAllVerticesRelativeTo(new Vector2(pl).mul(-1)); + int i = 3; + int k = 3; + while(k < this.mVertexCount) { + this.swap(i, k); + while(!this.isConvex(i - 1)) { + this.swap(i - 1, i--); + } + k++; + i++; + } + this.mHullVertexCount = i; + } + + private void makeAllVerticesRelativeTo(final Vector2 pVector) { + final Vector2[] vertices = this.mVertices; + final int vertexCount = this.mVertexCount; + + final Vector2 vertexCopy = new Vector2(pVector); // necessary, as pVector might be in mVertices[] + for(int i = 0; i < vertexCount; i++) { + vertices[i].sub(vertexCopy); + } + } + + private boolean isConvex(final int pIndex) { + final Vector2[] vertices = this.mVertices; + return Vector2Util.isConvex(vertices[pIndex], vertices[pIndex - 1], vertices[pIndex + 1]); + } + + private void sort() { + this.quicksort(1, this.mVertexCount - 1); // without Vertex 0 + } + + private void quicksort(final int pFromIndex, final int pToIndex) { + final Vector2[] vertices = this.mVertices; + int i = pFromIndex; + int j = pToIndex; + + final Vector2 q = vertices[(pFromIndex + pToIndex) / 2]; + while(i <= j) { + while(Vector2Util.isLess(vertices[i], q)) { + i++; + } + while(Vector2Util.isLess(q, vertices[j])) { + j--; + } + if(i <= j) { + this.swap(i++, j--); + } + } + if(pFromIndex < j) { + this.quicksort(pFromIndex, j); + } + if(i < pToIndex) { + this.quicksort(i, pToIndex); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/IHullAlgorithm.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/IHullAlgorithm.java new file mode 100644 index 0000000..ffd5ad1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/IHullAlgorithm.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 13:46:22 - 14.09.2010 + */ +public interface IHullAlgorithm { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public int computeHull(final Vector2[] pVertices); +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/JarvisMarch.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/JarvisMarch.java new file mode 100644 index 0000000..284fd25 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/JarvisMarch.java @@ -0,0 +1,78 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 14:01:18 - 14.09.2010 + * @see http://www.iti.fh-flensburg.de/lang/algorithmen/geo/ + */ +public class JarvisMarch extends BaseHullAlgorithm { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int computeHull(final Vector2[] pVectors) { + this.mVertices = pVectors; + this.mVertexCount = pVectors.length; + this.mHullVertexCount = 0; + this.jarvisMarch(); + return this.mHullVertexCount; + } + + // =========================================================== + // Methods + // =========================================================== + + private void jarvisMarch() { + final Vector2[] vertices = this.mVertices; + + int index = this.indexOfLowestVertex(); + do { + this.swap(this.mHullVertexCount, index); + index = this.indexOfRightmostVertexOf(vertices[this.mHullVertexCount]); + this.mHullVertexCount++; + } while(index > 0); + } + + private int indexOfRightmostVertexOf(final Vector2 pVector) { + final Vector2[] vertices = this.mVertices; + final int vertexCount = this.mVertexCount; + + int i = 0; + for(int j = 1; j < vertexCount; j++) { + + final Vector2 vector2A = Vector2Pool.obtain().set(vertices[j]); + final Vector2 vector2B = Vector2Pool.obtain().set(vertices[i]); + if(Vector2Util.isLess(vector2A.sub(pVector), vector2B.sub(pVector))) { + i = j; + } + Vector2Pool.recycle(vector2A); + Vector2Pool.recycle(vector2B); + } + return i; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/QuickHull.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/QuickHull.java new file mode 100644 index 0000000..d95d6b6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/QuickHull.java @@ -0,0 +1,117 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 14:01:34 - 14.09.2010 + * @see http://www.iti.fh-flensburg.de/lang/algorithmen/geo/ + */ +public class QuickHull extends BaseHullAlgorithm { + // =========================================================== + // Constants + // =========================================================== + + private final static float EPSILON = 1e-3f; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int computeHull(final Vector2[] pVectors) { + this.mVertices = pVectors; + this.mVertexCount = this.mVertices.length; + this.mHullVertexCount = 0; + this.quickHull(); + return this.mHullVertexCount; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private void quickHull() { + this.swap(0, this.indexOfLowestVertex()); + this.mHullVertexCount++; + final Vector2Line line = new Vector2Line(this.mVertices[0], new Vector2(this.mVertices[0]).add(-EPSILON, 0)); + this.computeHullVertices(line, 1, this.mVertexCount - 1); + } + + private void computeHullVertices(final Vector2Line pLine, final int pIndexFrom, final int pIndexTo) { + if(pIndexFrom > pIndexTo) { + return; + } + final int k = this.indexOfFurthestVertex(pLine, pIndexFrom, pIndexTo); + + final Vector2Line lineA = new Vector2Line(pLine.mVertexA, this.mVertices[k]); + final Vector2Line lineB = new Vector2Line(this.mVertices[k], pLine.mVertexB); + this.swap(k, pIndexTo); + + final int i = this.partition(lineA, pIndexFrom, pIndexTo - 1); + /* All vertices from pIndexFrom to i-1 are right of lineA. */ + /* All vertices from i to pIndexTo-1 are left of lineA. */ + this.computeHullVertices(lineA, pIndexFrom, i - 1); + + /* All vertices before pIndexTo are now on the hull. */ + this.swap(pIndexTo, i); + this.swap(i, this.mHullVertexCount); + this.mHullVertexCount++; + + final int j = this.partition(lineB, i + 1, pIndexTo); + /* All vertices from i+1 to j-1 are right of lineB. */ + /* All vertices from j to pToIndex are on the inside. */ + this.computeHullVertices(lineB, i + 1, j - 1); + } + + private int indexOfFurthestVertex(final Vector2Line pLine, final int pFromIndex, final int pToIndex) { + final Vector2[] vertices = this.mVertices; + + int f = pFromIndex; + float mx = 0; + for(int i = pFromIndex; i <= pToIndex; i++) { + final float d = -Vector2Util.area2(vertices[i], pLine); + if(d > mx || d == mx && vertices[i].x > vertices[f].y) { + mx = d; + f = i; + } + } + return f; + } + + private int partition(final Vector2Line pLine, final int pFromIndex, final int pToIndex) { + final Vector2[] vertices = this.mVertices; + + int i = pFromIndex; + int j = pToIndex; + while(i <= j) { + while(i <= j && Vector2Util.isRightOf(vertices[i], pLine)) { + i++; + } + while(i <= j && !Vector2Util.isRightOf(vertices[j], pLine)) { + j--; + } + if(i <= j) { + this.swap(i++, j--); + } + } + return i; + } + +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/Vector2Line.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/Vector2Line.java new file mode 100644 index 0000000..58d2eed --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/Vector2Line.java @@ -0,0 +1,45 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 13:43:54 - 14.09.2010 + */ +class Vector2Line { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + Vector2 mVertexA; + Vector2 mVertexB; + + // =========================================================== + // Constructors + // =========================================================== + + public Vector2Line(final Vector2 pVertexA, final Vector2 pVertexB) { + this.mVertexA = pVertexA; + this.mVertexB = pVertexB; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/Vector2Util.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/Vector2Util.java new file mode 100644 index 0000000..44a1149 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/hull/Vector2Util.java @@ -0,0 +1,71 @@ +package org.anddev.andengine.extension.physics.box2d.util.hull; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 15:05:33 - 14.09.2010 + */ +class Vector2Util { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean isLess(final Vector2 pVertexA, final Vector2 pVertexB) { + final float f = pVertexA.cross(pVertexB); + return f > 0 || f == 0 && Vector2Util.isLonger(pVertexA, pVertexB); + } + + public static boolean isLonger(final Vector2 pVertexA, final Vector2 pVertexB) { + return pVertexA.lenManhattan() > pVertexB.lenManhattan(); + } + + public static float getManhattanDistance(final Vector2 pVertexA, final Vector2 pVertexB) { + return Math.abs(pVertexA.x - pVertexB.x) + Math.abs(pVertexA.y - pVertexB.y); + } + + public static boolean isConvex(final Vector2 pVertexTest, final Vector2 pVertexA, final Vector2 pVertexB) { + final float f = Vector2Util.area2(pVertexTest, pVertexA, pVertexB); + return f < 0 || f == 0 && !Vector2Util.isBetween(pVertexTest, pVertexA, pVertexB); + } + + public static float area2(final Vector2 pVertexTest, final Vector2 pVertexA, final Vector2 pVertexB) { + return (pVertexA.x - pVertexTest.x) * (pVertexB.y - pVertexTest.y) - (pVertexB.x - pVertexTest.x) * (pVertexA.y - pVertexTest.y); + } + + public static float area2(final Vector2 pVertexTest, final Vector2Line pLine) { + return Vector2Util.area2(pVertexTest, pLine.mVertexA, pLine.mVertexB); + } + + public static boolean isBetween(final Vector2 pVertexTest, final Vector2 pVertexA, final Vector2 pVertexB) { + return Vector2Util.getManhattanDistance(pVertexA, pVertexB) >= Vector2Util.getManhattanDistance(pVertexTest, pVertexA) + Vector2Util.getManhattanDistance(pVertexTest, pVertexB); + } + + public static boolean isRightOf(final Vector2 pVertexTest, final Vector2Line pLine) { + return Vector2Util.area2(pVertexTest, pLine) < 0; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/triangulation/EarClippingTriangulator.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/triangulation/EarClippingTriangulator.java new file mode 100644 index 0000000..9c9982b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/triangulation/EarClippingTriangulator.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright 2010 Mario Zechner (contact@badlogicgames.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package org.anddev.andengine.extension.physics.box2d.util.triangulation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.badlogic.gdx.math.Vector2; + +/** + * A simple implementation of the ear cutting algorithm to triangulate simple + * polygons without holes. For more information: + * @see http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/algorithm2.html + * @see http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf + * + * @author badlogicgames@gmail.com + * @author Nicolas Gramlich (Improved performance. Collinear edges are now supported.) + */ +public final class EarClippingTriangulator implements ITriangulationAlgoritm { + // =========================================================== + // Constants + // =========================================================== + + private static final int CONCAVE = 1; + private static final int CONVEX = -1; + + // =========================================================== + // Fields + // =========================================================== + + private int mConcaveVertexCount; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public List computeTriangles(final List pVertices) { + // TODO Check if LinkedList performs better + final ArrayList triangles = new ArrayList(); + final ArrayList vertices = new ArrayList(pVertices.size()); + vertices.addAll(pVertices); + + if(vertices.size() == 3) { + triangles.addAll(vertices); + return triangles; + } + + while(vertices.size() >= 3) { + // TODO Usually(Always?) only the Types of the vertices next to the ear change! --> Improve + final int vertexTypes[] = this.classifyVertices(vertices); + + final int vertexCount = vertices.size(); + for(int index = 0; index < vertexCount; index++) { + if(this.isEarTip(vertices, index, vertexTypes)) { + this.cutEarTip(vertices, index, triangles); + break; + } + } + } + + return triangles; + } + + // =========================================================== + // Methods + // =========================================================== + + private static boolean areVerticesClockwise(final ArrayList pVertices) { + final int vertexCount = pVertices.size(); + + float area = 0; + for(int i = 0; i < vertexCount; i++) { + final Vector2 p1 = pVertices.get(i); + final Vector2 p2 = pVertices.get(EarClippingTriangulator.computeNextIndex(pVertices, i)); + area += p1.x * p2.y - p2.x * p1.y; + } + + if(area < 0) { + return true; + } else { + return false; + } + } + + /** + * @param pVertices + * @return An array of length pVertices.size() filled with either {@link EarClippingTriangulator#CONCAVE} or + * {@link EarClippingTriangulator#CONVEX}. + */ + private int[] classifyVertices(final ArrayList pVertices) { + final int vertexCount = pVertices.size(); + + final int[] vertexTypes = new int[vertexCount]; + this.mConcaveVertexCount = 0; + + /* Ensure vertices are in clockwise order. */ + if(!EarClippingTriangulator.areVerticesClockwise(pVertices)) { + Collections.reverse(pVertices); + } + + for(int index = 0; index < vertexCount; index++) { + final int previousIndex = EarClippingTriangulator.computePreviousIndex(pVertices, index); + final int nextIndex = EarClippingTriangulator.computeNextIndex(pVertices, index); + + final Vector2 previousVertex = pVertices.get(previousIndex); + final Vector2 currentVertex = pVertices.get(index); + final Vector2 nextVertex = pVertices.get(nextIndex); + + if(EarClippingTriangulator.isTriangleConvex(previousVertex.x, previousVertex.y, currentVertex.x, currentVertex.y, nextVertex.x, nextVertex.y)) { + vertexTypes[index] = CONVEX; + } else { + vertexTypes[index] = CONCAVE; + this.mConcaveVertexCount++; + } + } + + return vertexTypes; + } + + private static boolean isTriangleConvex(final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3) { + if(EarClippingTriangulator.computeSpannedAreaSign(pX1, pY1, pX2, pY2, pX3, pY3) < 0) { + return false; + } else { + return true; + } + } + + private static int computeSpannedAreaSign(final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3) { + float area = 0; + + area += pX1 * (pY3 - pY2); + area += pX2 * (pY1 - pY3); + area += pX3 * (pY2 - pY1); + + return (int)Math.signum(area); + } + + /** + * @return true when the Triangles contains one or more vertices, false otherwise. + */ + private static boolean isAnyVertexInTriangle(final ArrayList pVertices, final int[] pVertexTypes, final float pX1, final float pY1, final float pX2, final float pY2, final float pX3, final float pY3) { + int i = 0; + + final int vertexCount = pVertices.size(); + while(i < vertexCount - 1) { + if((pVertexTypes[i] == CONCAVE)) { + final Vector2 currentVertex = pVertices.get(i); + + final float currentVertexX = currentVertex.x; + final float currentVertexY = currentVertex.y; + + /* TODO The following condition fails for perpendicular, axis aligned triangles! + * Removing it doesn't seem to cause problems. + * Maybe it was an optimization? + * Maybe it tried to handle collinear pieces ? */ +// if(((currentVertexX != pX1) && (currentVertexY != pY1)) || ((currentVertexX != pX2) && (currentVertexY != pY2)) || ((currentVertexX != pX3) && (currentVertexY != pY3))) { + final int areaSign1 = EarClippingTriangulator.computeSpannedAreaSign(pX1, pY1, pX2, pY2, currentVertexX, currentVertexY); + final int areaSign2 = EarClippingTriangulator.computeSpannedAreaSign(pX2, pY2, pX3, pY3, currentVertexX, currentVertexY); + final int areaSign3 = EarClippingTriangulator.computeSpannedAreaSign(pX3, pY3, pX1, pY1, currentVertexX, currentVertexY); + + if(areaSign1 > 0 && areaSign2 > 0 && areaSign3 > 0) { + return true; + } else if(areaSign1 <= 0 && areaSign2 <= 0 && areaSign3 <= 0) { + return true; + } +// } + } + i++; + } + return false; + } + + private boolean isEarTip(final ArrayList pVertices, final int pEarTipIndex, final int[] pVertexTypes) { + if(this.mConcaveVertexCount != 0) { + final Vector2 previousVertex = pVertices.get(EarClippingTriangulator.computePreviousIndex(pVertices, pEarTipIndex)); + final Vector2 currentVertex = pVertices.get(pEarTipIndex); + final Vector2 nextVertex = pVertices.get(EarClippingTriangulator.computeNextIndex(pVertices, pEarTipIndex)); + + if(EarClippingTriangulator.isAnyVertexInTriangle(pVertices, pVertexTypes, previousVertex.x, previousVertex.y, currentVertex.x, currentVertex.y, nextVertex.x, nextVertex.y)) { + return false; + } else { + return true; + } + } else { + return true; + } + } + + private void cutEarTip(final ArrayList pVertices, final int pEarTipIndex, final ArrayList pTriangles) { + final int previousIndex = EarClippingTriangulator.computePreviousIndex(pVertices, pEarTipIndex); + final int nextIndex = EarClippingTriangulator.computeNextIndex(pVertices, pEarTipIndex); + + if(!EarClippingTriangulator.isCollinear(pVertices, previousIndex, pEarTipIndex, nextIndex)) { + pTriangles.add(new Vector2(pVertices.get(previousIndex))); + pTriangles.add(new Vector2(pVertices.get(pEarTipIndex))); + pTriangles.add(new Vector2(pVertices.get(nextIndex))); + } + + pVertices.remove(pEarTipIndex); + if(pVertices.size() >= 3) { + EarClippingTriangulator.removeCollinearNeighborEarsAfterRemovingEarTip(pVertices, pEarTipIndex); + } + } + + private static void removeCollinearNeighborEarsAfterRemovingEarTip(final ArrayList pVertices, final int pEarTipCutIndex) { + final int collinearityCheckNextIndex = pEarTipCutIndex % pVertices.size(); + int collinearCheckPreviousIndex = EarClippingTriangulator.computePreviousIndex(pVertices, collinearityCheckNextIndex); + + if(EarClippingTriangulator.isCollinear(pVertices, collinearityCheckNextIndex)) { + pVertices.remove(collinearityCheckNextIndex); + + if(pVertices.size() > 3) { + /* Update */ + collinearCheckPreviousIndex = EarClippingTriangulator.computePreviousIndex(pVertices, collinearityCheckNextIndex); + if(EarClippingTriangulator.isCollinear(pVertices, collinearCheckPreviousIndex)){ + pVertices.remove(collinearCheckPreviousIndex); + } + } + } else if(EarClippingTriangulator.isCollinear(pVertices, collinearCheckPreviousIndex)){ + pVertices.remove(collinearCheckPreviousIndex); + } + } + + private static boolean isCollinear(final ArrayList pVertices, final int pIndex) { + final int previousIndex = EarClippingTriangulator.computePreviousIndex(pVertices, pIndex); + final int nextIndex = EarClippingTriangulator.computeNextIndex(pVertices, pIndex); + + return EarClippingTriangulator.isCollinear(pVertices, previousIndex, pIndex, nextIndex); + } + + private static boolean isCollinear(final ArrayList pVertices, final int pPreviousIndex, final int pIndex, final int pNextIndex) { + final Vector2 previousVertex = pVertices.get(pPreviousIndex); + final Vector2 vertex = pVertices.get(pIndex); + final Vector2 nextVertex = pVertices.get(pNextIndex); + + return EarClippingTriangulator.computeSpannedAreaSign(previousVertex.x, previousVertex.y, vertex.x, vertex.y, nextVertex.x, nextVertex.y) == 0; + } + + private static int computePreviousIndex(final List pVertices, final int pIndex) { + return pIndex == 0 ? pVertices.size() - 1 : pIndex - 1; + } + + private static int computeNextIndex(final List pVertices, final int pIndex) { + return pIndex == pVertices.size() - 1 ? 0 : pIndex + 1; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/triangulation/ITriangulationAlgoritm.java b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/triangulation/ITriangulationAlgoritm.java new file mode 100644 index 0000000..7d7fb82 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/extension/physics/box2d/util/triangulation/ITriangulationAlgoritm.java @@ -0,0 +1,24 @@ +package org.anddev.andengine.extension.physics.box2d.util.triangulation; + +import java.util.List; + +import com.badlogic.gdx.math.Vector2; + +/** + * @author Nicolas Gramlich + * @since 20:16:04 - 14.09.2010 + */ +public interface ITriangulationAlgoritm { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * @return a {@link List} of {@link Vector2} objects where every three {@link Vector2} objects form a triangle. + */ + public List computeTriangles(final List pVertices); +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/TouchEvent.java b/AndEngine/src/org/anddev/andengine/input/touch/TouchEvent.java new file mode 100644 index 0000000..39e9995 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/TouchEvent.java @@ -0,0 +1,144 @@ +package org.anddev.andengine.input.touch; + +import org.anddev.andengine.util.pool.GenericPool; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 10:17:42 - 13.07.2010 + */ +public class TouchEvent { + // =========================================================== + // Constants + // =========================================================== + + public static final int ACTION_CANCEL = MotionEvent.ACTION_CANCEL; + public static final int ACTION_DOWN = MotionEvent.ACTION_DOWN; + public static final int ACTION_MOVE = MotionEvent.ACTION_MOVE; + public static final int ACTION_OUTSIDE = MotionEvent.ACTION_OUTSIDE; + public static final int ACTION_UP = MotionEvent.ACTION_UP; + + private static final TouchEventPool TOUCHEVENT_POOL = new TouchEventPool(); + + // =========================================================== + // Fields + // =========================================================== + + protected int mPointerID; + + protected float mX; + protected float mY; + + protected int mAction; + + protected MotionEvent mMotionEvent; + + // =========================================================== + // Constructors + // =========================================================== + + public static TouchEvent obtain(final float pX, final float pY, final int pAction, final int pPointerID, final MotionEvent pMotionEvent) { + final TouchEvent touchEvent = TOUCHEVENT_POOL.obtainPoolItem(); + touchEvent.set(pX, pY, pAction, pPointerID, pMotionEvent); + return touchEvent; + } + + private void set(final float pX, final float pY, final int pAction, final int pPointerID, final MotionEvent pMotionEvent) { + this.mX = pX; + this.mY = pY; + this.mAction = pAction; + this.mPointerID = pPointerID; + this.mMotionEvent = pMotionEvent; + } + + public void recycle() { + TOUCHEVENT_POOL.recyclePoolItem(this); + } + + public static void recycle(final TouchEvent pTouchEvent) { + TOUCHEVENT_POOL.recyclePoolItem(pTouchEvent); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getX() { + return this.mX; + } + + public float getY() { + return this.mY; + } + + public void set(final float pX, final float pY) { + this.mX = pX; + this.mY = pY; + } + + public void offset(final float pDeltaX, final float pDeltaY) { + this.mX += pDeltaX; + this.mY += pDeltaY; + } + + public int getPointerID() { + return this.mPointerID; + } + + public int getAction() { + return this.mAction; + } + + public boolean isActionDown() { + return this.mAction == TouchEvent.ACTION_DOWN; + } + + public boolean isActionUp() { + return this.mAction == TouchEvent.ACTION_UP; + } + + public boolean isActionMove() { + return this.mAction == TouchEvent.ACTION_MOVE; + } + + public boolean isActionCancel() { + return this.mAction == TouchEvent.ACTION_CANCEL; + } + + public boolean isActionOutside() { + return this.mAction == TouchEvent.ACTION_OUTSIDE; + } + + /** + * Provides the raw {@link MotionEvent} that originally caused this {@link TouchEvent}. + * The coordinates of this {@link MotionEvent} are in surface-coordinates! + * @return + */ + public MotionEvent getMotionEvent() { + return this.mMotionEvent; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private static final class TouchEventPool extends GenericPool { + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected TouchEvent onAllocatePoolItem() { + return new TouchEvent(); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/controller/BaseTouchController.java b/AndEngine/src/org/anddev/andengine/input/touch/controller/BaseTouchController.java new file mode 100644 index 0000000..2269c07 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/controller/BaseTouchController.java @@ -0,0 +1,134 @@ +package org.anddev.andengine.input.touch.controller; + +import org.anddev.andengine.engine.options.TouchOptions; +import org.anddev.andengine.input.touch.TouchEvent; +import org.anddev.andengine.util.pool.RunnablePoolItem; +import org.anddev.andengine.util.pool.RunnablePoolUpdateHandler; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 21:06:40 - 13.07.2010 + */ +public abstract class BaseTouchController implements ITouchController { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private ITouchEventCallback mTouchEventCallback; + + private boolean mRunOnUpdateThread; + + private final RunnablePoolUpdateHandler mTouchEventRunnablePoolUpdateHandler = new RunnablePoolUpdateHandler() { + @Override + protected TouchEventRunnablePoolItem onAllocatePoolItem() { + return new TouchEventRunnablePoolItem(); + } + }; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTouchController() { + + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public void setTouchEventCallback(final ITouchEventCallback pTouchEventCallback) { + this.mTouchEventCallback = pTouchEventCallback; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void reset() { + if(this.mRunOnUpdateThread) { + this.mTouchEventRunnablePoolUpdateHandler.reset(); + } + } + + @Override + public void onUpdate(final float pSecondsElapsed) { + if(this.mRunOnUpdateThread) { + this.mTouchEventRunnablePoolUpdateHandler.onUpdate(pSecondsElapsed); + } + } + + protected boolean fireTouchEvent(final float pX, final float pY, final int pAction, final int pPointerID, final MotionEvent pMotionEvent) { + final boolean handled; + + if(this.mRunOnUpdateThread) { + final TouchEvent touchEvent = TouchEvent.obtain(pX, pY, pAction, pPointerID, MotionEvent.obtain(pMotionEvent)); + + final TouchEventRunnablePoolItem touchEventRunnablePoolItem = this.mTouchEventRunnablePoolUpdateHandler.obtainPoolItem(); + touchEventRunnablePoolItem.set(touchEvent); + this.mTouchEventRunnablePoolUpdateHandler.postPoolItem(touchEventRunnablePoolItem); + + handled = true; + } else { + final TouchEvent touchEvent = TouchEvent.obtain(pX, pY, pAction, pPointerID, pMotionEvent); + handled = this.mTouchEventCallback.onTouchEvent(touchEvent); + touchEvent.recycle(); + } + + return handled; + } + + // =========================================================== + // Methods + // =========================================================== + + @Override + public void applyTouchOptions(final TouchOptions pTouchOptions) { + this.mRunOnUpdateThread = pTouchOptions.isRunOnUpdateThread(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + class TouchEventRunnablePoolItem extends RunnablePoolItem { + // =========================================================== + // Fields + // =========================================================== + + private TouchEvent mTouchEvent; + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void set(final TouchEvent pTouchEvent) { + this.mTouchEvent = pTouchEvent; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void run() { + BaseTouchController.this.mTouchEventCallback.onTouchEvent(this.mTouchEvent); + } + + @Override + protected void onRecycle() { + super.onRecycle(); + final TouchEvent touchEvent = this.mTouchEvent; + touchEvent.getMotionEvent().recycle(); + touchEvent.recycle(); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/controller/ITouchController.java b/AndEngine/src/org/anddev/andengine/input/touch/controller/ITouchController.java new file mode 100644 index 0000000..a4ece4c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/controller/ITouchController.java @@ -0,0 +1,35 @@ +package org.anddev.andengine.input.touch.controller; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.engine.options.TouchOptions; +import org.anddev.andengine.input.touch.TouchEvent; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 20:23:45 - 13.07.2010 + */ +public interface ITouchController extends IUpdateHandler { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void setTouchEventCallback(final ITouchEventCallback pTouchEventCallback); + + public void applyTouchOptions(final TouchOptions pTouchOptions); + + public boolean onHandleMotionEvent(final MotionEvent pMotionEvent); + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + static interface ITouchEventCallback { + public boolean onTouchEvent(final TouchEvent pTouchEvent); + } +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/controller/SingleTouchControler.java b/AndEngine/src/org/anddev/andengine/input/touch/controller/SingleTouchControler.java new file mode 100644 index 0000000..e5e2930 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/controller/SingleTouchControler.java @@ -0,0 +1,46 @@ +package org.anddev.andengine.input.touch.controller; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 20:23:33 - 13.07.2010 + */ +public class SingleTouchControler extends BaseTouchController { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SingleTouchControler() { + + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onHandleMotionEvent(final MotionEvent pMotionEvent) { + return this.fireTouchEvent(pMotionEvent.getX(), pMotionEvent.getY(), pMotionEvent.getAction(), 0, pMotionEvent); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/detector/BaseDetector.java b/AndEngine/src/org/anddev/andengine/input/touch/detector/BaseDetector.java new file mode 100644 index 0000000..e9cdb43 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/detector/BaseDetector.java @@ -0,0 +1,64 @@ +package org.anddev.andengine.input.touch.detector; + +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener; +import org.anddev.andengine.input.touch.TouchEvent; + +/** + * @author Nicolas Gramlich + * @since 15:59:00 - 05.11.2010 + */ +public abstract class BaseDetector implements IOnSceneTouchListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private boolean mEnabled = true; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isEnabled() { + return this.mEnabled; + } + + public void setEnabled(final boolean pEnabled) { + this.mEnabled = pEnabled; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract boolean onManagedTouchEvent(TouchEvent pSceneTouchEvent); + + @Override + public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) { + return this.onTouchEvent(pSceneTouchEvent); + } + + public final boolean onTouchEvent(final TouchEvent pSceneTouchEvent) { + if(this.mEnabled) { + return this.onManagedTouchEvent(pSceneTouchEvent); + } else { + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/detector/ClickDetector.java b/AndEngine/src/org/anddev/andengine/input/touch/detector/ClickDetector.java new file mode 100644 index 0000000..ba3937c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/detector/ClickDetector.java @@ -0,0 +1,95 @@ +package org.anddev.andengine.input.touch.detector; + +import org.anddev.andengine.input.touch.TouchEvent; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 14:29:59 - 16.08.2010 + */ +public class ClickDetector extends BaseDetector { + // =========================================================== + // Constants + // =========================================================== + + private static final long TRIGGER_CLICK_MAXIMUM_MILLISECONDS_DEFAULT = 200; + + // =========================================================== + // Fields + // =========================================================== + + private long mTriggerClickMaximumMilliseconds; + private final IClickDetectorListener mClickDetectorListener; + + private long mDownTimeMilliseconds = Long.MIN_VALUE; + + // =========================================================== + // Constructors + // =========================================================== + + public ClickDetector(final IClickDetectorListener pClickDetectorListener) { + this(TRIGGER_CLICK_MAXIMUM_MILLISECONDS_DEFAULT, pClickDetectorListener); + } + + public ClickDetector(final long pTriggerClickMaximumMilliseconds, final IClickDetectorListener pClickDetectorListener) { + this.mTriggerClickMaximumMilliseconds = pTriggerClickMaximumMilliseconds; + this.mClickDetectorListener = pClickDetectorListener; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public long getTriggerClickMaximumMilliseconds() { + return this.mTriggerClickMaximumMilliseconds; + } + + public void setTriggerClickMaximumMilliseconds(final long pClickMaximumMilliseconds) { + this.mTriggerClickMaximumMilliseconds = pClickMaximumMilliseconds; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onManagedTouchEvent(final TouchEvent pSceneTouchEvent) { + switch(pSceneTouchEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + this.mDownTimeMilliseconds = pSceneTouchEvent.getMotionEvent().getDownTime(); + return true; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + final long upTimeMilliseconds = pSceneTouchEvent.getMotionEvent().getEventTime(); + + if(upTimeMilliseconds - this.mDownTimeMilliseconds <= this.mTriggerClickMaximumMilliseconds) { + this.mDownTimeMilliseconds = Long.MIN_VALUE; + this.mClickDetectorListener.onClick(this, pSceneTouchEvent); + } + return true; + default: + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IClickDetectorListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onClick(final ClickDetector pClickDetector, final TouchEvent pTouchEvent); + } +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/detector/HoldDetector.java b/AndEngine/src/org/anddev/andengine/input/touch/detector/HoldDetector.java new file mode 100644 index 0000000..9ef6212 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/detector/HoldDetector.java @@ -0,0 +1,189 @@ +package org.anddev.andengine.input.touch.detector; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.engine.handler.timer.ITimerCallback; +import org.anddev.andengine.engine.handler.timer.TimerHandler; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.input.touch.TouchEvent; + +import android.os.SystemClock; +import android.speech.tts.TextToSpeech.Engine; +import android.view.MotionEvent; + +/** + * Note: Needs to be registered as an {@link IUpdateHandler} to the {@link Engine} or {@link Scene} to work properly. + * + * @author Nicolas Gramlich + * @since 20:49:25 - 23.08.2010 + */ +public class HoldDetector extends BaseDetector implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + private static final long TRIGGER_HOLD_MINIMUM_MILLISECONDS_DEFAULT = 200; + private static final float TRIGGER_HOLD_MAXIMUM_DISTANCE_DEFAULT = 10; + + private static final float TIME_BETWEEN_UPDATES_DEFAULT = 0.1f; + + // =========================================================== + // Fields + // =========================================================== + + private long mTriggerHoldMinimumMilliseconds; + private float mTriggerHoldMaximumDistance; + private final IHoldDetectorListener mHoldDetectorListener; + + private long mDownTimeMilliseconds = Long.MIN_VALUE; + + private float mDownX; + private float mDownY; + + private float mHoldX; + private float mHoldY; + + private boolean mMaximumDistanceExceeded = false; + + private boolean mTriggerOnHold = false; + private boolean mTriggerOnHoldFinished = false; + + private final TimerHandler mTimerHandler; + + // =========================================================== + // Constructors + // =========================================================== + + public HoldDetector(final IHoldDetectorListener pClickDetectorListener) { + this(TRIGGER_HOLD_MINIMUM_MILLISECONDS_DEFAULT, TRIGGER_HOLD_MAXIMUM_DISTANCE_DEFAULT, TIME_BETWEEN_UPDATES_DEFAULT, pClickDetectorListener); + } + + public HoldDetector(final long pTriggerHoldMinimumMilliseconds, final float pTriggerHoldMaximumDistance, final float pTimeBetweenUpdates, final IHoldDetectorListener pClickDetectorListener) { + this.mTriggerHoldMinimumMilliseconds = pTriggerHoldMinimumMilliseconds; + this.mTriggerHoldMaximumDistance = pTriggerHoldMaximumDistance; + this.mHoldDetectorListener = pClickDetectorListener; + + this.mTimerHandler = new TimerHandler(pTimeBetweenUpdates, true, new ITimerCallback() { + @Override + public void onTimePassed(final TimerHandler pTimerHandler) { + HoldDetector.this.fireListener(); + } + }); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public long getTriggerHoldMinimumMilliseconds() { + return this.mTriggerHoldMinimumMilliseconds; + } + + public void setTriggerHoldMinimumMilliseconds(final long pTriggerHoldMinimumMilliseconds) { + this.mTriggerHoldMinimumMilliseconds = pTriggerHoldMinimumMilliseconds; + } + + public float getTriggerHoldMaximumDistance() { + return this.mTriggerHoldMaximumDistance; + } + + public void setTriggerHoldMaximumDistance(final float pTriggerHoldMaximumDistance) { + this.mTriggerHoldMaximumDistance = pTriggerHoldMaximumDistance; + } + + public boolean isHolding() { + return this.mTriggerOnHold; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + this.mTimerHandler.onUpdate(pSecondsElapsed); + } + + @Override + public void reset() { + this.mTimerHandler.reset(); + } + + @Override + public boolean onManagedTouchEvent(final TouchEvent pSceneTouchEvent) { + final MotionEvent motionEvent = pSceneTouchEvent.getMotionEvent(); + + this.mHoldX = pSceneTouchEvent.getX(); + this.mHoldY = pSceneTouchEvent.getY(); + + switch(pSceneTouchEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + this.mDownTimeMilliseconds = motionEvent.getDownTime(); + this.mDownX = motionEvent.getX(); + this.mDownY = motionEvent.getY(); + this.mMaximumDistanceExceeded = false; + return true; + case MotionEvent.ACTION_MOVE: + { + final long currentTimeMilliseconds = motionEvent.getEventTime(); + + final float triggerHoldMaximumDistance = this.mTriggerHoldMaximumDistance; + this.mMaximumDistanceExceeded = this.mMaximumDistanceExceeded || Math.abs(this.mDownX - motionEvent.getX()) > triggerHoldMaximumDistance || Math.abs(this.mDownY - motionEvent.getY()) > triggerHoldMaximumDistance; + if(this.mTriggerOnHold || !this.mMaximumDistanceExceeded) { + final long holdTimeMilliseconds = currentTimeMilliseconds - this.mDownTimeMilliseconds; + if(holdTimeMilliseconds >= this.mTriggerHoldMinimumMilliseconds) { + this.mTriggerOnHold = true; + } + } + return true; + } + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + { + final long upTimeMilliseconds = motionEvent.getEventTime(); + + final float triggerHoldMaximumDistance = this.mTriggerHoldMaximumDistance; + this.mMaximumDistanceExceeded = this.mMaximumDistanceExceeded || Math.abs(this.mDownX - motionEvent.getX()) > triggerHoldMaximumDistance || Math.abs(this.mDownY - motionEvent.getY()) > triggerHoldMaximumDistance; + if(this.mTriggerOnHold || !this.mMaximumDistanceExceeded) { + final long holdTimeMilliseconds = upTimeMilliseconds - this.mDownTimeMilliseconds; + if(holdTimeMilliseconds >= this.mTriggerHoldMinimumMilliseconds) { + this.mTriggerOnHoldFinished = true; + } + } + return true; + } + default: + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + protected void fireListener() { + if(this.mTriggerOnHoldFinished) { + this.mHoldDetectorListener.onHoldFinished(this, SystemClock.uptimeMillis() - this.mDownTimeMilliseconds, this.mHoldX, this.mHoldY); + this.mTriggerOnHoldFinished = false; + this.mTriggerOnHold = false; + } else if(this.mTriggerOnHold) { + this.mHoldDetectorListener.onHold(this, SystemClock.uptimeMillis() - this.mDownTimeMilliseconds, this.mHoldX, this.mHoldY); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IHoldDetectorListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onHold(final HoldDetector pHoldDetector, final long pHoldTimeMilliseconds, final float pHoldX, final float pHoldY); + public void onHoldFinished(final HoldDetector pHoldDetector, final long pHoldTimeMilliseconds, final float pHoldX, final float pHoldY); + } +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/detector/ScrollDetector.java b/AndEngine/src/org/anddev/andengine/input/touch/detector/ScrollDetector.java new file mode 100644 index 0000000..1e87f02 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/detector/ScrollDetector.java @@ -0,0 +1,117 @@ +package org.anddev.andengine.input.touch.detector; + +import org.anddev.andengine.input.touch.TouchEvent; + +import android.view.MotionEvent; + +/** + * @author Nicolas Gramlich + * @since 14:29:59 - 16.08.2010 + */ +public class ScrollDetector extends BaseDetector { + // =========================================================== + // Constants + // =========================================================== + + private static final float TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT = 10; + + // =========================================================== + // Fields + // =========================================================== + + private float mTriggerScrollMinimumDistance; + + private final IScrollDetectorListener mScrollDetectorListener; + + private boolean mTriggered; + + private float mLastX; + private float mLastY; + + // =========================================================== + // Constructors + // =========================================================== + + public ScrollDetector(final IScrollDetectorListener pScrollDetectorListener) { + this(TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT, pScrollDetectorListener); + } + + public ScrollDetector(final float pTriggerScrollMinimumDistance, final IScrollDetectorListener pScrollDetectorListener) { + this.mTriggerScrollMinimumDistance = pTriggerScrollMinimumDistance; + this.mScrollDetectorListener = pScrollDetectorListener; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getTriggerScrollMinimumDistance() { + return this.mTriggerScrollMinimumDistance; + } + + public void setTriggerScrollMinimumDistance(final float pTriggerScrollMinimumDistance) { + this.mTriggerScrollMinimumDistance = pTriggerScrollMinimumDistance; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onManagedTouchEvent(final TouchEvent pSceneTouchEvent) { + final float touchX = this.getX(pSceneTouchEvent); + final float touchY = this.getY(pSceneTouchEvent); + + switch(pSceneTouchEvent.getAction()) { + case MotionEvent.ACTION_DOWN: + this.mLastX = touchX; + this.mLastY = touchY; + this.mTriggered = false; + return true; + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + final float distanceX = touchX - this.mLastX; + final float distanceY = touchY - this.mLastY; + + final float triggerScrollMinimumDistance = this.mTriggerScrollMinimumDistance; + if(this.mTriggered || Math.abs(distanceX) > triggerScrollMinimumDistance || Math.abs(distanceY) > triggerScrollMinimumDistance) { + this.mScrollDetectorListener.onScroll(this, pSceneTouchEvent, distanceX, distanceY); + this.mLastX = touchX; + this.mLastY = touchY; + this.mTriggered = true; + } + return true; + default: + return false; + } + } + + // =========================================================== + // Methods + // =========================================================== + + protected float getX(final TouchEvent pTouchEvent) { + return pTouchEvent.getX(); + } + + protected float getY(final TouchEvent pTouchEvent) { + return pTouchEvent.getY(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IScrollDetectorListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onScroll(final ScrollDetector pScollDetector, final TouchEvent pTouchEvent, final float pDistanceX, final float pDistanceY); + } +} diff --git a/AndEngine/src/org/anddev/andengine/input/touch/detector/SurfaceGestureDetector.java b/AndEngine/src/org/anddev/andengine/input/touch/detector/SurfaceGestureDetector.java new file mode 100644 index 0000000..fba10f6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/detector/SurfaceGestureDetector.java @@ -0,0 +1,195 @@ +package org.anddev.andengine.input.touch.detector; + +import org.anddev.andengine.input.touch.TouchEvent; + +import android.view.GestureDetector; +import android.view.GestureDetector.SimpleOnGestureListener; +import android.view.MotionEvent; + +/** + * @author rkpost + * @author Nicolas Gramlich + * @since 11:36:26 - 11.10.2010 + */ +public abstract class SurfaceGestureDetector extends BaseDetector { + // =========================================================== + // Constants + // =========================================================== + + private static final float SWIPE_MIN_DISTANCE_DEFAULT = 120; + + // =========================================================== + // Fields + // =========================================================== + + private final GestureDetector mGestureDetector; + + // =========================================================== + // Constructors + // =========================================================== + + public SurfaceGestureDetector() { + this(SWIPE_MIN_DISTANCE_DEFAULT); + } + + public SurfaceGestureDetector(final float pSwipeMinDistance) { + this.mGestureDetector = new GestureDetector(new InnerOnGestureDetectorListener(pSwipeMinDistance)); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract boolean onSingleTap(); + protected abstract boolean onDoubleTap(); + protected abstract boolean onSwipeUp(); + protected abstract boolean onSwipeDown(); + protected abstract boolean onSwipeLeft(); + protected abstract boolean onSwipeRight(); + + @Override + public boolean onManagedTouchEvent(final TouchEvent pSceneTouchEvent) { + return this.mGestureDetector.onTouchEvent(pSceneTouchEvent.getMotionEvent()); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private class InnerOnGestureDetectorListener extends SimpleOnGestureListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mSwipeMinDistance; + + // =========================================================== + // Constructors + // =========================================================== + + public InnerOnGestureDetectorListener(final float pSwipeMinDistance) { + this.mSwipeMinDistance = pSwipeMinDistance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean onSingleTapConfirmed(final MotionEvent pMotionEvent) { + return SurfaceGestureDetector.this.onSingleTap(); + } + + @Override + public boolean onDoubleTap(final MotionEvent pMotionEvent) { + return SurfaceGestureDetector.this.onDoubleTap(); + } + + @Override + public boolean onFling(final MotionEvent pMotionEventStart, final MotionEvent pMotionEventEnd, final float pVelocityX, final float pVelocityY) { + final float swipeMinDistance = this.mSwipeMinDistance; + + final boolean isHorizontalFling = Math.abs(pVelocityX) > Math.abs(pVelocityY); + + if(isHorizontalFling) { + if(pMotionEventStart.getX() - pMotionEventEnd.getX() > swipeMinDistance) { + return SurfaceGestureDetector.this.onSwipeLeft(); + } else if(pMotionEventEnd.getX() - pMotionEventStart.getX() > swipeMinDistance) { + return SurfaceGestureDetector.this.onSwipeRight(); + } + } else { + if(pMotionEventStart.getY() - pMotionEventEnd.getY() > swipeMinDistance) { + return SurfaceGestureDetector.this.onSwipeUp(); + } else if(pMotionEventEnd.getY() - pMotionEventStart.getY() > swipeMinDistance) { + return SurfaceGestureDetector.this.onSwipeDown(); + } + } + + return false; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } + + public static class SurfaceGestureDetectorAdapter extends SurfaceGestureDetector { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected boolean onDoubleTap() { + return false; + } + + @Override + protected boolean onSingleTap() { + return false; + } + + @Override + protected boolean onSwipeDown() { + return false; + } + + @Override + protected boolean onSwipeLeft() { + return false; + } + + @Override + protected boolean onSwipeRight() { + return false; + } + + @Override + protected boolean onSwipeUp() { + return false; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/input/touch/detector/SurfaceScrollDetector.java b/AndEngine/src/org/anddev/andengine/input/touch/detector/SurfaceScrollDetector.java new file mode 100644 index 0000000..41c8c04 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/input/touch/detector/SurfaceScrollDetector.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.input.touch.detector; + +import org.anddev.andengine.input.touch.TouchEvent; + +/** + * @author Nicolas Gramlich + * @since 16:12:29 - 16.08.2010 + */ +public class SurfaceScrollDetector extends ScrollDetector { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SurfaceScrollDetector(final float pTriggerScrollMinimumDistance, final IScrollDetectorListener pScrollDetectorListener) { + super(pTriggerScrollMinimumDistance, pScrollDetectorListener); + } + + public SurfaceScrollDetector(final IScrollDetectorListener pScrollDetectorListener) { + super(pScrollDetectorListener); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected float getX(final TouchEvent pTouchEvent) { + return pTouchEvent.getMotionEvent().getX(); + } + + @Override + protected float getY(final TouchEvent pTouchEvent) { + return pTouchEvent.getMotionEvent().getY(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/level/LevelLoader.java b/AndEngine/src/org/anddev/andengine/level/LevelLoader.java new file mode 100644 index 0000000..3be1487 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/level/LevelLoader.java @@ -0,0 +1,143 @@ +package org.anddev.andengine.level; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.anddev.andengine.level.util.constants.LevelConstants; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.StreamUtils; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import android.content.Context; + +/** + * @author Nicolas Gramlich + * @since 14:16:19 - 11.10.2010 + */ +public class LevelLoader implements LevelConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private String mAssetBasePath; + + private final HashMap mEntityLoaders = new HashMap(); + + // =========================================================== + // Constructors + // =========================================================== + + public LevelLoader() { + this(""); + } + + public LevelLoader(final String pAssetBasePath) { + this.setAssetBasePath(pAssetBasePath); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * @param pAssetBasePath must end with '/' or have .length() == 0. + */ + public void setAssetBasePath(final String pAssetBasePath) { + if(pAssetBasePath.endsWith("/") || pAssetBasePath.length() == 0) { + this.mAssetBasePath = pAssetBasePath; + } else { + throw new IllegalStateException("pAssetBasePath must end with '/' or be lenght zero."); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected void onAfterLoadLevel() { + + } + + protected void onBeforeLoadLevel() { + + } + + // =========================================================== + // Methods + // =========================================================== + + public void registerEntityLoader(final String pEntityName, final IEntityLoader pEntityLoader) { + this.mEntityLoaders.put(pEntityName, pEntityLoader); + } + + public void registerEntityLoader(final String[] pEntityNames, final IEntityLoader pEntityLoader) { + final HashMap entityLoaders = this.mEntityLoaders; + + for(int i = pEntityNames.length - 1; i >= 0; i--) { + entityLoaders.put(pEntityNames[i], pEntityLoader); + } + } + + public void loadLevelFromAsset(final Context pContext, final String pAssetPath) throws IOException { + this.loadLevelFromStream(pContext.getAssets().open(this.mAssetBasePath + pAssetPath)); + } + + public void loadLevelFromResource(final Context pContext, final int pRawResourceID) throws IOException { + this.loadLevelFromStream(pContext.getResources().openRawResource(pRawResourceID)); + } + + public void loadLevelFromStream(final InputStream pInputStream) throws IOException { + try{ + final SAXParserFactory spf = SAXParserFactory.newInstance(); + final SAXParser sp = spf.newSAXParser(); + + final XMLReader xr = sp.getXMLReader(); + + this.onBeforeLoadLevel(); + + final LevelParser levelParser = new LevelParser(this.mEntityLoaders); + xr.setContentHandler(levelParser); + + xr.parse(new InputSource(new BufferedInputStream(pInputStream))); + + this.onAfterLoadLevel(); + } catch (final SAXException se) { + Debug.e(se); + /* Doesn't happen. */ + } catch (final ParserConfigurationException pe) { + Debug.e(pe); + /* Doesn't happen. */ + } finally { + StreamUtils.close(pInputStream); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IEntityLoader { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onLoadEntity(final String pEntityName, final Attributes pAttributes); + } +} diff --git a/AndEngine/src/org/anddev/andengine/level/LevelParser.java b/AndEngine/src/org/anddev/andengine/level/LevelParser.java new file mode 100644 index 0000000..d97b699 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/level/LevelParser.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.level; + +import java.util.HashMap; + +import org.anddev.andengine.level.LevelLoader.IEntityLoader; +import org.anddev.andengine.level.util.constants.LevelConstants; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * @author Nicolas Gramlich + * @since 14:35:32 - 11.10.2010 + */ +public class LevelParser extends DefaultHandler implements LevelConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final HashMap mEntityLoaders; + + // =========================================================== + // Constructors + // =========================================================== + + public LevelParser(final HashMap pEntityLoaders) { + this.mEntityLoaders = pEntityLoaders; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void startElement(final String pUri, final String pLocalName, final String pQualifiedName, final Attributes pAttributes) throws SAXException { + final IEntityLoader entityLoader = this.mEntityLoaders.get(pLocalName); + if(entityLoader != null) { + entityLoader.onLoadEntity(pLocalName, pAttributes); + } else { + throw new IllegalArgumentException("Unexpected tag: '" + pLocalName + "'."); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/level/util/constants/LevelConstants.java b/AndEngine/src/org/anddev/andengine/level/util/constants/LevelConstants.java new file mode 100644 index 0000000..dee65d8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/level/util/constants/LevelConstants.java @@ -0,0 +1,22 @@ +package org.anddev.andengine.level.util.constants; + + +/** + * @author Nicolas Gramlich + * @since 14:23:27 - 11.10.2010 + */ +public interface LevelConstants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final String TAG_LEVEL = "level"; + public static final String TAG_LEVEL_ATTRIBUTE_NAME = "name"; + public static final String TAG_LEVEL_ATTRIBUTE_UID = "uid"; + public static final String TAG_LEVEL_ATTRIBUTE_WIDTH = "width"; + public static final String TAG_LEVEL_ATTRIBUTE_HEIGHT = "height"; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/IDrawable.java b/AndEngine/src/org/anddev/andengine/opengl/IDrawable.java new file mode 100644 index 0000000..d9e62de --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/IDrawable.java @@ -0,0 +1,22 @@ +package org.anddev.andengine.opengl; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.camera.Camera; + + +/** + * @author Nicolas Gramlich + * @since 10:50:58 - 08.08.2010 + */ +public interface IDrawable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onDraw(final GL10 pGL, final Camera pCamera); +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/buffer/BufferObject.java b/AndEngine/src/org/anddev/andengine/opengl/buffer/BufferObject.java new file mode 100644 index 0000000..935a56e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/buffer/BufferObject.java @@ -0,0 +1,120 @@ +package org.anddev.andengine.opengl.buffer; + +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.opengl.util.FastFloatBuffer; +import org.anddev.andengine.opengl.util.GLHelper; + +/** + * @author Nicolas Gramlich + * @since 14:22:56 - 07.04.2010 + */ +public abstract class BufferObject { + // =========================================================== + // Constants + // =========================================================== + + private static final int[] HARDWAREBUFFERID_FETCHER = new int[1]; + + // =========================================================== + // Fields + // =========================================================== + + protected final int[] mBufferData; + + private final int mDrawType; + + private final FastFloatBuffer mFloatBuffer; + + private int mHardwareBufferID = -1; + private boolean mLoadedToHardware; + private boolean mHardwareBufferNeedsUpdate = true; + + // =========================================================== + // Constructors + // =========================================================== + + public BufferObject(final int pCapacity, final int pDrawType) { + this.mDrawType = pDrawType; + this.mBufferData = new int[pCapacity]; + this.mFloatBuffer = new FastFloatBuffer(pCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public FastFloatBuffer getFloatBuffer() { + return this.mFloatBuffer; + } + + public int getHardwareBufferID() { + return this.mHardwareBufferID; + } + + public boolean isLoadedToHardware() { + return this.mLoadedToHardware; + } + + void setLoadedToHardware(final boolean pLoadedToHardware) { + this.mLoadedToHardware = pLoadedToHardware; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public void setHardwareBufferNeedsUpdate(){ + this.mHardwareBufferNeedsUpdate = true; + } + + // =========================================================== + // Methods + // =========================================================== + + public void selectOnHardware(final GL11 pGL11) { + final int hardwareBufferID = this.mHardwareBufferID; + if(hardwareBufferID == -1) { + return; + } + + GLHelper.bindBuffer(pGL11, hardwareBufferID); // TODO Does this always need to be binded, or are just for buffers of the same 'type'(texture/vertex)? + + if(this.mHardwareBufferNeedsUpdate) { + // Debug.d("BufferObject.updating: ID = " + this.mHardwareBufferID); + this.mHardwareBufferNeedsUpdate = false; + synchronized(this) { + GLHelper.bufferData(pGL11, this.mFloatBuffer.mByteBuffer, this.mDrawType); + } + } + } + + public void loadToHardware(final GL11 pGL11) { + this.mHardwareBufferID = this.generateHardwareBufferID(pGL11); + // Debug.d("BufferObject.loadToHardware(): ID = " + this.mHardwareBufferID); + + this.mLoadedToHardware = true; + } + + public void unloadFromHardware(final GL11 pGL11) { + this.deleteBufferOnHardware(pGL11); + + this.mHardwareBufferID = -1; + + this.mLoadedToHardware = false; + } + + private void deleteBufferOnHardware(final GL11 pGL11) { + GLHelper.deleteBuffer(pGL11, this.mHardwareBufferID); + } + + private int generateHardwareBufferID(final GL11 pGL11) { + pGL11.glGenBuffers(1, HARDWAREBUFFERID_FETCHER, 0); + + return HARDWAREBUFFERID_FETCHER[0]; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/buffer/BufferObjectManager.java b/AndEngine/src/org/anddev/andengine/opengl/buffer/BufferObjectManager.java new file mode 100644 index 0000000..7f6c495 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/buffer/BufferObjectManager.java @@ -0,0 +1,151 @@ +package org.anddev.andengine.opengl.buffer; + +import java.util.ArrayList; +import java.util.HashSet; + +import javax.microedition.khronos.opengles.GL11; + +/** + * @author Nicolas Gramlich + * @since 17:48:46 - 08.03.2010 + */ +public class BufferObjectManager { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static final HashSet mBufferObjectsManaged = new HashSet(); + + private static final ArrayList mBufferObjectsLoaded = new ArrayList(); + + private static final ArrayList mBufferObjectsToBeLoaded = new ArrayList(); + private static final ArrayList mBufferObjectsToBeUnloaded = new ArrayList(); + + private static BufferObjectManager mActiveInstance = null; + + // =========================================================== + // Constructors + // =========================================================== + + public static BufferObjectManager getActiveInstance() { + return BufferObjectManager.mActiveInstance; + } + + public static void setActiveInstance(final BufferObjectManager pActiveInstance) { + BufferObjectManager.mActiveInstance = pActiveInstance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void clear() { + BufferObjectManager.mBufferObjectsToBeLoaded.clear(); + BufferObjectManager.mBufferObjectsLoaded.clear(); + BufferObjectManager.mBufferObjectsManaged.clear(); + } + + public void loadBufferObject(final BufferObject pBufferObject) { + if(pBufferObject == null) { + return; + } + + if(BufferObjectManager.mBufferObjectsManaged.contains(pBufferObject)) { + /* Just make sure it doesn't get deleted. */ + BufferObjectManager.mBufferObjectsToBeUnloaded.remove(pBufferObject); + } else { + BufferObjectManager.mBufferObjectsManaged.add(pBufferObject); + BufferObjectManager.mBufferObjectsToBeLoaded.add(pBufferObject); + } + } + + public void unloadBufferObject(final BufferObject pBufferObject) { + if(pBufferObject == null) { + return; + } + if(BufferObjectManager.mBufferObjectsManaged.contains(pBufferObject)) { + if(BufferObjectManager.mBufferObjectsLoaded.contains(pBufferObject)) { + BufferObjectManager.mBufferObjectsToBeUnloaded.add(pBufferObject); + } else if(BufferObjectManager.mBufferObjectsToBeLoaded.remove(pBufferObject)) { + BufferObjectManager.mBufferObjectsManaged.remove(pBufferObject); + } + } + } + + public void loadBufferObjects(final BufferObject... pBufferObjects) { + for(int i = pBufferObjects.length - 1; i >= 0; i--) { + this.loadBufferObject(pBufferObjects[i]); + } + } + + public void unloadBufferObjects(final BufferObject... pBufferObjects) { + for(int i = pBufferObjects.length - 1; i >= 0; i--) { + this.unloadBufferObject(pBufferObjects[i]); + } + } + + public void reloadBufferObjects() { + final ArrayList loadedBufferObjects = BufferObjectManager.mBufferObjectsLoaded; + for(int i = loadedBufferObjects.size() - 1; i >= 0; i--) { + loadedBufferObjects.get(i).setLoadedToHardware(false); + } + + BufferObjectManager.mBufferObjectsToBeLoaded.addAll(loadedBufferObjects); + + loadedBufferObjects.clear(); + } + + public void updateBufferObjects(final GL11 pGL11) { + final HashSet bufferObjectsManaged = BufferObjectManager.mBufferObjectsManaged; + final ArrayList bufferObjectsLoaded = BufferObjectManager.mBufferObjectsLoaded; + final ArrayList bufferObjectsToBeLoaded = BufferObjectManager.mBufferObjectsToBeLoaded; + final ArrayList bufferObjectsToBeUnloaded = BufferObjectManager.mBufferObjectsToBeUnloaded; + + /* First load pending BufferObjects. */ + final int bufferObjectToBeLoadedCount = bufferObjectsToBeLoaded.size(); + + if(bufferObjectToBeLoadedCount > 0) { + for(int i = bufferObjectToBeLoadedCount - 1; i >= 0; i--) { + final BufferObject bufferObjectToBeLoaded = bufferObjectsToBeLoaded.get(i); + if(!bufferObjectToBeLoaded.isLoadedToHardware()) { + bufferObjectToBeLoaded.loadToHardware(pGL11); + bufferObjectToBeLoaded.setHardwareBufferNeedsUpdate(); + } + bufferObjectsLoaded.add(bufferObjectToBeLoaded); + } + + bufferObjectsToBeLoaded.clear(); + } + + /* Then unload pending BufferObjects. */ + final int bufferObjectsToBeUnloadedCount = bufferObjectsToBeUnloaded.size(); + + if(bufferObjectsToBeUnloadedCount > 0){ + for(int i = bufferObjectsToBeUnloadedCount - 1; i >= 0; i--){ + final BufferObject bufferObjectToBeUnloaded = bufferObjectsToBeUnloaded.remove(i); + if(bufferObjectToBeUnloaded.isLoadedToHardware()){ + bufferObjectToBeUnloaded.unloadFromHardware(pGL11); + } + bufferObjectsLoaded.remove(bufferObjectToBeUnloaded); + bufferObjectsManaged.remove(bufferObjectToBeUnloaded); + } + } + + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/Font.java b/AndEngine/src/org/anddev/andengine/opengl/font/Font.java new file mode 100644 index 0000000..d0ba3ad --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/Font.java @@ -0,0 +1,226 @@ +package org.anddev.andengine.opengl.font; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.util.GLHelper; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Paint.FontMetrics; +import android.graphics.Paint.Style; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.opengl.GLUtils; +import android.util.FloatMath; +import android.util.SparseArray; + +/** + * @author Nicolas Gramlich + * @since 10:39:33 - 03.04.2010 + */ +public class Font { + // =========================================================== + // Constants + // =========================================================== + + protected static final float LETTER_LEFT_OFFSET = 0; + private static final int LETTER_EXTRA_WIDTH = 10; + + // =========================================================== + // Fields + // =========================================================== + + private final Texture mTexture; + private final float mTextureWidth; + private final float mTextureHeight; + private int mCurrentTextureX = 0; + private int mCurrentTextureY = 0; + + private final SparseArray mManagedCharacterToLetterMap = new SparseArray(); + private final ArrayList mLettersPendingToBeDrawnToTexture = new ArrayList(); + + protected final Paint mPaint; + private final Paint mBackgroundPaint; + + protected final FontMetrics mFontMetrics; + private final int mLineHeight; + private final int mLineGap; + + private final Size mCreateLetterTemporarySize = new Size(); + private final Rect mGetLetterBitmapTemporaryRect = new Rect(); + private final Rect mGetStringWidthTemporaryRect = new Rect(); + private final Rect mGetLetterBoundsTemporaryRect = new Rect(); + private final float[] mTemporaryTextWidthFetchers = new float[1]; + + protected final Canvas mCanvas = new Canvas(); + + // =========================================================== + // Constructors + // =========================================================== + + public Font(final Texture pTexture, final Typeface pTypeface, final float pSize, final boolean pAntiAlias, final int pColor) { + this.mTexture = pTexture; + this.mTextureWidth = pTexture.getWidth(); + this.mTextureHeight = pTexture.getHeight(); + + this.mPaint = new Paint(); + this.mPaint.setTypeface(pTypeface); + this.mPaint.setColor(pColor); + this.mPaint.setTextSize(pSize); + this.mPaint.setAntiAlias(pAntiAlias); + + this.mBackgroundPaint = new Paint(); + this.mBackgroundPaint.setColor(Color.TRANSPARENT); + this.mBackgroundPaint.setStyle(Style.FILL); + + this.mFontMetrics = this.mPaint.getFontMetrics(); + this.mLineHeight = (int) FloatMath.ceil(Math.abs(this.mFontMetrics.ascent) + Math.abs(this.mFontMetrics.descent)); + this.mLineGap = (int) (FloatMath.ceil(this.mFontMetrics.leading)); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getLineGap() { + return this.mLineGap; + } + + public int getLineHeight() { + return this.mLineHeight; + } + + public Texture getTexture() { + return this.mTexture; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void reload() { + final ArrayList lettersPendingToBeDrawnToTexture = this.mLettersPendingToBeDrawnToTexture; + final SparseArray managedCharacterToLetterMap = this.mManagedCharacterToLetterMap; + + /* Make all letters redraw to the texture. */ + for(int i = managedCharacterToLetterMap.size() - 1; i >= 0; i--) { + lettersPendingToBeDrawnToTexture.add(managedCharacterToLetterMap.valueAt(i)); + } + } + + private int getLetterAdvance(final char pCharacter) { + this.mPaint.getTextWidths(String.valueOf(pCharacter), this.mTemporaryTextWidthFetchers); + return (int) (FloatMath.ceil(this.mTemporaryTextWidthFetchers[0])); + } + + private Bitmap getLetterBitmap(final char pCharacter) { + final Rect getLetterBitmapTemporaryRect = this.mGetLetterBitmapTemporaryRect; + final String characterAsString = String.valueOf(pCharacter); + this.mPaint.getTextBounds(characterAsString, 0, 1, getLetterBitmapTemporaryRect); + + final int lineHeight = this.getLineHeight(); + final Bitmap bitmap = Bitmap.createBitmap(getLetterBitmapTemporaryRect.width() == 0 ? 1 : getLetterBitmapTemporaryRect.width() + LETTER_EXTRA_WIDTH, lineHeight, Bitmap.Config.ARGB_8888); + this.mCanvas.setBitmap(bitmap); + + /* Make background transparent. */ + this.mCanvas.drawRect(0, 0, getLetterBitmapTemporaryRect.width() + LETTER_EXTRA_WIDTH, lineHeight, this.mBackgroundPaint); + + /* Actually draw the character. */ + this.drawCharacterString(characterAsString); + + return bitmap; + } + + protected void drawCharacterString(final String pCharacterAsString) { + this.mCanvas.drawText(pCharacterAsString, LETTER_LEFT_OFFSET, -this.mFontMetrics.ascent, this.mPaint); + } + + public int getStringWidth(final String pText) { + this.mPaint.getTextBounds(pText, 0, pText.length(), this.mGetStringWidthTemporaryRect); + return this.mGetStringWidthTemporaryRect.width(); + } + + private void getLetterBounds(final char pCharacter, final Size pSize) { + this.mPaint.getTextBounds(String.valueOf(pCharacter), 0, 1, this.mGetLetterBoundsTemporaryRect); + pSize.set(this.mGetLetterBoundsTemporaryRect.width() + LETTER_EXTRA_WIDTH, this.getLineHeight()); + } + + public void prepareLettes(final char ... pCharacters) { + for(final char character : pCharacters) { + this.getLetter(character); + } + } + + public synchronized Letter getLetter(final char pCharacter) { + final SparseArray managedCharacterToLetterMap = this.mManagedCharacterToLetterMap; + Letter letter = managedCharacterToLetterMap.get(pCharacter); + if (letter == null) { + letter = this.createLetter(pCharacter); + + this.mLettersPendingToBeDrawnToTexture.add(letter); + managedCharacterToLetterMap.put(pCharacter, letter); + } + return letter; + } + + private Letter createLetter(final char pCharacter) { + final float textureWidth = this.mTextureWidth; + final float textureHeight = this.mTextureHeight; + + final Size createLetterTemporarySize = this.mCreateLetterTemporarySize; + this.getLetterBounds(pCharacter, createLetterTemporarySize); + + final float letterWidth = createLetterTemporarySize.getWidth(); + final float letterHeight = createLetterTemporarySize.getHeight(); + + if (this.mCurrentTextureX + letterWidth >= textureWidth) { + this.mCurrentTextureX = 0; + this.mCurrentTextureY += this.getLineGap() + this.getLineHeight(); + } + + final float letterTextureX = this.mCurrentTextureX / textureWidth; + final float letterTextureY = this.mCurrentTextureY / textureHeight; + final float letterTextureWidth = letterWidth / textureWidth; + final float letterTextureHeight = letterHeight / textureHeight; + + final Letter letter = new Letter(pCharacter, this.getLetterAdvance(pCharacter), (int)letterWidth, (int)letterHeight, letterTextureX, letterTextureY, letterTextureWidth, letterTextureHeight); + this.mCurrentTextureX += letterWidth; + + return letter; + } + + public synchronized void update(final GL10 pGL) { + final ArrayList lettersPendingToBeDrawnToTexture = this.mLettersPendingToBeDrawnToTexture; + if(lettersPendingToBeDrawnToTexture.size() > 0) { + final int hardwareTextureID = this.mTexture.getHardwareTextureID(); + + final float textureWidth = this.mTextureWidth; + final float textureHeight = this.mTextureHeight; + + for(int i = lettersPendingToBeDrawnToTexture.size() - 1; i >= 0; i--) { + final Letter letter = lettersPendingToBeDrawnToTexture.get(i); + final Bitmap bitmap = this.getLetterBitmap(letter.mCharacter); + + GLHelper.bindTexture(pGL, hardwareTextureID); + GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, (int)(letter.mTextureX * textureWidth), (int)(letter.mTextureY * textureHeight), bitmap); + + bitmap.recycle(); + } + lettersPendingToBeDrawnToTexture.clear(); + System.gc(); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/FontFactory.java b/AndEngine/src/org/anddev/andengine/opengl/font/FontFactory.java new file mode 100644 index 0000000..3f6be15 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/FontFactory.java @@ -0,0 +1,77 @@ +package org.anddev.andengine.opengl.font; + +import org.anddev.andengine.opengl.texture.Texture; + +import android.content.Context; +import android.graphics.Typeface; + +/** + * @author Nicolas Gramlich + * @since 17:17:28 - 16.06.2010 + */ +public class FontFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static String sAssetBasePath = ""; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * @param pAssetBasePath must end with '/' or have .length() == 0. + */ + public static void setAssetBasePath(final String pAssetBasePath) { + if(pAssetBasePath.endsWith("/") || pAssetBasePath.length() == 0) { + FontFactory.sAssetBasePath = pAssetBasePath; + } else { + throw new IllegalStateException("pAssetBasePath must end with '/' or be lenght zero."); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static Font create(final Texture pTexture, final Typeface pTypeface, final float pSize, final boolean pAntiAlias, final int pColor) { + return new Font(pTexture, pTypeface, pSize, pAntiAlias, pColor); + } + + public static StrokeFont createStroke(final Texture pTexture, final Typeface pTypeface, final float pSize, final boolean pAntiAlias, final int pColor, final float pStrokeWidth, final int pStrokeColor) { + return new StrokeFont(pTexture, pTypeface, pSize, pAntiAlias, pColor, pStrokeWidth, pStrokeColor); + } + + public static StrokeFont createStroke(final Texture pTexture, final Typeface pTypeface, final float pSize, final boolean pAntiAlias, final int pColor, final float pStrokeWidth, final int pStrokeColor, final boolean pStrokeOnly) { + return new StrokeFont(pTexture, pTypeface, pSize, pAntiAlias, pColor, pStrokeWidth, pStrokeColor, pStrokeOnly); + } + + public static Font createFromAsset(final Texture pTexture, final Context pContext, final String pAssetPath, final float pSize, final boolean pAntiAlias, final int pColor) { + return new Font(pTexture, Typeface.createFromAsset(pContext.getAssets(), FontFactory.sAssetBasePath + pAssetPath), pSize, pAntiAlias, pColor); + } + + public static StrokeFont createStrokeFromAsset(final Texture pTexture, final Context pContext, final String pAssetPath, final float pSize, final boolean pAntiAlias, final int pColor, final float pStrokeWidth, final int pStrokeColor) { + return new StrokeFont(pTexture, Typeface.createFromAsset(pContext.getAssets(), FontFactory.sAssetBasePath + pAssetPath), pSize, pAntiAlias, pColor, pStrokeWidth, pStrokeColor); + } + + public static StrokeFont createStrokeFromAsset(final Texture pTexture, final Context pContext, final String pAssetPath, final float pSize, final boolean pAntiAlias, final int pColor, final float pStrokeWidth, final int pStrokeColor, final boolean pStrokeOnly) { + return new StrokeFont(pTexture, Typeface.createFromAsset(pContext.getAssets(), FontFactory.sAssetBasePath + pAssetPath), pSize, pAntiAlias, pColor, pStrokeWidth, pStrokeColor, pStrokeOnly); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/FontLibrary.java b/AndEngine/src/org/anddev/andengine/opengl/font/FontLibrary.java new file mode 100644 index 0000000..cede114 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/FontLibrary.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.opengl.font; + +import org.anddev.andengine.util.Library; + +import android.util.SparseArray; + +/** + * @author Nicolas Gramlich + * @since 11:52:26 - 20.08.2010 + */ +public class FontLibrary extends Library { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public FontLibrary() { + super(); + } + + public FontLibrary(final int pInitialCapacity) { + super(pInitialCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + void loadFonts(final FontManager pFontManager) { + final SparseArray items = this.mItems; + for(int i = items.size() - 1; i >= 0; i--) { + final Font font = items.valueAt(i); + if(font != null) { + pFontManager.loadFont(font); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/FontManager.java b/AndEngine/src/org/anddev/andengine/opengl/font/FontManager.java new file mode 100644 index 0000000..459c437 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/FontManager.java @@ -0,0 +1,80 @@ +package org.anddev.andengine.opengl.font; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL10; + + +/** + * @author Nicolas Gramlich + * @since 17:48:46 - 08.03.2010 + */ +public class FontManager { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mFontsManaged = new ArrayList(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void clear() { + this.mFontsManaged.clear(); + } + + public void loadFont(final Font pFont) { + if(pFont == null) { + throw new IllegalArgumentException("pFont must not be null!"); + } + this.mFontsManaged.add(pFont); + } + + public void loadFonts(final FontLibrary pFontLibrary) { + pFontLibrary.loadFonts(this); + } + + public void loadFonts(final Font ... pFonts) { + for(int i = pFonts.length - 1; i >= 0; i--) { + this.loadFont(pFonts[i]); + } + } + + public void updateFonts(final GL10 pGL) { + final ArrayList fonts = this.mFontsManaged; + final int fontCount = fonts.size(); + if(fontCount > 0){ + for(int i = fontCount - 1; i >= 0; i--){ + fonts.get(i).update(pGL); + } + } + } + + public void reloadFonts() { + final ArrayList managedFonts = this.mFontsManaged; + for(int i = managedFonts.size() - 1; i >= 0; i--) { + managedFonts.get(i).reload(); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/Letter.java b/AndEngine/src/org/anddev/andengine/opengl/font/Letter.java new file mode 100644 index 0000000..384be3a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/Letter.java @@ -0,0 +1,84 @@ +/** + * + */ +package org.anddev.andengine.opengl.font; + +/** + * @author Nicolas Gramlich + * @since 10:30:22 - 03.04.2010 + */ +public class Letter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public final int mAdvance; + public final int mWidth; + public final int mHeight; + public final float mTextureX; + public final float mTextureY; + public final float mTextureWidth; + public final float mTextureHeight; + public final char mCharacter; + + // =========================================================== + // Constructors + // =========================================================== + + Letter(final char pCharacter, final int pAdvance, final int pWidth, final int pHeight, final float pTextureX, final float pTextureY, final float pTextureWidth, final float pTextureHeight) { + this.mCharacter = pCharacter; + this.mAdvance = pAdvance; + this.mWidth = pWidth; + this.mHeight = pHeight; + this.mTextureX = pTextureX; + this.mTextureY = pTextureY; + this.mTextureWidth = pTextureWidth; + this.mTextureHeight = pTextureHeight; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + this.mCharacter; + return result; + } + + @Override + public boolean equals(final Object obj) { + if(this == obj) { + return true; + } + if(obj == null) { + return false; + } + if(this.getClass() != obj.getClass()) { + return false; + } + final Letter other = (Letter) obj; + if(this.mCharacter != other.mCharacter) { + return false; + } + return true; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/Size.java b/AndEngine/src/org/anddev/andengine/opengl/font/Size.java new file mode 100644 index 0000000..1fb60ea --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/Size.java @@ -0,0 +1,68 @@ +package org.anddev.andengine.opengl.font; + +/** + * @author Nicolas Gramlich + * @since 10:29:21 - 03.04.2010 + */ +class Size { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mWidth; + private float mHeight; + + // =========================================================== + // Constructors + // =========================================================== + + public Size() { + this(0, 0); + } + + public Size(final float pWidth, final float pHeight) { + this.setWidth(pWidth); + this.setHeight(pHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void setWidth(final float width) { + this.mWidth = width; + } + + public float getWidth() { + return this.mWidth; + } + + public void setHeight(final float height) { + this.mHeight = height; + } + + public float getHeight() { + return this.mHeight; + } + + public void set(final int pWidth, final int pHeight) { + this.setWidth(pWidth); + this.setHeight(pHeight); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/font/StrokeFont.java b/AndEngine/src/org/anddev/andengine/opengl/font/StrokeFont.java new file mode 100644 index 0000000..979bcaa --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/font/StrokeFont.java @@ -0,0 +1,69 @@ +package org.anddev.andengine.opengl.font; + +import org.anddev.andengine.opengl.texture.Texture; + +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.Typeface; + +/** + * @author Nicolas Gramlich + * @since 10:39:33 - 03.04.2010 + */ +public class StrokeFont extends Font { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Paint mStrokePaint; + private final boolean mStrokeOnly; + + // =========================================================== + // Constructors + // =========================================================== + + public StrokeFont(final Texture pTexture, final Typeface pTypeface, final float pSize, final boolean pAntiAlias, final int pColor, final float pStrokeWidth, final int pStrokeColor) { + this(pTexture, pTypeface, pSize, pAntiAlias, pColor, pStrokeWidth, pStrokeColor, false); + } + + public StrokeFont(final Texture pTexture, final Typeface pTypeface, final float pSize, final boolean pAntiAlias, final int pColor, final float pStrokeWidth, final int pStrokeColor, final boolean pStrokeOnly) { + super(pTexture, pTypeface, pSize, pAntiAlias, pColor); + this.mStrokePaint = new Paint(); + this.mStrokePaint.setTypeface(pTypeface); + this.mStrokePaint.setStyle(Style.STROKE); + this.mStrokePaint.setStrokeWidth(pStrokeWidth); + this.mStrokePaint.setColor(pStrokeColor); + this.mStrokePaint.setTextSize(pSize); + this.mStrokePaint.setAntiAlias(pAntiAlias); + + this.mStrokeOnly = pStrokeOnly; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void drawCharacterString(final String pCharacterAsString) { + if(this.mStrokeOnly == false) { + super.drawCharacterString(pCharacterAsString); + } + this.mCanvas.drawText(pCharacterAsString, LETTER_LEFT_OFFSET, -this.mFontMetrics.ascent, this.mStrokePaint); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/BuildableTexture.java b/AndEngine/src/org/anddev/andengine/opengl/texture/BuildableTexture.java new file mode 100644 index 0000000..34f5301 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/BuildableTexture.java @@ -0,0 +1,206 @@ +package org.anddev.andengine.opengl.texture; + +import java.util.ArrayList; + +import org.anddev.andengine.opengl.texture.builder.ITextureBuilder; +import org.anddev.andengine.opengl.texture.builder.ITextureBuilder.TextureSourcePackingException; +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.util.Callback; + +import android.graphics.Bitmap; + +/** + * @author Nicolas Gramlich + * @since 21:26:38 - 12.08.2010 + */ +public class BuildableTexture extends Texture { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mTextureSourcesToPlace = new ArrayList(); + + // =========================================================== + // Constructors + // =========================================================== + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + */ + public BuildableTexture(final int pWidth, final int pHeight) { + super(pWidth, pHeight, TextureOptions.DEFAULT, null); + } + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pTextureStateListener to be informed when this {@link BuildableTexture} is loaded, unloaded or a {@link ITextureSource} failed to load. + */ + public BuildableTexture(final int pWidth, final int pHeight, final ITextureStateListener pTextureStateListener) { + super(pWidth, pHeight, TextureOptions.DEFAULT, pTextureStateListener); + } + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pTextureOptions the (quality) settings of the Texture. + */ + public BuildableTexture(final int pWidth, final int pHeight, final TextureOptions pTextureOptions) throws IllegalArgumentException { + super(pWidth, pHeight, pTextureOptions, null); + } + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pTextureOptions the (quality) settings of the Texture. + * @param pTextureStateListener to be informed when this {@link BuildableTexture} is loaded, unloaded or a {@link ITextureSource} failed to load. + */ + public BuildableTexture(final int pWidth, final int pHeight, final TextureOptions pTextureOptions, final ITextureStateListener pTextureStateListener) throws IllegalArgumentException { + super(pWidth, pHeight, pTextureOptions, pTextureStateListener); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + /** + * Most likely this is not the method you'd want to be using, as the {@link ITextureSource} won't get packed through this. + * @deprecated Use {@link BuildableTexture#addTextureSource(ITextureSource)} instead. + */ + @Deprecated + @Override + public TextureSourceWithLocation addTextureSource(final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY) { + return super.addTextureSource(pTextureSource, pTexturePositionX, pTexturePositionY); + } + + @Override + public void clearTextureSources() { + super.clearTextureSources(); + this.mTextureSourcesToPlace.clear(); + } + + // =========================================================== + // Methods + // =========================================================== + + /** + * When all {@link ITextureSource}s are added you have to call {@link BuildableTexture#build(ITextureBuilder)}. + * @param pTextureSource to be added. + * @param pTextureRegion + */ + public void addTextureSource(final ITextureSource pTextureSource, final Callback pCallback) { + this.mTextureSourcesToPlace.add(new TextureSourceWithWithLocationCallback(pTextureSource, pCallback)); + } + + /** + * Removes a {@link ITextureSource} before {@link BuildableTexture#build(ITextureBuilder)} is called. + * @param pTextureSource to be removed. + */ + public void removeTextureSource(final ITextureSource pTextureSource) { + final ArrayList textureSources = this.mTextureSourcesToPlace; + for(int i = textureSources.size() - 1; i >= 0; i--) { + final TextureSourceWithWithLocationCallback textureSource = textureSources.get(i); + if(textureSource.mTextureSource == pTextureSource) { + textureSources.remove(i); + this.mUpdateOnHardwareNeeded = true; + return; + } + } + } + + /** + * May draw over already added {@link ITextureSource}s. + * + * @param pTextureSourcePackingAlgorithm the {@link ITextureBuilder} to use for packing the {@link ITextureSource} in this {@link BuildableTexture}. + * @throws TextureSourcePackingException i.e. when the {@link ITextureSource}s didn't fit into this {@link BuildableTexture}. + */ + public void build(final ITextureBuilder pTextureSourcePackingAlgorithm) throws TextureSourcePackingException { + pTextureSourcePackingAlgorithm.pack(this, this.mTextureSourcesToPlace); + this.mTextureSourcesToPlace.clear(); + this.mUpdateOnHardwareNeeded = true; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class TextureSourceWithWithLocationCallback implements ITextureSource { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ITextureSource mTextureSource; + private final Callback mCallback; + + // =========================================================== + // Constructors + // =========================================================== + + public TextureSourceWithWithLocationCallback(final ITextureSource pTextureSource, final Callback pCallback) { + this.mTextureSource = pTextureSource; + this.mCallback = pCallback; + } + + @Override + public TextureSourceWithWithLocationCallback clone() { + return null; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Callback getCallback() { + return this.mCallback; + } + + public ITextureSource getTextureSource() { + return this.mTextureSource; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int getWidth() { + return this.mTextureSource.getWidth(); + } + + @Override + public int getHeight() { + return this.mTextureSource.getHeight(); + } + + @Override + public Bitmap onLoadBitmap() { + return this.mTextureSource.onLoadBitmap(); + } + + @Override + public String toString() { + return this.mTextureSource.toString(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/Texture.java b/AndEngine/src/org/anddev/andengine/opengl/texture/Texture.java new file mode 100644 index 0000000..eb31c93 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/Texture.java @@ -0,0 +1,380 @@ +package org.anddev.andengine.opengl.texture; + +import java.util.ArrayList; + +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.MathUtils; + +import android.graphics.Bitmap; +import android.opengl.GLUtils; + +/** + * @author Nicolas Gramlich + * @since 14:55:02 - 08.03.2010 + */ +public class Texture { + // =========================================================== + // Constants + // =========================================================== + + private static final int[] HARDWARETEXTUREID_FETCHER = new int[1]; + + // =========================================================== + // Fields + // =========================================================== + + private final int mWidth; + private final int mHeight; + + private boolean mLoadedToHardware; + private int mHardwareTextureID = -1; + private final TextureOptions mTextureOptions; + + private final ArrayList mTextureSources = new ArrayList(); + + private final ITextureStateListener mTextureStateListener; + + protected boolean mUpdateOnHardwareNeeded = false; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + */ + public Texture(final int pWidth, final int pHeight) { + this(pWidth, pHeight, TextureOptions.DEFAULT, null); + } + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pTextureStateListener to be informed when this {@link Texture} is loaded, unloaded or a {@link ITextureSource} failed to load. + */ + public Texture(final int pWidth, final int pHeight, final ITextureStateListener pTextureStateListener) { + this(pWidth, pHeight, TextureOptions.DEFAULT, pTextureStateListener); + } + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pTextureOptions the (quality) settings of the Texture. + */ + public Texture(final int pWidth, final int pHeight, final TextureOptions pTextureOptions) throws IllegalArgumentException { + this(pWidth, pHeight, pTextureOptions, null); + } + + /** + * @param pWidth must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pHeight must be a power of 2 (i.e. 32, 64, 128, 256, 512, 1024). + * @param pTextureOptions the (quality) settings of the Texture. + * @param pTextureStateListener to be informed when this {@link Texture} is loaded, unloaded or a {@link ITextureSource} failed to load. + */ + public Texture(final int pWidth, final int pHeight, final TextureOptions pTextureOptions, final ITextureStateListener pTextureStateListener) throws IllegalArgumentException { + if (!MathUtils.isPowerOfTwo(pWidth) || !MathUtils.isPowerOfTwo(pHeight)){ + throw new IllegalArgumentException("pWidth and pHeight must be a power of 2!"); + } + + this.mWidth = pWidth; + this.mHeight = pHeight; + this.mTextureOptions = pTextureOptions; + this.mTextureStateListener = pTextureStateListener; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getHardwareTextureID() { + return this.mHardwareTextureID; + } + + public boolean isLoadedToHardware() { + return this.mLoadedToHardware; + } + + public boolean isUpdateOnHardwareNeeded() { + return this.mUpdateOnHardwareNeeded; + } + + void setLoadedToHardware(final boolean pLoadedToHardware) { + this.mLoadedToHardware = pLoadedToHardware; + } + + public int getWidth() { + return this.mWidth; + } + + public int getHeight() { + return this.mHeight; + } + + public TextureOptions getTextureOptions() { + return this.mTextureOptions; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public TextureSourceWithLocation addTextureSource(final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY) throws IllegalArgumentException { + this.checkTextureSourcePosition(pTextureSource, pTexturePositionX, pTexturePositionY); + + final TextureSourceWithLocation textureSourceWithLocation = new TextureSourceWithLocation(pTextureSource, pTexturePositionX, pTexturePositionY); + this.mTextureSources.add(textureSourceWithLocation); + this.mUpdateOnHardwareNeeded = true; + return textureSourceWithLocation; + } + + private void checkTextureSourcePosition(final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY) throws IllegalArgumentException { + if(pTexturePositionX < 0) { + throw new IllegalArgumentException("Illegal negative pTexturePositionX supplied: '" + pTexturePositionX + "'"); + } else if(pTexturePositionY < 0) { + throw new IllegalArgumentException("Illegal negative pTexturePositionY supplied: '" + pTexturePositionY + "'"); + } else if(pTexturePositionX + pTextureSource.getWidth() > this.mWidth || pTexturePositionY + pTextureSource.getHeight() > this.mHeight) { + throw new IllegalArgumentException("Supplied pTextureSource must not exceed bounds of Texture."); + } + } + + public void removeTextureSource(final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY) { + final ArrayList textureSources = this.mTextureSources; + for(int i = textureSources.size() - 1; i >= 0; i--) { + final TextureSourceWithLocation textureSourceWithLocation = textureSources.get(i); + if(textureSourceWithLocation.mTextureSource == pTextureSource && textureSourceWithLocation.mTexturePositionX == pTexturePositionX && textureSourceWithLocation.mTexturePositionY == pTexturePositionY) { + textureSources.remove(i); + this.mUpdateOnHardwareNeeded = true; + return; + } + } + } + + public void clearTextureSources() { + this.mTextureSources.clear(); + this.mUpdateOnHardwareNeeded = true; + } + + public void loadToHardware(final GL10 pGL) { + GLHelper.enableTextures(pGL); + + this.mHardwareTextureID = Texture.generateHardwareTextureID(pGL); + + this.allocateAndBindTextureOnHardware(pGL); + + this.applyTextureOptions(pGL); + + this.writeTextureToHardware(pGL); + + this.mUpdateOnHardwareNeeded = false; + this.mLoadedToHardware = true; + + if(this.mTextureStateListener != null) { + this.mTextureStateListener.onLoadedToHardware(this); + } + } + + public void unloadFromHardware(final GL10 pGL) { + GLHelper.enableTextures(pGL); + + this.deleteTextureOnHardware(pGL); + + this.mHardwareTextureID = -1; + + this.mLoadedToHardware = false; + + if(this.mTextureStateListener != null) { + this.mTextureStateListener.onUnloadedFromHardware(this); + } + } + + private void writeTextureToHardware(final GL10 pGL) { + final boolean preMultipyAlpha = this.mTextureOptions.mPreMultipyAlpha; + + final ArrayList textureSources = this.mTextureSources; + final int textureSourceCount = textureSources.size(); + + for(int j = 0; j < textureSourceCount; j++) { + final TextureSourceWithLocation textureSourceWithLocation = textureSources.get(j); + if(textureSourceWithLocation != null) { + final Bitmap bmp = textureSourceWithLocation.onLoadBitmap(); + try{ + if(bmp == null) { + throw new IllegalArgumentException("TextureSource: " + textureSourceWithLocation.toString() + " returned a null Bitmap."); + } + if(preMultipyAlpha) { + GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, textureSourceWithLocation.getTexturePositionX(), textureSourceWithLocation.getTexturePositionY(), bmp, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE); + } else { + GLHelper.glTexSubImage2D(pGL, GL10.GL_TEXTURE_2D, 0, textureSourceWithLocation.getTexturePositionX(), textureSourceWithLocation.getTexturePositionY(), bmp, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE); + } + + bmp.recycle(); + } catch (final IllegalArgumentException iae) { + // TODO Load some static checkerboard or so to visualize that loading the texture has failed. + Debug.e("Error loading: " + textureSourceWithLocation.toString(), iae); + if(this.mTextureStateListener != null) { + this.mTextureStateListener.onTextureSourceLoadExeption(this, textureSourceWithLocation.mTextureSource, iae); + } else { + throw iae; + } + } + } + } + } + + private void applyTextureOptions(final GL10 pGL) { + final TextureOptions textureOptions = this.mTextureOptions; + pGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, textureOptions.mMinFilter); + pGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, textureOptions.mMagFilter); + pGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, textureOptions.mWrapS); + pGL.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, textureOptions.mWrapT); + pGL.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, textureOptions.mTextureEnvironment); + } + + private void allocateAndBindTextureOnHardware(final GL10 pGL) { + GLHelper.bindTexture(pGL, this.mHardwareTextureID); + + Texture.sendPlaceholderBitmapToHardware(this.mWidth, this.mHeight); + } + + private void deleteTextureOnHardware(final GL10 pGL) { + GLHelper.deleteTexture(pGL, this.mHardwareTextureID); + } + + private static int generateHardwareTextureID(final GL10 pGL) { + pGL.glGenTextures(1, Texture.HARDWARETEXTUREID_FETCHER, 0); + + return Texture.HARDWARETEXTUREID_FETCHER[0]; + } + + private static void sendPlaceholderBitmapToHardware(final int pWidth, final int pHeight) { + final Bitmap textureBitmap = Bitmap.createBitmap(pWidth, pHeight, Bitmap.Config.ARGB_8888); + + GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, textureBitmap, 0); + + textureBitmap.recycle(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface ITextureStateListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onLoadedToHardware(final Texture pTexture); + public void onTextureSourceLoadExeption(final Texture pTexture, final ITextureSource pTextureSource, final Throwable pThrowable); + public void onUnloadedFromHardware(final Texture pTexture); + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class TextureStateAdapter implements ITextureStateListener { + @Override + public void onLoadedToHardware(final Texture pTexture) { } + + @Override + public void onTextureSourceLoadExeption(final Texture pTexture, final ITextureSource pTextureSource, final Throwable pThrowable) { } + + @Override + public void onUnloadedFromHardware(final Texture pTexture) { } + } + + public static class DebugTextureStateListener implements ITextureStateListener { + @Override + public void onLoadedToHardware(final Texture pTexture) { + Debug.d("Texture loaded: " + pTexture.toString()); + } + + @Override + public void onTextureSourceLoadExeption(final Texture pTexture, final ITextureSource pTextureSource, final Throwable pThrowable) { + Debug.e("Exception loading TextureSource. Texture: " + pTexture.toString() + " TextureSource: " + pTextureSource.toString(), pThrowable); + } + + @Override + public void onUnloadedFromHardware(final Texture pTexture) { + Debug.d("Texture unloaded: " + pTexture.toString()); + } + } + } + + public static class TextureSourceWithLocation { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ITextureSource mTextureSource; + private final int mTexturePositionX; + private final int mTexturePositionY; + + // =========================================================== + // Constructors + // =========================================================== + + public TextureSourceWithLocation(final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY) { + this.mTextureSource = pTextureSource; + this.mTexturePositionX = pTexturePositionX; + this.mTexturePositionY = pTexturePositionY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getTexturePositionX() { + return this.mTexturePositionX; + } + + public int getTexturePositionY() { + return this.mTexturePositionY; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public int getWidth() { + return this.mTextureSource.getWidth(); + } + + public int getHeight() { + return this.mTextureSource.getHeight(); + } + + public Bitmap onLoadBitmap() { + return this.mTextureSource.onLoadBitmap(); + } + + @Override + public String toString() { + return this.mTextureSource.toString(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/TextureFactory.java b/AndEngine/src/org/anddev/andengine/opengl/texture/TextureFactory.java new file mode 100644 index 0000000..816337a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/TextureFactory.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.opengl.texture; + +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.util.MathUtils; + +/** + * @author Nicolas Gramlich + * @since 09:38:51 - 03.05.2010 + */ +public class TextureFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public static Texture createForTextureSourceSize(final TextureRegion pTextureRegion) { + return TextureFactory.createForTextureRegionSize(pTextureRegion, TextureOptions.DEFAULT); + } + + public static Texture createForTextureRegionSize(final TextureRegion pTextureRegion, final TextureOptions pTextureOptions) { + final int loadingScreenWidth = pTextureRegion.getWidth(); + final int loadingScreenHeight = pTextureRegion.getHeight(); + return new Texture(MathUtils.nextPowerOfTwo(loadingScreenWidth), MathUtils.nextPowerOfTwo(loadingScreenHeight), pTextureOptions); + } + + public static Texture createForTextureSourceSize(final ITextureSource pTextureSource) { + return TextureFactory.createForTextureSourceSize(pTextureSource, TextureOptions.DEFAULT); + } + + public static Texture createForTextureSourceSize(final ITextureSource pTextureSource, final TextureOptions pTextureOptions) { + final int loadingScreenWidth = pTextureSource.getWidth(); + final int loadingScreenHeight = pTextureSource.getHeight(); + return new Texture(MathUtils.nextPowerOfTwo(loadingScreenWidth), MathUtils.nextPowerOfTwo(loadingScreenHeight), pTextureOptions); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/TextureManager.java b/AndEngine/src/org/anddev/andengine/opengl/texture/TextureManager.java new file mode 100644 index 0000000..fe81247 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/TextureManager.java @@ -0,0 +1,165 @@ +package org.anddev.andengine.opengl.texture; + +import java.util.ArrayList; +import java.util.HashSet; + +import javax.microedition.khronos.opengles.GL10; + +/** + * @author Nicolas Gramlich + * @since 17:48:46 - 08.03.2010 + */ +public class TextureManager { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final HashSet mTexturesManaged = new HashSet(); + + private final ArrayList mTexturesLoaded = new ArrayList(); + + private final ArrayList mTexturesToBeLoaded = new ArrayList(); + private final ArrayList mTexturesToBeUnloaded = new ArrayList(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + protected void clear() { + this.mTexturesToBeLoaded.clear(); + this.mTexturesLoaded.clear(); + this.mTexturesManaged.clear(); + } + + /** + * @param pTexture the {@link Texture} to be loaded before the very next frame is drawn (Or prevent it from being unloaded then). + * @return true when the {@link Texture} was previously not managed by this {@link TextureManager}, false if it was already managed. + */ + public boolean loadTexture(final Texture pTexture) { + if(this.mTexturesManaged.contains(pTexture)) { + /* Just make sure it doesn't get deleted. */ + this.mTexturesToBeUnloaded.remove(pTexture); + return false; + } else { + this.mTexturesManaged.add(pTexture); + this.mTexturesToBeLoaded.add(pTexture); + return true; + } + } + + /** + * @param pTexture the {@link Texture} to be unloaded before the very next frame is drawn (Or prevent it from being loaded then). + * @return true when the {@link Texture} was already managed by this {@link TextureManager}, false if it was not managed. + */ + public boolean unloadTexture(final Texture pTexture) { + if(this.mTexturesManaged.contains(pTexture)) { + /* If the Texture is loaded, unload it. + * If the Texture is about to be loaded, stop it from being loaded. */ + if(this.mTexturesLoaded.contains(pTexture)){ + this.mTexturesToBeUnloaded.add(pTexture); + } else if(this.mTexturesToBeLoaded.remove(pTexture)){ + this.mTexturesManaged.remove(pTexture); + } + return true; + } else { + return false; + } + } + + public void loadTextures(final Texture ... pTextures) { + for(int i = pTextures.length - 1; i >= 0; i--) { + this.loadTexture(pTextures[i]); + } + } + + public void unloadTextures(final Texture ... pTextures) { + for(int i = pTextures.length - 1; i >= 0; i--) { + this.unloadTexture(pTextures[i]); + } + } + + public void reloadTextures() { + final HashSet managedTextures = this.mTexturesManaged; + for(final Texture texture : managedTextures) { // TODO Can the use of the iterator be avoided somehow? + texture.setLoadedToHardware(false); + } + + this.mTexturesToBeLoaded.addAll(this.mTexturesLoaded); // TODO Check if addAll uses iterator internally! + this.mTexturesLoaded.clear(); + + this.mTexturesManaged.removeAll(this.mTexturesToBeUnloaded); // TODO Check if removeAll uses iterator internally! + this.mTexturesToBeUnloaded.clear(); + } + + public void updateTextures(final GL10 pGL) { + final HashSet texturesManaged = this.mTexturesManaged; + final ArrayList texturesLoaded = this.mTexturesLoaded; + final ArrayList texturesToBeLoaded = this.mTexturesToBeLoaded; + final ArrayList texturesToBeUnloaded = this.mTexturesToBeUnloaded; + + /* First reload Textures that need to be updated. */ + final int textursLoadedCount = texturesLoaded.size(); + + if(textursLoadedCount > 0){ + for(int i = textursLoadedCount - 1; i >= 0; i--){ + final Texture textureToBeUpdated = texturesLoaded.get(i); + if(textureToBeUpdated.isUpdateOnHardwareNeeded()){ + textureToBeUpdated.unloadFromHardware(pGL); + textureToBeUpdated.loadToHardware(pGL); + } + } + } + + /* Then load pending Textures. */ + final int texturesToBeLoadedCount = texturesToBeLoaded.size(); + + if(texturesToBeLoadedCount > 0){ + for(int i = texturesToBeLoadedCount - 1; i >= 0; i--){ + final Texture textureToBeLoaded = texturesToBeLoaded.remove(i); + if(!textureToBeLoaded.isLoadedToHardware()){ + textureToBeLoaded.loadToHardware(pGL); + } + texturesLoaded.add(textureToBeLoaded); + } + } + + /* Then unload pending Textures. */ + final int texturesToBeUnloadedCount = texturesToBeUnloaded.size(); + + if(texturesToBeUnloadedCount > 0){ + for(int i = texturesToBeUnloadedCount - 1; i >= 0; i--){ + final Texture textureToBeUnloaded = texturesToBeUnloaded.remove(i); + if(textureToBeUnloaded.isLoadedToHardware()){ + textureToBeUnloaded.unloadFromHardware(pGL); + } + texturesLoaded.remove(textureToBeUnloaded); + texturesManaged.remove(textureToBeUnloaded); + } + } + + /* Finally invoke the GC if anything has changed. */ + if(texturesToBeLoadedCount > 0 || texturesToBeUnloadedCount > 0){ + System.gc(); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/TextureOptions.java b/AndEngine/src/org/anddev/andengine/opengl/texture/TextureOptions.java new file mode 100644 index 0000000..786aff6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/TextureOptions.java @@ -0,0 +1,65 @@ +package org.anddev.andengine.opengl.texture; + +import javax.microedition.khronos.opengles.GL10; + +/** + * @author Nicolas Gramlich + * @since 13:00:09 - 05.04.2010 + */ +public class TextureOptions { + // =========================================================== + // Constants + // =========================================================== + + public static final TextureOptions NEAREST = new TextureOptions(GL10.GL_NEAREST, GL10.GL_NEAREST, GL10.GL_CLAMP_TO_EDGE, GL10.GL_CLAMP_TO_EDGE, GL10.GL_MODULATE, false); + public static final TextureOptions BILINEAR = new TextureOptions(GL10.GL_LINEAR, GL10.GL_LINEAR, GL10.GL_CLAMP_TO_EDGE, GL10.GL_CLAMP_TO_EDGE, GL10.GL_MODULATE, false); + public static final TextureOptions REPEATING = new TextureOptions(GL10.GL_NEAREST, GL10.GL_NEAREST, GL10.GL_REPEAT, GL10.GL_REPEAT, GL10.GL_MODULATE, false); + public static final TextureOptions REPEATING_BILINEAR = new TextureOptions(GL10.GL_LINEAR, GL10.GL_LINEAR, GL10.GL_REPEAT, GL10.GL_REPEAT, GL10.GL_MODULATE, false); + + public static final TextureOptions NEAREST_PREMULTIPLYALPHA = new TextureOptions(GL10.GL_NEAREST, GL10.GL_NEAREST, GL10.GL_CLAMP_TO_EDGE, GL10.GL_CLAMP_TO_EDGE, GL10.GL_MODULATE, true); + public static final TextureOptions BILINEAR_PREMULTIPLYALPHA = new TextureOptions(GL10.GL_LINEAR, GL10.GL_LINEAR, GL10.GL_CLAMP_TO_EDGE, GL10.GL_CLAMP_TO_EDGE, GL10.GL_MODULATE, true); + public static final TextureOptions REPEATING_PREMULTIPLYALPHA = new TextureOptions(GL10.GL_NEAREST, GL10.GL_NEAREST, GL10.GL_REPEAT, GL10.GL_REPEAT, GL10.GL_MODULATE, true); + public static final TextureOptions REPEATING_BILINEAR_PREMULTIPLYALPHA = new TextureOptions(GL10.GL_LINEAR, GL10.GL_LINEAR, GL10.GL_REPEAT, GL10.GL_REPEAT, GL10.GL_MODULATE, true); + + public static final TextureOptions DEFAULT = NEAREST_PREMULTIPLYALPHA; + + // =========================================================== + // Fields + // =========================================================== + + public final int mMagFilter; + public final int mMinFilter; + public final float mWrapT; + public final float mWrapS; + public final int mTextureEnvironment; + public final boolean mPreMultipyAlpha; + + // =========================================================== + // Constructors + // =========================================================== + + public TextureOptions(final int pMinFilter, final int pMagFilter, final int pWrapT, final int pWrapS, final int pTextureEnvironment, final boolean pPreMultiplyAlpha) { + this.mMinFilter = pMinFilter; + this.mMagFilter = pMagFilter; + this.mWrapT = pWrapT; + this.mWrapS = pWrapS; + this.mTextureEnvironment = pTextureEnvironment; + this.mPreMultipyAlpha = pPreMultiplyAlpha; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/buffer/TextTextureBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/texture/buffer/TextTextureBuffer.java new file mode 100644 index 0000000..d95695b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/buffer/TextTextureBuffer.java @@ -0,0 +1,88 @@ +package org.anddev.andengine.opengl.texture.buffer; + +import org.anddev.andengine.opengl.buffer.BufferObject; +import org.anddev.andengine.opengl.font.Font; +import org.anddev.andengine.opengl.font.Letter; +import org.anddev.andengine.opengl.util.FastFloatBuffer; + +/** + * @author Nicolas Gramlich + * @since 11:05:56 - 03.04.2010 + */ +public class TextTextureBuffer extends BufferObject { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TextTextureBuffer(final int pCapacity, final int pDrawType) { + super(pCapacity, pDrawType); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void update(final Font pFont, final String[] pLines) { + final FastFloatBuffer textureFloatBuffer = this.getFloatBuffer(); + textureFloatBuffer.position(0); + + final Font font = pFont; + final String[] lines = pLines; + + final int lineCount = lines.length; + for (int i = 0; i < lineCount; i++) { + final String line = lines[i]; + + final int lineLength = line.length(); + for (int j = 0; j < lineLength; j++) { + final Letter letter = font.getLetter(line.charAt(j)); + + final float letterTextureX = letter.mTextureX; + final float letterTextureY = letter.mTextureY; + final float letterTextureX2 = letterTextureX + letter.mTextureWidth; + final float letterTextureY2 = letterTextureY + letter.mTextureHeight; + + textureFloatBuffer.put(letterTextureX); + textureFloatBuffer.put(letterTextureY); + + textureFloatBuffer.put(letterTextureX); + textureFloatBuffer.put(letterTextureY2); + + textureFloatBuffer.put(letterTextureX2); + textureFloatBuffer.put(letterTextureY2); + + textureFloatBuffer.put(letterTextureX2); + textureFloatBuffer.put(letterTextureY2); + + textureFloatBuffer.put(letterTextureX2); + textureFloatBuffer.put(letterTextureY); + + textureFloatBuffer.put(letterTextureX); + textureFloatBuffer.put(letterTextureY); + } + } + textureFloatBuffer.position(0); + + this.setHardwareBufferNeedsUpdate(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/builder/BlackPawnTextureBuilder.java b/AndEngine/src/org/anddev/andengine/opengl/texture/builder/BlackPawnTextureBuilder.java new file mode 100644 index 0000000..8caf801 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/builder/BlackPawnTextureBuilder.java @@ -0,0 +1,324 @@ +package org.anddev.andengine.opengl.texture.builder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +import org.anddev.andengine.opengl.texture.BuildableTexture; +import org.anddev.andengine.opengl.texture.BuildableTexture.TextureSourceWithWithLocationCallback; +import org.anddev.andengine.opengl.texture.Texture.TextureSourceWithLocation; +import org.anddev.andengine.opengl.texture.source.ITextureSource; + +/** + * @author Nicolas Gramlich + * @since 16:03:01 - 12.08.2010 + * @see http://www.blackpawn.com/texts/lightmaps/default.html + */ +public class BlackPawnTextureBuilder implements ITextureBuilder { + // =========================================================== + // Constants + // =========================================================== + + private static final Comparator TEXTURESOURCE_COMPARATOR = new Comparator() { + @Override + public int compare(final ITextureSource pTextureSourceA, final ITextureSource pTextureSourceB) { + final int deltaWidth = pTextureSourceB.getWidth() - pTextureSourceA.getWidth(); + if(deltaWidth != 0) { + return deltaWidth; + } else { + return pTextureSourceB.getHeight() - pTextureSourceA.getHeight(); + } + } + }; + + // =========================================================== + // Fields + // =========================================================== + + private final int mTextureSourceSpacing; + + // =========================================================== + // Constructors + // =========================================================== + + public BlackPawnTextureBuilder(final int pTextureSourceSpacing) { + this.mTextureSourceSpacing = pTextureSourceSpacing; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @SuppressWarnings("deprecation") + @Override + public void pack(final BuildableTexture pBuildableTexture, final ArrayList pTextureSourcesWithLocationCallback) throws IllegalArgumentException { + Collections.sort(pTextureSourcesWithLocationCallback, TEXTURESOURCE_COMPARATOR); + + final Node root = new Node(new Rect(0, 0, pBuildableTexture.getWidth(), pBuildableTexture.getHeight())); + + final int textureSourceCount = pTextureSourcesWithLocationCallback.size(); + + for(int i = 0; i < textureSourceCount; i++) { + final TextureSourceWithWithLocationCallback textureSourceWithLocationCallback = pTextureSourcesWithLocationCallback.get(i); + final ITextureSource textureSource = textureSourceWithLocationCallback.getTextureSource(); + + final Node inserted = root.insert(textureSource, pBuildableTexture.getWidth(), pBuildableTexture.getHeight(), this.mTextureSourceSpacing); + + if(inserted == null) { + throw new IllegalArgumentException("Could not pack: " + textureSource.toString()); + } + final TextureSourceWithLocation textureSourceWithLocation = pBuildableTexture.addTextureSource(textureSource, inserted.mRect.mLeft, inserted.mRect.mTop); + textureSourceWithLocationCallback.getCallback().onCallback(textureSourceWithLocation); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + protected static class Rect { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mLeft; + private final int mTop; + private final int mWidth; + private final int mHeight; + + // =========================================================== + // Constructors + // =========================================================== + + public Rect(final int pLeft, final int pTop, final int pWidth, final int pHeight) { + this.mLeft = pLeft; + this.mTop = pTop; + this.mWidth = pWidth; + this.mHeight = pHeight; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getWidth() { + return this.mWidth; + } + + public int getHeight() { + return this.mHeight; + } + + public int getLeft() { + return this.mLeft; + } + + public int getTop() { + return this.mTop; + } + + public int getRight() { + return this.mLeft + this.mWidth; + } + + public int getBottom() { + return this.mTop + this.mHeight; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public String toString() { + return "@: " + this.mLeft + "/" + this.mTop + " * " + this.mWidth + "x" + this.mHeight; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } + + protected static class Node { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private Node mChildA; + private Node mChildB; + private final Rect mRect; + private ITextureSource mTextureSource; + + // =========================================================== + // Constructors + // =========================================================== + + public Node(final int pLeft, final int pTop, final int pWidth, final int pHeight) { + this(new Rect(pLeft, pTop, pWidth, pHeight)); + } + + public Node(final Rect pRect) { + this.mRect = pRect; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Rect getRect() { + return this.mRect; + } + + public Node getChildA() { + return this.mChildA; + } + + public Node getChildB() { + return this.mChildB; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public Node insert(final ITextureSource pTextureSource, final int pTextureWidth, final int pTextureHeight, final int pTextureSpacing) throws IllegalArgumentException { + if(this.mChildA != null && this.mChildB != null) { + final Node newNode = this.mChildA.insert(pTextureSource, pTextureWidth, pTextureHeight, pTextureSpacing); + if(newNode != null){ + return newNode; + } else { + return this.mChildB.insert(pTextureSource, pTextureWidth, pTextureHeight, pTextureSpacing); + } + } else { + if(this.mTextureSource != null) { + return null; + } + + final int textureSourceWidth = pTextureSource.getWidth(); + final int textureSourceHeight = pTextureSource.getHeight(); + + final int rectWidth = this.mRect.getWidth(); + final int rectHeight = this.mRect.getHeight(); + + if(textureSourceWidth > rectWidth || textureSourceHeight > rectHeight) { + return null; + } + + final int textureSourceWidthWithSpacing = textureSourceWidth + pTextureSpacing; + final int textureSourceHeightWithSpacing = textureSourceHeight + pTextureSpacing; + + final int rectLeft = this.mRect.getLeft(); + final int rectTop = this.mRect.getTop(); + + final boolean fitToBottomWithoutSpacing = textureSourceHeight == rectHeight && rectTop + textureSourceHeight == pTextureHeight; + final boolean fitToRightWithoutSpacing = textureSourceWidth == rectWidth && rectLeft + textureSourceWidth == pTextureWidth; + + if(textureSourceWidthWithSpacing == rectWidth){ + if(textureSourceHeightWithSpacing == rectHeight) { /* Normal case with padding. */ + this.mTextureSource = pTextureSource; + return this; + } else if(fitToBottomWithoutSpacing) { /* Bottom edge of the Texture. */ + this.mTextureSource = pTextureSource; + return this; + } + } + + if(fitToRightWithoutSpacing) { /* Right edge of the Texture. */ + if(textureSourceHeightWithSpacing == rectHeight) { + this.mTextureSource = pTextureSource; + return this; + } else if(fitToBottomWithoutSpacing) { /* Bottom edge of the Texture. */ + this.mTextureSource = pTextureSource; + return this; + } else if(textureSourceHeightWithSpacing > rectHeight) { + return null; + } else { + + return this.createChildren(pTextureSource, pTextureWidth, pTextureHeight, pTextureSpacing, rectWidth - textureSourceWidth, rectHeight - textureSourceHeightWithSpacing); + } + } + + if(fitToBottomWithoutSpacing) { + if(textureSourceWidthWithSpacing == rectWidth) { + this.mTextureSource = pTextureSource; + return this; + } else if(textureSourceWidthWithSpacing > rectWidth) { + return null; + } else { + return this.createChildren(pTextureSource, pTextureWidth, pTextureHeight, pTextureSpacing, rectWidth - textureSourceWidthWithSpacing, rectHeight - textureSourceHeight); + } + } else if(textureSourceWidthWithSpacing > rectWidth || textureSourceHeightWithSpacing > rectHeight) { + return null; + } else { + return this.createChildren(pTextureSource, pTextureWidth, pTextureHeight, pTextureSpacing, rectWidth - textureSourceWidthWithSpacing, rectHeight - textureSourceHeightWithSpacing); + } + } + } + + private Node createChildren(final ITextureSource pTextureSource, final int pTextureWidth, final int pTextureHeight, final int pTextureSpacing, final int pDeltaWidth, final int pDeltaHeight) { + final Rect rect = this.mRect; + + if(pDeltaWidth >= pDeltaHeight) { + /* Split using a vertical axis. */ + this.mChildA = new Node( + rect.getLeft(), + rect.getTop(), + pTextureSource.getWidth() + pTextureSpacing, + rect.getHeight() + ); + + this.mChildB = new Node( + rect.getLeft() + (pTextureSource.getWidth() + pTextureSpacing), + rect.getTop(), + rect.getWidth() - (pTextureSource.getWidth() + pTextureSpacing), + rect.getHeight() + ); + } else { + /* Split using a horizontal axis. */ + this.mChildA = new Node( + rect.getLeft(), + rect.getTop(), + rect.getWidth(), + pTextureSource.getHeight() + pTextureSpacing + ); + + this.mChildB = new Node( + rect.getLeft(), + rect.getTop() + (pTextureSource.getHeight() + pTextureSpacing), + rect.getWidth(), + rect.getHeight() - (pTextureSource.getHeight() + pTextureSpacing) + ); + } + + return this.mChildA.insert(pTextureSource, pTextureWidth, pTextureHeight, pTextureSpacing); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/builder/ITextureBuilder.java b/AndEngine/src/org/anddev/andengine/opengl/texture/builder/ITextureBuilder.java new file mode 100644 index 0000000..b2b8328 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/builder/ITextureBuilder.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.opengl.texture.builder; + +import java.util.ArrayList; + +import org.anddev.andengine.opengl.texture.BuildableTexture; +import org.anddev.andengine.opengl.texture.BuildableTexture.TextureSourceWithWithLocationCallback; + +/** + * @author Nicolas Gramlich + * @since 15:59:14 - 12.08.2010 + */ +public interface ITextureBuilder { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void pack(final BuildableTexture pBuildableTexture, final ArrayList pTextureSourcesWithLocationCallback) throws TextureSourcePackingException; + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class TextureSourcePackingException extends Exception { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 4700734424214372671L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } + +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/BaseTextureRegion.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/BaseTextureRegion.java new file mode 100644 index 0000000..ade50c0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/BaseTextureRegion.java @@ -0,0 +1,147 @@ +package org.anddev.andengine.opengl.texture.region; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.region.buffer.BaseTextureRegionBuffer; +import org.anddev.andengine.opengl.util.GLHelper; + +/** + * @author Nicolas Gramlich + * @since 14:29:59 - 08.03.2010 + */ +public abstract class BaseTextureRegion { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final Texture mTexture; + + protected final BaseTextureRegionBuffer mTextureRegionBuffer; + + protected int mWidth; + protected int mHeight; + + protected int mTexturePositionX; + protected int mTexturePositionY; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTextureRegion(final Texture pTexture, final int pTexturePositionX, final int pTexturePositionY, final int pWidth, final int pHeight) { + this.mTexture = pTexture; + this.mTexturePositionX = pTexturePositionX; + this.mTexturePositionY = pTexturePositionY; + this.mWidth = pWidth; + this.mHeight = pHeight; + + this.mTextureRegionBuffer = this.onCreateTextureRegionBuffer(); + + BufferObjectManager.getActiveInstance().loadBufferObject(this.mTextureRegionBuffer); + + this.initTextureBuffer(); + } + + protected void initTextureBuffer() { + this.updateTextureRegionBuffer(); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getWidth() { + return this.mWidth; + } + + public int getHeight() { + return this.mHeight; + } + + public void setWidth(final int pWidth) { + this.mWidth = pWidth; + this.updateTextureRegionBuffer(); + } + + public void setHeight(final int pHeight) { + this.mHeight = pHeight; + this.updateTextureRegionBuffer(); + } + + public void setTexturePosition(final int pX, final int pY) { + this.mTexturePositionX = pX; + this.mTexturePositionY = pY; + this.updateTextureRegionBuffer(); + } + + public int getTexturePositionX() { + return this.mTexturePositionX; + } + + public int getTexturePositionY() { + return this.mTexturePositionY; + } + + public Texture getTexture() { + return this.mTexture; + } + + public BaseTextureRegionBuffer getTextureBuffer() { + return this.mTextureRegionBuffer; + } + + public boolean isFlippedHorizontal() { + return this.mTextureRegionBuffer.isFlippedHorizontal(); + } + + public void setFlippedHorizontal(final boolean pFlippedHorizontal) { + this.mTextureRegionBuffer.setFlippedHorizontal(pFlippedHorizontal); + } + + public boolean isFlippedVertical() { + return this.mTextureRegionBuffer.isFlippedVertical(); + } + + public void setFlippedVertical(final boolean pFlippedVertical) { + this.mTextureRegionBuffer.setFlippedVertical(pFlippedVertical); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract BaseTextureRegionBuffer onCreateTextureRegionBuffer(); + + // =========================================================== + // Methods + // =========================================================== + + protected void updateTextureRegionBuffer() { + this.mTextureRegionBuffer.update(); + } + + public void onApply(final GL10 pGL) { + if(GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS) { + final GL11 gl11 = (GL11)pGL; + + this.mTextureRegionBuffer.selectOnHardware(gl11); + + GLHelper.bindTexture(pGL, this.mTexture.getHardwareTextureID()); + GLHelper.texCoordZeroPointer(gl11); + } else { + GLHelper.bindTexture(pGL, this.mTexture.getHardwareTextureID()); + GLHelper.texCoordPointer(pGL, this.mTextureRegionBuffer.getFloatBuffer()); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegion.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegion.java new file mode 100644 index 0000000..ac259a2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegion.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.opengl.texture.region; + +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.region.buffer.BaseTextureRegionBuffer; +import org.anddev.andengine.opengl.texture.region.buffer.TextureRegionBuffer; + +/** + * @author Nicolas Gramlich + * @since 14:29:59 - 08.03.2010 + */ +public class TextureRegion extends BaseTextureRegion { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TextureRegion(final Texture pTexture, final int pTexturePositionX, final int pTexturePositionY, final int pWidth, final int pHeight) { + super(pTexture, pTexturePositionX, pTexturePositionY, pWidth, pHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public TextureRegionBuffer getTextureBuffer() { + return (TextureRegionBuffer) this.mTextureRegionBuffer; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public TextureRegion clone() { + return new TextureRegion(this.mTexture, this.mTexturePositionX, this.mTexturePositionY, this.mWidth, this.mHeight); + } + + // =========================================================== + // Methods + // =========================================================== + + @Override + protected BaseTextureRegionBuffer onCreateTextureRegionBuffer() { + return new TextureRegionBuffer(this, GL11.GL_STATIC_DRAW); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegionFactory.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegionFactory.java new file mode 100644 index 0000000..ee26475 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegionFactory.java @@ -0,0 +1,150 @@ +package org.anddev.andengine.opengl.texture.region; + + +import org.anddev.andengine.opengl.texture.BuildableTexture; +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.Texture.TextureSourceWithLocation; +import org.anddev.andengine.opengl.texture.source.AssetTextureSource; +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.ResourceTextureSource; +import org.anddev.andengine.util.Callback; + +import android.content.Context; + + +/** + * @author Nicolas Gramlich + * @since 18:15:14 - 09.03.2010 + */ +public class TextureRegionFactory { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static String sAssetBasePath = ""; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * @param pAssetBasePath must end with '/' or have .length() == 0. + */ + public static void setAssetBasePath(final String pAssetBasePath) { + if(pAssetBasePath.endsWith("/") || pAssetBasePath.length() == 0) { + TextureRegionFactory.sAssetBasePath = pAssetBasePath; + } else { + throw new IllegalStateException("pAssetBasePath must end with '/' or be lenght zero."); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static TextureRegion extractFromTexture(final Texture pTexture, final int pTexturePositionX, final int pTexturePositionY, final int pWidth, final int pHeight) { + return new TextureRegion(pTexture, pTexturePositionX, pTexturePositionY, pWidth, pHeight); + } + + // =========================================================== + // Methods using Texture + // =========================================================== + + public static TextureRegion createFromAsset(final Texture pTexture, final Context pContext, final String pAssetPath, final int pTexturePositionX, final int pTexturePositionY) { + final ITextureSource textureSource = new AssetTextureSource(pContext, TextureRegionFactory.sAssetBasePath + pAssetPath); + return TextureRegionFactory.createFromSource(pTexture, textureSource, pTexturePositionX, pTexturePositionY); + } + + public static TiledTextureRegion createTiledFromAsset(final Texture pTexture, final Context pContext, final String pAssetPath, final int pTexturePositionX, final int pTexturePositionY, final int pTileColumns, final int pTileRows) { + final ITextureSource textureSource = new AssetTextureSource(pContext, TextureRegionFactory.sAssetBasePath + pAssetPath); + return TextureRegionFactory.createTiledFromSource(pTexture, textureSource, pTexturePositionX, pTexturePositionY, pTileColumns, pTileRows); + } + + + public static TextureRegion createFromResource(final Texture pTexture, final Context pContext, final int pDrawableResourceID, final int pTexturePositionX, final int pTexturePositionY) { + final ITextureSource textureSource = new ResourceTextureSource(pContext, pDrawableResourceID); + return TextureRegionFactory.createFromSource(pTexture, textureSource, pTexturePositionX, pTexturePositionY); + } + + public static TiledTextureRegion createTiledFromResource(final Texture pTexture, final Context pContext, final int pDrawableResourceID, final int pTexturePositionX, final int pTexturePositionY, final int pTileColumns, final int pTileRows) { + final ITextureSource textureSource = new ResourceTextureSource(pContext, pDrawableResourceID); + return TextureRegionFactory.createTiledFromSource(pTexture, textureSource, pTexturePositionX, pTexturePositionY, pTileColumns, pTileRows); + } + + + public static TextureRegion createFromSource(final Texture pTexture, final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY) { + final TextureRegion textureRegion = new TextureRegion(pTexture, pTexturePositionX, pTexturePositionY, pTextureSource.getWidth(), pTextureSource.getHeight()); + pTexture.addTextureSource(pTextureSource, textureRegion.getTexturePositionX(), textureRegion.getTexturePositionY()); + return textureRegion; + } + + public static TiledTextureRegion createTiledFromSource(final Texture pTexture, final ITextureSource pTextureSource, final int pTexturePositionX, final int pTexturePositionY, final int pTileColumns, final int pTileRows) { + final TiledTextureRegion tiledTextureRegion = new TiledTextureRegion(pTexture, pTexturePositionX, pTexturePositionY, pTextureSource.getWidth(), pTextureSource.getHeight(), pTileColumns, pTileRows); + pTexture.addTextureSource(pTextureSource, tiledTextureRegion.getTexturePositionX(), tiledTextureRegion.getTexturePositionY()); + return tiledTextureRegion; + } + + // =========================================================== + // Methods using BuildableTexture + // =========================================================== + + public static TextureRegion createFromAsset(final BuildableTexture pBuildableTexture, final Context pContext, final String pAssetPath) { + final ITextureSource textureSource = new AssetTextureSource(pContext, TextureRegionFactory.sAssetBasePath + pAssetPath); + return TextureRegionFactory.createFromSource(pBuildableTexture, textureSource); + } + + public static TiledTextureRegion createTiledFromAsset(final BuildableTexture pBuildableTexture, final Context pContext, final String pAssetPath, final int pTileColumns, final int pTileRows) { + final ITextureSource textureSource = new AssetTextureSource(pContext, TextureRegionFactory.sAssetBasePath + pAssetPath); + return TextureRegionFactory.createTiledFromSource(pBuildableTexture, textureSource, pTileColumns, pTileRows); + } + + + public static TextureRegion createFromResource(final BuildableTexture pBuildableTexture, final Context pContext, final int pDrawableResourceID) { + final ITextureSource textureSource = new ResourceTextureSource(pContext, pDrawableResourceID); + return TextureRegionFactory.createFromSource(pBuildableTexture, textureSource); + } + + public static TiledTextureRegion createTiledFromResource(final BuildableTexture pBuildableTexture, final Context pContext, final int pDrawableResourceID, final int pTileColumns, final int pTileRows) { + final ITextureSource textureSource = new ResourceTextureSource(pContext, pDrawableResourceID); + return TextureRegionFactory.createTiledFromSource(pBuildableTexture, textureSource, pTileColumns, pTileRows); + } + + + public static TextureRegion createFromSource(final BuildableTexture pBuildableTexture, final ITextureSource pTextureSource) { + final TextureRegion textureRegion = new TextureRegion(pBuildableTexture, 0, 0, pTextureSource.getWidth(), pTextureSource.getHeight()); + pBuildableTexture.addTextureSource(pTextureSource, new Callback() { + @Override + public void onCallback(final TextureSourceWithLocation pCallbackValue) { + textureRegion.setTexturePosition(pCallbackValue.getTexturePositionX(), pCallbackValue.getTexturePositionY()); + } + }); + return textureRegion; + } + + public static TiledTextureRegion createTiledFromSource(final BuildableTexture pBuildableTexture, final ITextureSource pTextureSource, final int pTileColumns, final int pTileRows) { + final TiledTextureRegion tiledTextureRegion = new TiledTextureRegion(pBuildableTexture, 0, 0, pTextureSource.getWidth(), pTextureSource.getHeight(), pTileColumns, pTileRows); + pBuildableTexture.addTextureSource(pTextureSource, new Callback() { + @Override + public void onCallback(final TextureSourceWithLocation pCallbackValue) { + tiledTextureRegion.setTexturePosition(pCallbackValue.getTexturePositionX(), pCallbackValue.getTexturePositionY()); + } + }); + return tiledTextureRegion; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegionLibrary.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegionLibrary.java new file mode 100644 index 0000000..47f3e8d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TextureRegionLibrary.java @@ -0,0 +1,54 @@ +package org.anddev.andengine.opengl.texture.region; + +import org.anddev.andengine.util.Library; + +/** + * @author Nicolas Gramlich + * @since 11:52:26 - 20.08.2010 + */ +public class TextureRegionLibrary extends Library { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TextureRegionLibrary() { + super(); + } + + public TextureRegionLibrary(final int pInitialCapacity) { + super(pInitialCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public TextureRegion get(final int pID) { + return (TextureRegion) super.get(pID); + } + + public TiledTextureRegion getTiled(final int pID) { + return (TiledTextureRegion) this.mItems.get(pID); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/TiledTextureRegion.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TiledTextureRegion.java new file mode 100644 index 0000000..a95aea2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/TiledTextureRegion.java @@ -0,0 +1,133 @@ +package org.anddev.andengine.opengl.texture.region; + +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.region.buffer.TiledTextureRegionBuffer; + +/** + * @author Nicolas Gramlich + * @since 18:14:42 - 09.03.2010 + */ +public class TiledTextureRegion extends BaseTextureRegion { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mTileColumns; + private final int mTileRows; + private int mCurrentTileColumn; + private int mCurrentTileRow; + private final int mTileCount; + + // =========================================================== + // Constructors + // =========================================================== + + public TiledTextureRegion(final Texture pTexture, final int pTexturePositionX, final int pTexturePositionY, final int pWidth, final int pHeight, final int pTileColumns, final int pTileRows) { + super(pTexture, pTexturePositionX, pTexturePositionY, pWidth, pHeight); + this.mTileColumns = pTileColumns; + this.mTileRows = pTileRows; + this.mTileCount = this.mTileColumns * this.mTileRows; + this.mCurrentTileColumn = 0; + this.mCurrentTileRow = 0; + + this.initTextureBuffer(); + } + + @Override + protected void initTextureBuffer() { + if(this.mTileRows != 0 && this.mTileColumns != 0) { + super.initTextureBuffer(); + } + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public TiledTextureRegionBuffer getTextureBuffer() { + return (TiledTextureRegionBuffer) this.mTextureRegionBuffer; + } + + public int getTileCount() { + return this.mTileCount; + } + + public int getTileWidth() { + return super.getWidth() / this.mTileColumns; + } + + public int getTileHeight() { + return super.getHeight() / this.mTileRows; + } + + public int getCurrentTileColumn() { + return this.mCurrentTileColumn; + } + + public int getCurrentTileRow() { + return this.mCurrentTileRow; + } + + public int getCurrentTileIndex() { + return this.mCurrentTileRow * this.mTileColumns + this.mCurrentTileColumn; + } + + public void setCurrentTileIndex(final int pTileColumn, final int pTileRow) { + if(pTileColumn != this.mCurrentTileColumn || pTileRow != this.mCurrentTileRow) { + this.mCurrentTileColumn = pTileColumn; + this.mCurrentTileRow = pTileRow; + super.updateTextureRegionBuffer(); + } + } + + public void setCurrentTileIndex(final int pTileIndex) { + if(pTileIndex < this.mTileCount) { + final int tileColumns = this.mTileColumns; + this.setCurrentTileIndex(pTileIndex % tileColumns, pTileIndex / tileColumns); + } + } + + public float getTexturePositionOfCurrentTileX() { + return super.getTexturePositionX() + this.mCurrentTileColumn * this.getTileWidth(); + } + + public float getTexturePositionOfCurrentTileY() { + return super.getTexturePositionY() + this.mCurrentTileRow * this.getTileHeight(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public TiledTextureRegion clone() { + final TiledTextureRegion clone = new TiledTextureRegion(this.mTexture, this.getTexturePositionX(), this.getTexturePositionY(), this.getWidth(), this.getHeight(), this.mTileColumns, this.mTileRows); + clone.setCurrentTileIndex(this.mCurrentTileColumn, this.mCurrentTileRow); + return clone; + } + + @Override + protected TiledTextureRegionBuffer onCreateTextureRegionBuffer() { + return new TiledTextureRegionBuffer(this, GL11.GL_STATIC_DRAW); + } + + // =========================================================== + // Methods + // =========================================================== + + public void nextTile() { + final int tileIndex = (this.getCurrentTileIndex() + 1) % this.getTileCount(); + this.setCurrentTileIndex(tileIndex); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/BaseTextureRegionBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/BaseTextureRegionBuffer.java new file mode 100644 index 0000000..3257c46 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/BaseTextureRegionBuffer.java @@ -0,0 +1,162 @@ +package org.anddev.andengine.opengl.texture.region.buffer; + +import static org.anddev.andengine.opengl.vertex.RectangleVertexBuffer.VERTICES_PER_RECTANGLE; + +import org.anddev.andengine.opengl.buffer.BufferObject; +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.region.BaseTextureRegion; +import org.anddev.andengine.opengl.util.FastFloatBuffer; + +/** + * @author Nicolas Gramlich + * @since 19:05:50 - 09.03.2010 + */ +public abstract class BaseTextureRegionBuffer extends BufferObject { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final BaseTextureRegion mTextureRegion; + private boolean mFlippedVertical; + private boolean mFlippedHorizontal; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTextureRegionBuffer(final BaseTextureRegion pBaseTextureRegion, final int pDrawType) { + super(2 * VERTICES_PER_RECTANGLE, pDrawType); + this.mTextureRegion = pBaseTextureRegion; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public BaseTextureRegion getTextureRegion() { + return this.mTextureRegion; + } + + public boolean isFlippedHorizontal() { + return this.mFlippedHorizontal; + } + + public void setFlippedHorizontal(final boolean pFlippedHorizontal) { + if(this.mFlippedHorizontal != pFlippedHorizontal) { + this.mFlippedHorizontal = pFlippedHorizontal; + this.update(); + } + } + + public boolean isFlippedVertical() { + return this.mFlippedVertical; + } + + public void setFlippedVertical(final boolean pFlippedVertical) { + if(this.mFlippedVertical != pFlippedVertical) { + this.mFlippedVertical = pFlippedVertical; + this.update(); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract float getX1(); + + protected abstract float getY1(); + + protected abstract float getX2(); + + protected abstract float getY2(); + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void update() { + final BaseTextureRegion textureRegion = this.mTextureRegion; + final Texture texture = textureRegion.getTexture(); + + if(texture == null) { + return; + } + + final int x1 = Float.floatToRawIntBits(this.getX1()); + final int y1 = Float.floatToRawIntBits(this.getY1()); + final int x2 = Float.floatToRawIntBits(this.getX2()); + final int y2 = Float.floatToRawIntBits(this.getY2()); + + final int[] bufferData = this.mBufferData; + + if(this.mFlippedVertical) { + if(this.mFlippedHorizontal) { + bufferData[0] = x2; + bufferData[1] = y2; + + bufferData[2] = x2; + bufferData[3] = y1; + + bufferData[4] = x1; + bufferData[5] = y2; + + bufferData[6] = x1; + bufferData[7] = y1; + } else { + bufferData[0] = x1; + bufferData[1] = y2; + + bufferData[2] = x1; + bufferData[3] = y1; + + bufferData[4] = x2; + bufferData[5] = y2; + + bufferData[6] = x2; + bufferData[7] = y1; + } + } else { + if(this.mFlippedHorizontal) { + bufferData[0] = x2; + bufferData[1] = y1; + + bufferData[2] = x2; + bufferData[3] = y2; + + bufferData[4] = x1; + bufferData[5] = y1; + + bufferData[6] = x1; + bufferData[7] = y2; + } else { + bufferData[0] = x1; + bufferData[1] = y1; + + bufferData[2] = x1; + bufferData[3] = y2; + + bufferData[4] = x2; + bufferData[5] = y1; + + bufferData[6] = x2; + bufferData[7] = y2; + } + } + + final FastFloatBuffer buffer = this.getFloatBuffer(); + buffer.position(0); + buffer.put(bufferData); + buffer.position(0); + + super.setHardwareBufferNeedsUpdate(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/TextureRegionBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/TextureRegionBuffer.java new file mode 100644 index 0000000..570eb8d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/TextureRegionBuffer.java @@ -0,0 +1,66 @@ +package org.anddev.andengine.opengl.texture.region.buffer; + +import org.anddev.andengine.opengl.texture.region.TextureRegion; + +public class TextureRegionBuffer extends BaseTextureRegionBuffer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TextureRegionBuffer(final TextureRegion pTextureRegion, final int pDrawType) { + super(pTextureRegion, pDrawType); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public TextureRegion getTextureRegion() { + return (TextureRegion) super.getTextureRegion(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected float getX1() { + final TextureRegion textureRegion = this.getTextureRegion(); + return (float) textureRegion.getTexturePositionX() / textureRegion.getTexture().getWidth(); + } + + @Override + protected float getX2() { + final TextureRegion textureRegion = this.getTextureRegion(); + return (float) (textureRegion.getTexturePositionX() + textureRegion.getWidth()) / textureRegion.getTexture().getWidth(); + } + + @Override + protected float getY1() { + final TextureRegion textureRegion = this.getTextureRegion(); + return (float) textureRegion.getTexturePositionY() / textureRegion.getTexture().getHeight(); + } + + @Override + protected float getY2() { + final TextureRegion textureRegion = this.getTextureRegion(); + return (float) (textureRegion.getTexturePositionY() + textureRegion.getHeight()) / textureRegion.getTexture().getHeight(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/TiledTextureRegionBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/TiledTextureRegionBuffer.java new file mode 100644 index 0000000..4ec3ca6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/region/buffer/TiledTextureRegionBuffer.java @@ -0,0 +1,70 @@ +package org.anddev.andengine.opengl.texture.region.buffer; + +import org.anddev.andengine.opengl.texture.region.TiledTextureRegion; + +/** + * @author Nicolas Gramlich + * @since 19:01:11 - 09.03.2010 + */ +public class TiledTextureRegionBuffer extends BaseTextureRegionBuffer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public TiledTextureRegionBuffer(final TiledTextureRegion pTextureRegion, final int pDrawType) { + super(pTextureRegion, pDrawType); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + @Override + public TiledTextureRegion getTextureRegion() { + return (TiledTextureRegion) super.getTextureRegion(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected float getX1() { + final TiledTextureRegion textureRegion = this.getTextureRegion(); + return textureRegion.getTexturePositionOfCurrentTileX() / textureRegion.getTexture().getWidth(); + } + + @Override + protected float getX2() { + final TiledTextureRegion textureRegion = this.getTextureRegion(); + return (textureRegion.getTexturePositionOfCurrentTileX() + textureRegion.getTileWidth()) / textureRegion.getTexture().getWidth(); + } + + @Override + protected float getY1() { + final TiledTextureRegion textureRegion = this.getTextureRegion(); + return textureRegion.getTexturePositionOfCurrentTileY() / textureRegion.getTexture().getHeight(); + } + + @Override + protected float getY2() { + final TiledTextureRegion textureRegion = this.getTextureRegion(); + return (textureRegion.getTexturePositionOfCurrentTileY() + textureRegion.getTileHeight()) / textureRegion.getTexture().getHeight(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/AssetTextureSource.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/AssetTextureSource.java new file mode 100644 index 0000000..b318ca5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/AssetTextureSource.java @@ -0,0 +1,117 @@ +package org.anddev.andengine.opengl.texture.source; + +import java.io.IOException; +import java.io.InputStream; + +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.StreamUtils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; + +/** + * @author Nicolas Gramlich + * @since 12:07:52 - 09.03.2010 + */ +public class AssetTextureSource implements ITextureSource { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mWidth; + private final int mHeight; + + private final String mAssetPath; + private final Context mContext; + + // =========================================================== + // Constructors + // =========================================================== + + public AssetTextureSource(final Context pContext, final String pAssetPath) { + this.mContext = pContext; + this.mAssetPath = pAssetPath; + + final BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); + decodeOptions.inJustDecodeBounds = true; + + InputStream in = null; + try { + in = pContext.getAssets().open(pAssetPath); + BitmapFactory.decodeStream(in, null, decodeOptions); + } catch (final IOException e) { + Debug.e("Failed loading Bitmap in AssetTextureSource. AssetPath: " + pAssetPath, e); + } finally { + StreamUtils.close(in); + } + + this.mWidth = decodeOptions.outWidth; + this.mHeight = decodeOptions.outHeight; + } + + AssetTextureSource(final Context pContext, final String pAssetPath, final int pWidth, final int pHeight) { + this.mContext = pContext; + this.mAssetPath = pAssetPath; + this.mWidth = pWidth; + this.mHeight = pHeight; + } + + @Override + public AssetTextureSource clone() { + return new AssetTextureSource(this.mContext, this.mAssetPath, this.mWidth, this.mHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int getHeight() { + return this.mHeight; + } + + @Override + public int getWidth() { + return this.mWidth; + } + + @Override + public Bitmap onLoadBitmap() { + InputStream in = null; + try { + final BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); + decodeOptions.inPreferredConfig = Config.ARGB_8888; + + in = this.mContext.getAssets().open(this.mAssetPath); + return BitmapFactory.decodeStream(in, null, decodeOptions); + } catch (final IOException e) { + Debug.e("Failed loading Bitmap in AssetTextureSource. AssetPath: " + this.mAssetPath, e); + return null; + } finally { + StreamUtils.close(in); + } + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "(" + this.mAssetPath + ")"; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/EmptyBitmapTextureSource.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/EmptyBitmapTextureSource.java new file mode 100644 index 0000000..2a8c7c5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/EmptyBitmapTextureSource.java @@ -0,0 +1,71 @@ +package org.anddev.andengine.opengl.texture.source; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; + +/** + * @author Nicolas Gramlich + * @since 20:20:36 - 08.08.2010 + */ +public class EmptyBitmapTextureSource implements ITextureSource { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mWidth; + private final int mHeight; + + // =========================================================== + // Constructors + // =========================================================== + + public EmptyBitmapTextureSource(final int pWidth, final int pHeight) { + this.mWidth = pWidth; + this.mHeight = pHeight; + } + + @Override + public EmptyBitmapTextureSource clone() { + return new EmptyBitmapTextureSource(this.mWidth, this.mHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int getHeight() { + return this.mHeight; + } + + @Override + public int getWidth() { + return this.mWidth; + } + + @Override + public Bitmap onLoadBitmap() { + return Bitmap.createBitmap(this.mWidth, this.mHeight, Config.ARGB_8888); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "(" + this.mWidth + " x " + this.mHeight + ")"; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/FileTextureSource.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/FileTextureSource.java new file mode 100644 index 0000000..5279584 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/FileTextureSource.java @@ -0,0 +1,116 @@ +package org.anddev.andengine.opengl.texture.source; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.StreamUtils; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; + +/** + * + * @author Nicolas Gramlich + * @since 16:39:22 - 10.08.2010 + */ +public class FileTextureSource implements ITextureSource { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mWidth; + private final int mHeight; + + private final File mFile; + + // =========================================================== + // Constructors + // =========================================================== + + public FileTextureSource(final File pFile) { + this.mFile = pFile; + + final BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); + decodeOptions.inJustDecodeBounds = true; + + InputStream in = null; + try { + in = new FileInputStream(pFile); + BitmapFactory.decodeStream(in, null, decodeOptions); + } catch (final IOException e) { + Debug.e("Failed loading Bitmap in FileTextureSource. File: " + pFile, e); + } finally { + StreamUtils.close(in); + } + + this.mWidth = decodeOptions.outWidth; + this.mHeight = decodeOptions.outHeight; + } + + FileTextureSource(final File pFile, final int pWidth, final int pHeight) { + this.mFile = pFile; + this.mWidth = pWidth; + this.mHeight = pHeight; + } + + @Override + public FileTextureSource clone() { + return new FileTextureSource(this.mFile, this.mWidth, this.mHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int getHeight() { + return this.mHeight; + } + + @Override + public int getWidth() { + return this.mWidth; + } + + @Override + public Bitmap onLoadBitmap() { + final BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); + decodeOptions.inPreferredConfig = Config.ARGB_8888; + + InputStream in = null; + try { + in = new FileInputStream(this.mFile); + return BitmapFactory.decodeStream(in, null, decodeOptions); + } catch (final IOException e) { + Debug.e("Failed loading Bitmap in FileTextureSource. File: " + this.mFile, e); + return null; + } finally { + StreamUtils.close(in); + } + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "(" + this.mFile + ")"; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/ITextureSource.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/ITextureSource.java new file mode 100644 index 0000000..e5eb9de --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/ITextureSource.java @@ -0,0 +1,24 @@ +package org.anddev.andengine.opengl.texture.source; + +import android.graphics.Bitmap; + +/** + * @author Nicolas Gramlich + * @since 12:08:52 - 09.03.2010 + */ +public interface ITextureSource extends Cloneable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public int getWidth(); + public int getHeight(); + + public ITextureSource clone(); + + public Bitmap onLoadBitmap(); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/ResourceTextureSource.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/ResourceTextureSource.java new file mode 100644 index 0000000..01270dc --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/ResourceTextureSource.java @@ -0,0 +1,95 @@ +package org.anddev.andengine.opengl.texture.source; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; + +/** + * @author Nicolas Gramlich + * @since 15:07:23 - 09.03.2010 + */ +public class ResourceTextureSource implements ITextureSource { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mWidth; + private final int mHeight; + + private final int mDrawableResourceID; + private final Context mContext; + + // =========================================================== + // Constructors + // =========================================================== + + public ResourceTextureSource(final Context pContext, final int pDrawableResourceID) { + this.mContext = pContext; + this.mDrawableResourceID = pDrawableResourceID; + + final BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); + decodeOptions.inJustDecodeBounds = true; +// decodeOptions.inScaled = false; // TODO Check how this behaves with drawable-""/nodpi/ldpi/mdpi/hdpi folders + + BitmapFactory.decodeResource(pContext.getResources(), pDrawableResourceID, decodeOptions); + + this.mWidth = decodeOptions.outWidth; + this.mHeight = decodeOptions.outHeight; + } + + protected ResourceTextureSource(final Context pContext, final int pDrawableResourceID, final int pWidth, final int pHeight) { + this.mContext = pContext; + this.mDrawableResourceID = pDrawableResourceID; + this.mWidth = pWidth; + this.mHeight = pHeight; + } + + @Override + public ResourceTextureSource clone() { + return new ResourceTextureSource(this.mContext, this.mDrawableResourceID, this.mWidth, this.mHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int getHeight() { + return this.mHeight; + } + + @Override + public int getWidth() { + return this.mWidth; + } + + @Override + public Bitmap onLoadBitmap() { + final BitmapFactory.Options decodeOptions = new BitmapFactory.Options(); + decodeOptions.inPreferredConfig = Config.ARGB_8888; +// decodeOptions.inScaled = false; // TODO Check how this behaves with drawable-""/nodpi/ldpi/mdpi/hdpi folders + return BitmapFactory.decodeResource(this.mContext.getResources(), this.mDrawableResourceID, decodeOptions); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "(" + this.mDrawableResourceID + ")"; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/BaseShapeTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/BaseShapeTextureSourceDecorator.java new file mode 100644 index 0000000..4af3b89 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/BaseShapeTextureSourceDecorator.java @@ -0,0 +1,56 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.shape.ITextureSourceDecoratorShape; + +import android.graphics.Canvas; + +/** + * @author Nicolas Gramlich + * @since 20:09:41 - 05.11.2010 + */ +public abstract class BaseShapeTextureSourceDecorator extends BaseTextureSourceDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final ITextureSourceDecoratorShape mTextureSourceDecoratorShape; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseShapeTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + super(pTextureSource, pTextureSourceDecoratorOptions); + + this.mTextureSourceDecoratorShape = pTextureSourceDecoratorShape; + } + + @Override + public abstract BaseShapeTextureSourceDecorator clone(); + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected void onDecorateBitmap(final Canvas pCanvas){ + this.mTextureSourceDecoratorShape.onDecorateBitmap(pCanvas, this.mPaint, (this.mTextureSourceDecoratorOptions == null) ? TextureSourceDecoratorOptions.DEFAULT : this.mTextureSourceDecoratorOptions); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/BaseTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/BaseTextureSourceDecorator.java new file mode 100644 index 0000000..b3aa18b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/BaseTextureSourceDecorator.java @@ -0,0 +1,209 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; + +/** + * @author Nicolas Gramlich + * @since 16:43:29 - 06.08.2010 + */ +public abstract class BaseTextureSourceDecorator implements ITextureSource { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final ITextureSource mTextureSource; + protected TextureSourceDecoratorOptions mTextureSourceDecoratorOptions; + protected Paint mPaint = new Paint(); + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTextureSourceDecorator(final ITextureSource pTextureSource) { + this(pTextureSource, new TextureSourceDecoratorOptions()); + } + + public BaseTextureSourceDecorator(final ITextureSource pTextureSource, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + this.mTextureSource = pTextureSource; + this.mTextureSourceDecoratorOptions = (pTextureSourceDecoratorOptions == null) ? new TextureSourceDecoratorOptions() : pTextureSourceDecoratorOptions; + this.mPaint.setAntiAlias(this.mTextureSourceDecoratorOptions.getAntiAliasing()); + } + + @Override + public abstract BaseTextureSourceDecorator clone(); + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Paint getPaint() { + return this.mPaint; + } + + public void setPaint(final Paint pPaint) { + this.mPaint = pPaint; + } + + public TextureSourceDecoratorOptions getTextureSourceDecoratorOptions() { + return this.mTextureSourceDecoratorOptions; + } + + public void setTextureSourceDecoratorOptions(final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + this.mTextureSourceDecoratorOptions = pTextureSourceDecoratorOptions; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onDecorateBitmap(final Canvas pCanvas); + + @Override + public int getWidth() { + return this.mTextureSource.getWidth(); + } + + @Override + public int getHeight() { + return this.mTextureSource.getHeight(); + } + + @Override + public Bitmap onLoadBitmap() { + final Bitmap bitmap = this.ensureLoadedBitmapIsMutable(this.mTextureSource.onLoadBitmap()); + + final Canvas canvas = new Canvas(bitmap); + this.onDecorateBitmap(canvas); + return bitmap; + } + + // =========================================================== + // Methods + // =========================================================== + + private Bitmap ensureLoadedBitmapIsMutable(final Bitmap pBitmap) { + if(pBitmap.isMutable()) { + return pBitmap; + } else { + final Bitmap mutableBitmap = pBitmap.copy(pBitmap.getConfig(), true); + pBitmap.recycle(); + return mutableBitmap; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class TextureSourceDecoratorOptions { + // =========================================================== + // Constants + // =========================================================== + + public static final TextureSourceDecoratorOptions DEFAULT = new TextureSourceDecoratorOptions(); + + // =========================================================== + // Fields + // =========================================================== + + private float mInsetLeft = 0.0f; + private float mInsetRight = 0.0f; + private float mInsetTop = 0.0f; + private float mInsetBottom = 0.0f; + + private boolean mAntiAliasing; + + // =========================================================== + // Constructors + // =========================================================== + + @Override + protected TextureSourceDecoratorOptions clone() { + final TextureSourceDecoratorOptions textureSourceDecoratorOptions = new TextureSourceDecoratorOptions(); + textureSourceDecoratorOptions.setInsets(this.mInsetLeft, this.mInsetTop, this.mInsetRight, this.mInsetBottom); + textureSourceDecoratorOptions.setAntiAliasing(this.mAntiAliasing); + return textureSourceDecoratorOptions; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean getAntiAliasing() { + return this.mAntiAliasing; + } + + public float getInsetLeft() { + return this.mInsetLeft; + } + + public float getInsetRight() { + return this.mInsetRight; + } + + public float getInsetTop() { + return this.mInsetTop; + } + + public float getInsetBottom() { + return this.mInsetBottom; + } + + public TextureSourceDecoratorOptions setAntiAliasing(final boolean pAntiAliasing) { + this.mAntiAliasing = pAntiAliasing; + return this; + } + + public TextureSourceDecoratorOptions setInsetLeft(final float pInsetLeft) { + this.mInsetLeft = pInsetLeft; + return this; + } + + public TextureSourceDecoratorOptions setInsetRight(final float pInsetRight) { + this.mInsetRight = pInsetRight; + return this; + } + + public TextureSourceDecoratorOptions setInsetTop(final float pInsetTop) { + this.mInsetTop = pInsetTop; + return this; + } + + public TextureSourceDecoratorOptions setInsetBottom(final float pInsetBottom) { + this.mInsetBottom = pInsetBottom; + return this; + } + + public TextureSourceDecoratorOptions setInsets(final float pInsets) { + return this.setInsets(pInsets, pInsets, pInsets, pInsets); + } + + public TextureSourceDecoratorOptions setInsets(final float pInsetLeft, final float pInsetTop, final float pInsetRight, final float pInsetBottom) { + this.mInsetLeft = pInsetLeft; + this.mInsetTop = pInsetTop; + this.mInsetRight = pInsetRight; + this.mInsetBottom = pInsetBottom; + return this; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/ColorKeyTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/ColorKeyTextureSourceDecorator.java new file mode 100644 index 0000000..d50af96 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/ColorKeyTextureSourceDecorator.java @@ -0,0 +1,72 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.shape.ITextureSourceDecoratorShape; + +import android.graphics.AvoidXfermode; +import android.graphics.AvoidXfermode.Mode; +import android.graphics.Color; + +/** + * @author Nicolas Gramlich + * @since 22:16:41 - 06.08.2010 + */ +public class ColorKeyTextureSourceDecorator extends BaseShapeTextureSourceDecorator { + // =========================================================== + // Constants + // =========================================================== + + private static final int TOLERANCE_DEFAULT = 0; + + // =========================================================== + // Fields + // =========================================================== + + private final int mColorKeyColor; + private final int mTolerance; + + // =========================================================== + // Constructors + // =========================================================== + + public ColorKeyTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pColorKeyColor) { + this(pTextureSource, pTextureSourceDecoratorShape, pColorKeyColor, ColorKeyTextureSourceDecorator.TOLERANCE_DEFAULT, null); + } + + public ColorKeyTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pColorKeyColor, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + this(pTextureSource, pTextureSourceDecoratorShape, pColorKeyColor, ColorKeyTextureSourceDecorator.TOLERANCE_DEFAULT, pTextureSourceDecoratorOptions); + } + + public ColorKeyTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pColorKeyColor, final int pTolerance) { + this(pTextureSource, pTextureSourceDecoratorShape, pColorKeyColor, pTolerance, null); + } + + public ColorKeyTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pColorKeyColor, final int pTolerance, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + super(pTextureSource, pTextureSourceDecoratorShape, pTextureSourceDecoratorOptions); + this.mColorKeyColor = pColorKeyColor; + this.mTolerance = pTolerance; + this.mPaint.setXfermode(new AvoidXfermode(pColorKeyColor, pTolerance, Mode.TARGET)); + this.mPaint.setColor(Color.TRANSPARENT); + } + + @Override + public ColorKeyTextureSourceDecorator clone() { + return new ColorKeyTextureSourceDecorator(this.mTextureSource, this.mTextureSourceDecoratorShape, this.mColorKeyColor, this.mTolerance, this.mTextureSourceDecoratorOptions); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/FillTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/FillTextureSourceDecorator.java new file mode 100644 index 0000000..45a3546 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/FillTextureSourceDecorator.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.shape.ITextureSourceDecoratorShape; + +import android.graphics.Paint.Style; + +/** + * @author Nicolas Gramlich + * @since 18:08:00 - 05.11.2010 + */ +public class FillTextureSourceDecorator extends BaseShapeTextureSourceDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final int mFillColor; + + // =========================================================== + // Constructors + // =========================================================== + + public FillTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pFillColor) { + this(pTextureSource, pTextureSourceDecoratorShape, pFillColor, null); + } + + public FillTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pFillColor, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + super(pTextureSource, pTextureSourceDecoratorShape, pTextureSourceDecoratorOptions); + this.mFillColor = pFillColor; + + this.mPaint.setStyle(Style.FILL); + this.mPaint.setColor(pFillColor); + } + + @Override + public FillTextureSourceDecorator clone() { + return new FillTextureSourceDecorator(this.mTextureSource, this.mTextureSourceDecoratorShape, this.mFillColor, this.mTextureSourceDecoratorOptions); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/LinearGradientFillTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/LinearGradientFillTextureSourceDecorator.java new file mode 100644 index 0000000..1f90176 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/LinearGradientFillTextureSourceDecorator.java @@ -0,0 +1,145 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.shape.ITextureSourceDecoratorShape; + +import android.graphics.LinearGradient; +import android.graphics.Paint.Style; +import android.graphics.Shader.TileMode; + +/** + * @author Nicolas Gramlich + * @since 19:21:24 - 05.11.2010 + */ +public class LinearGradientFillTextureSourceDecorator extends BaseShapeTextureSourceDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final LinearGradientDirection mLinearGradientDirection; + protected final int mFromColor; + protected final int mToColor; + + // =========================================================== + // Constructors + // =========================================================== + + public LinearGradientFillTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pFromColor, final int pToColor, final LinearGradientDirection pLinearGradientDirection) { + this(pTextureSource, pTextureSourceDecoratorShape, pFromColor, pToColor, pLinearGradientDirection, null); + } + + public LinearGradientFillTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pFromColor, final int pToColor, final LinearGradientDirection pLinearGradientDirection, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + super(pTextureSource, pTextureSourceDecoratorShape, pTextureSourceDecoratorOptions); + this.mFromColor = pFromColor; + this.mToColor = pToColor; + this.mLinearGradientDirection = pLinearGradientDirection; + + this.mPaint.setStyle(Style.FILL); + + final int width = pTextureSource.getWidth(); + final int height = pTextureSource.getHeight(); + + final float fromX = pLinearGradientDirection.getFromX() * width; + final float fromY = pLinearGradientDirection.getFromY() * height; + final float toX = pLinearGradientDirection.getToX() * width; + final float toY = pLinearGradientDirection.getToY() * height; + + this.mPaint.setShader(new LinearGradient(fromX, fromY, toX, toY, pFromColor, pToColor, TileMode.CLAMP)); + } + + @Override + public LinearGradientFillTextureSourceDecorator clone() { + return new LinearGradientFillTextureSourceDecorator(this.mTextureSource, this.mTextureSourceDecoratorShape, this.mFromColor, this.mToColor, this.mLinearGradientDirection, this.mTextureSourceDecoratorOptions); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static enum LinearGradientDirection { + // =========================================================== + // Elements + // =========================================================== + + LEFT_TO_RIGHT(0, 0, 1, 0), + RIGHT_TO_LEFT(1, 0, 0, 0), + BOTTOM_TO_TOP(0, 0, 0, 1), + TOP_TO_BOTTOM(0, 1, 0, 0), + TOPLEFT_TO_BOTTOMRIGHT(0, 0, 1, 1), + BOTTOMRIGHT_TO_TOPLEFT(1, 1, 0, 0), + TOPRIGHT_TO_BOTTOMLEFT(1, 0, 0, 1), + BOTTOMLEFT_TO_TOPRIGHT(0, 1, 1, 0); + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mFromX; + private final int mFromY; + private final int mToX; + private final int mToY; + + // =========================================================== + // Constructors + // =========================================================== + + private LinearGradientDirection(final int pFromX, final int pFromY, final int pToX, final int pToY) { + this.mFromX = pFromX; + this.mFromY = pFromY; + this.mToX = pToX; + this.mToY = pToY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + final int getFromX() { + return this.mFromX; + } + + final int getFromY() { + return this.mFromY; + } + + final int getToX() { + return this.mToX; + } + + final int getToY() { + return this.mToY; + } + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/OutlineTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/OutlineTextureSourceDecorator.java new file mode 100644 index 0000000..2c87037 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/OutlineTextureSourceDecorator.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.shape.ITextureSourceDecoratorShape; + +import android.graphics.Paint.Style; + +/** + * @author Nicolas Gramlich + * @since 18:07:55 - 05.11.2010 + */ +public class OutlineTextureSourceDecorator extends BaseShapeTextureSourceDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final int mOutlineColor; + + // =========================================================== + // Constructors + // =========================================================== + + public OutlineTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pOutlineColor) { + this(pTextureSource, pTextureSourceDecoratorShape, pOutlineColor, null); + } + + public OutlineTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pOutlineColor, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + super(pTextureSource, pTextureSourceDecoratorShape, pTextureSourceDecoratorOptions); + this.mOutlineColor = pOutlineColor; + + this.mPaint.setStyle(Style.STROKE); + this.mPaint.setColor(pOutlineColor); + } + + @Override + public OutlineTextureSourceDecorator clone() { + return new OutlineTextureSourceDecorator(this.mTextureSource, this.mTextureSourceDecoratorShape, this.mOutlineColor, this.mTextureSourceDecoratorOptions); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/RadialGradientFillTextureSourceDecorator.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/RadialGradientFillTextureSourceDecorator.java new file mode 100644 index 0000000..a2d5179 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/RadialGradientFillTextureSourceDecorator.java @@ -0,0 +1,118 @@ +package org.anddev.andengine.opengl.texture.source.decorator; + +import org.anddev.andengine.opengl.texture.source.ITextureSource; +import org.anddev.andengine.opengl.texture.source.decorator.shape.ITextureSourceDecoratorShape; + +import android.graphics.Paint.Style; +import android.graphics.RadialGradient; +import android.graphics.Shader.TileMode; + +/** + * @author Nicolas Gramlich + * @since 19:21:24 - 05.11.2010 + */ +public class RadialGradientFillTextureSourceDecorator extends BaseShapeTextureSourceDecorator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final RadialGradientDirection mRadialGradientDirection; + protected final int mFromColor; + protected final int mToColor; + + // =========================================================== + // Constructors + // =========================================================== + + public RadialGradientFillTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pFromColor, final int pToColor, final RadialGradientDirection pRadialGradientDirection) { + this(pTextureSource, pTextureSourceDecoratorShape, pFromColor, pToColor, pRadialGradientDirection, null); + } + + public RadialGradientFillTextureSourceDecorator(final ITextureSource pTextureSource, final ITextureSourceDecoratorShape pTextureSourceDecoratorShape, final int pFromColor, final int pToColor, final RadialGradientDirection pRadialGradientDirection, final TextureSourceDecoratorOptions pTextureSourceDecoratorOptions) { + super(pTextureSource, pTextureSourceDecoratorShape, pTextureSourceDecoratorOptions); + this.mFromColor = pFromColor; + this.mToColor = pToColor; + this.mRadialGradientDirection = pRadialGradientDirection; + + this.mPaint.setStyle(Style.FILL); + + final int width = pTextureSource.getWidth(); + final int height = pTextureSource.getHeight(); + + final float centerX = width * 0.5f; + final float centerY = height * 0.5f; + + final float radius = Math.max(centerX, centerY); + + switch(pRadialGradientDirection) { + case INSIDE_OUT: + this.mPaint.setShader(new RadialGradient(centerX, centerY, radius, pFromColor, pToColor, TileMode.CLAMP)); + break; + case OUTSIDE_IN: + this.mPaint.setShader(new RadialGradient(centerX, centerY, radius, pToColor, pFromColor, TileMode.CLAMP)); + break; + } + } + + @Override + public RadialGradientFillTextureSourceDecorator clone() { + return new RadialGradientFillTextureSourceDecorator(this.mTextureSource, this.mTextureSourceDecoratorShape, this.mFromColor, this.mToColor, this.mRadialGradientDirection, this.mTextureSourceDecoratorOptions); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static enum RadialGradientDirection { + // =========================================================== + // Elements + // =========================================================== + + INSIDE_OUT, + OUTSIDE_IN; + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ArcTextureSourceDecoratorShape.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ArcTextureSourceDecoratorShape.java new file mode 100644 index 0000000..3709885 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ArcTextureSourceDecoratorShape.java @@ -0,0 +1,84 @@ +package org.anddev.andengine.opengl.texture.source.decorator.shape; + +import org.anddev.andengine.opengl.texture.source.decorator.BaseTextureSourceDecorator.TextureSourceDecoratorOptions; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +/** + * @author Nicolas Gramlich + * @since 12:52:55 - 04.01.2011 + */ +public class ArcTextureSourceDecoratorShape implements ITextureSourceDecoratorShape { + // =========================================================== + // Constants + // =========================================================== + + private static final float STARTANGLE_DEFAULT = 0; + private static final float SWEEPANGLE_DEFAULT = 360; + private static final boolean USECENTER_DEFAULT = true; + + // =========================================================== + // Fields + // =========================================================== + + private static ArcTextureSourceDecoratorShape sDefaultInstance; + + private final RectF mRectF = new RectF(); + + private final float mStartAngle; + private final float mSweepAngle; + private final boolean mUseCenter; + + // =========================================================== + // Constructors + // =========================================================== + + public ArcTextureSourceDecoratorShape() { + this(STARTANGLE_DEFAULT, SWEEPANGLE_DEFAULT, USECENTER_DEFAULT); + } + + public ArcTextureSourceDecoratorShape(final float pStartAngle, final float pSweepAngle, final boolean pUseCenter) { + this.mStartAngle = pStartAngle; + this.mSweepAngle = pSweepAngle; + this.mUseCenter = pUseCenter; + } + + @Deprecated + public static ArcTextureSourceDecoratorShape getDefaultInstance() { + if(sDefaultInstance == null) { + sDefaultInstance = new ArcTextureSourceDecoratorShape(); + } + return sDefaultInstance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDecorateBitmap(final Canvas pCanvas, final Paint pPaint, final TextureSourceDecoratorOptions pDecoratorOptions) { + final float left = pDecoratorOptions.getInsetLeft(); + final float top = pDecoratorOptions.getInsetTop(); + final float right = pCanvas.getWidth() - 1 - pDecoratorOptions.getInsetRight(); + final float bottom = pCanvas.getHeight() - 1 - pDecoratorOptions.getInsetBottom(); + + this.mRectF.set(left, top, right, bottom); + + pCanvas.drawArc(this.mRectF, this.mStartAngle, this.mSweepAngle, this.mUseCenter, pPaint); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} + diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/CircleTextureSourceDecoratorShape.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/CircleTextureSourceDecoratorShape.java new file mode 100644 index 0000000..cfa3bba --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/CircleTextureSourceDecoratorShape.java @@ -0,0 +1,67 @@ +package org.anddev.andengine.opengl.texture.source.decorator.shape; + +import org.anddev.andengine.opengl.texture.source.decorator.BaseTextureSourceDecorator.TextureSourceDecoratorOptions; + +import android.graphics.Canvas; +import android.graphics.Paint; + +/** + * @author Nicolas Gramlich + * @since 12:53:13 - 04.01.2011 + */ +public class CircleTextureSourceDecoratorShape implements ITextureSourceDecoratorShape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static CircleTextureSourceDecoratorShape sDefaultInstance; + + // =========================================================== + // Constructors + // =========================================================== + + public CircleTextureSourceDecoratorShape() { + + } + + public static CircleTextureSourceDecoratorShape getDefaultInstance() { + if(sDefaultInstance == null) { + sDefaultInstance = new CircleTextureSourceDecoratorShape(); + } + return sDefaultInstance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDecorateBitmap(final Canvas pCanvas, final Paint pPaint, final TextureSourceDecoratorOptions pDecoratorOptions) { + final float width = pCanvas.getWidth() - pDecoratorOptions.getInsetLeft() - pDecoratorOptions.getInsetRight(); + final float height = pCanvas.getHeight() - pDecoratorOptions.getInsetTop() - pDecoratorOptions.getInsetBottom(); + + final float centerX = (pCanvas.getWidth() + pDecoratorOptions.getInsetLeft() - pDecoratorOptions.getInsetRight()) / 2; + final float centerY = (pCanvas.getHeight() + pDecoratorOptions.getInsetTop() - pDecoratorOptions.getInsetBottom()) / 2; + + final float radius = Math.min(width / 2, height / 2); + + pCanvas.drawCircle(centerX, centerY, radius, pPaint); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} + diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/EllipseTextureSourceDecoratorShape.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/EllipseTextureSourceDecoratorShape.java new file mode 100644 index 0000000..75589ea --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/EllipseTextureSourceDecoratorShape.java @@ -0,0 +1,69 @@ +package org.anddev.andengine.opengl.texture.source.decorator.shape; + +import org.anddev.andengine.opengl.texture.source.decorator.BaseTextureSourceDecorator.TextureSourceDecoratorOptions; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +/** + * @author Nicolas Gramlich + * @since 12:52:55 - 04.01.2011 + */ +public class EllipseTextureSourceDecoratorShape implements ITextureSourceDecoratorShape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EllipseTextureSourceDecoratorShape sDefaultInstance; + + private final RectF mRectF = new RectF(); + + // =========================================================== + // Constructors + // =========================================================== + + public EllipseTextureSourceDecoratorShape() { + + } + + public static EllipseTextureSourceDecoratorShape getDefaultInstance() { + if(sDefaultInstance == null) { + sDefaultInstance = new EllipseTextureSourceDecoratorShape(); + } + return sDefaultInstance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDecorateBitmap(final Canvas pCanvas, final Paint pPaint, final TextureSourceDecoratorOptions pDecoratorOptions) { + final float left = pDecoratorOptions.getInsetLeft(); + final float top = pDecoratorOptions.getInsetTop(); + final float right = pCanvas.getWidth() - 1 - pDecoratorOptions.getInsetRight(); + final float bottom = pCanvas.getHeight() - 1 - pDecoratorOptions.getInsetBottom(); + + this.mRectF.set(left, top, right, bottom); + + pCanvas.drawOval(this.mRectF, pPaint); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} + diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ITextureSourceDecoratorShape.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ITextureSourceDecoratorShape.java new file mode 100644 index 0000000..52c23d1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/ITextureSourceDecoratorShape.java @@ -0,0 +1,22 @@ +package org.anddev.andengine.opengl.texture.source.decorator.shape; + +import org.anddev.andengine.opengl.texture.source.decorator.BaseTextureSourceDecorator.TextureSourceDecoratorOptions; + +import android.graphics.Canvas; +import android.graphics.Paint; + +/** + * @author Nicolas Gramlich + * @since 12:47:40 - 04.01.2011 + */ +public interface ITextureSourceDecoratorShape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onDecorateBitmap(final Canvas pCanvas, final Paint pPaint, final TextureSourceDecoratorOptions pDecoratorOptions); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RectangleTextureSourceDecoratorShape.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RectangleTextureSourceDecoratorShape.java new file mode 100644 index 0000000..5fd30f1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RectangleTextureSourceDecoratorShape.java @@ -0,0 +1,58 @@ +package org.anddev.andengine.opengl.texture.source.decorator.shape; + +import org.anddev.andengine.opengl.texture.source.decorator.BaseTextureSourceDecorator.TextureSourceDecoratorOptions; + +import android.graphics.Canvas; +import android.graphics.Paint; + +public class RectangleTextureSourceDecoratorShape implements ITextureSourceDecoratorShape { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static RectangleTextureSourceDecoratorShape sDefaultInstance; + + // =========================================================== + // Constructors + // =========================================================== + + public RectangleTextureSourceDecoratorShape() { + + } + + public static RectangleTextureSourceDecoratorShape getDefaultInstance() { + if(sDefaultInstance == null) { + sDefaultInstance = new RectangleTextureSourceDecoratorShape(); + } + return sDefaultInstance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDecorateBitmap(final Canvas pCanvas, final Paint pPaint, final TextureSourceDecoratorOptions pDecoratorOptions) { + final float left = pDecoratorOptions.getInsetLeft(); + final float top = pDecoratorOptions.getInsetTop(); + final float right = pCanvas.getWidth() - 1 - pDecoratorOptions.getInsetRight(); + final float bottom = pCanvas.getHeight() - 1 - pDecoratorOptions.getInsetBottom(); + pCanvas.drawRect(left, top, right, bottom, pPaint); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +}; \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RoundedRectangleTextureSourceDecoratorShape.java b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RoundedRectangleTextureSourceDecoratorShape.java new file mode 100644 index 0000000..4acac0d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/texture/source/decorator/shape/RoundedRectangleTextureSourceDecoratorShape.java @@ -0,0 +1,78 @@ +package org.anddev.andengine.opengl.texture.source.decorator.shape; + +import org.anddev.andengine.opengl.texture.source.decorator.BaseTextureSourceDecorator.TextureSourceDecoratorOptions; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; + +/** + * @author Nicolas Gramlich + * @since 12:50:09 - 04.01.2011 + */ +public class RoundedRectangleTextureSourceDecoratorShape implements ITextureSourceDecoratorShape { + // =========================================================== + // Constants + // =========================================================== + + private static final float CORNER_RADIUS_DEFAULT = 1; + + // =========================================================== + // Fields + // =========================================================== + + private final RectF mRectF = new RectF(); + + private final float mCornerRadiusX; + private final float mCornerRadiusY; + + private static RoundedRectangleTextureSourceDecoratorShape sDefaultInstance; + + // =========================================================== + // Constructors + // =========================================================== + + public RoundedRectangleTextureSourceDecoratorShape() { + this(CORNER_RADIUS_DEFAULT, CORNER_RADIUS_DEFAULT); + } + + public RoundedRectangleTextureSourceDecoratorShape(final float pCornerRadiusX, final float pCornerRadiusY) { + this.mCornerRadiusX = pCornerRadiusX; + this.mCornerRadiusY = pCornerRadiusY; + } + + public static RoundedRectangleTextureSourceDecoratorShape getDefaultInstance() { + if(sDefaultInstance == null) { + sDefaultInstance = new RoundedRectangleTextureSourceDecoratorShape(); + } + return sDefaultInstance; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onDecorateBitmap(final Canvas pCanvas, final Paint pPaint, final TextureSourceDecoratorOptions pDecoratorOptions) { + final float left = pDecoratorOptions.getInsetLeft(); + final float top = pDecoratorOptions.getInsetTop(); + final float right = pCanvas.getWidth() - 1 - pDecoratorOptions.getInsetRight(); + final float bottom = pCanvas.getHeight() - 1 - pDecoratorOptions.getInsetBottom(); + + this.mRectF.set(left, top, right, bottom); + + pCanvas.drawRoundRect(this.mRectF, this.mCornerRadiusX, this.mCornerRadiusY, pPaint); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/util/FastFloatBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/util/FastFloatBuffer.java new file mode 100644 index 0000000..aee5aeb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/util/FastFloatBuffer.java @@ -0,0 +1,209 @@ +package org.anddev.andengine.opengl.util; + +import static org.anddev.andengine.opengl.util.GLHelper.BYTES_PER_FLOAT; + +import java.lang.ref.SoftReference; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +/** + * Convenient work-around for poor {@link FloatBuffer#put(float[])} performance. + * This should become unnecessary in gingerbread, + * @see Issue 11078 + * + * @author ryanm + */ +public class FastFloatBuffer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + /** + * Use a {@link SoftReference} so that the array can be collected if + * necessary + */ + private static SoftReference sWeakIntArray = new SoftReference(new int[0]); + + /** + * Underlying data - give this to OpenGL + */ + public final ByteBuffer mByteBuffer; + private final FloatBuffer mFloatBuffer; + private final IntBuffer mIntBuffer; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * Constructs a new direct native-ordered buffer + */ + public FastFloatBuffer(final int pCapacity) { + this.mByteBuffer = ByteBuffer.allocateDirect((pCapacity * BYTES_PER_FLOAT)).order(ByteOrder.nativeOrder()); + this.mFloatBuffer = this.mByteBuffer.asFloatBuffer(); + this.mIntBuffer = this.mByteBuffer.asIntBuffer(); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * See {@link FloatBuffer#flip()} + */ + public void flip() { + this.mByteBuffer.flip(); + this.mFloatBuffer.flip(); + this.mIntBuffer.flip(); + } + + /** + * See {@link FloatBuffer#put(float)} + */ + public void put(final float f) { + final ByteBuffer byteBuffer = this.mByteBuffer; + final IntBuffer intBuffer = this.mIntBuffer; + + byteBuffer.position(byteBuffer.position() + BYTES_PER_FLOAT); + this.mFloatBuffer.put(f); + intBuffer.position(intBuffer.position() + 1); + } + + /** + * It's like {@link FloatBuffer#put(float[])}, but about 10 times faster + */ + public void put(final float[] data) { + final int length = data.length; + + int[] ia = sWeakIntArray.get(); + if(ia == null || ia.length < length) { + ia = new int[length]; + sWeakIntArray = new SoftReference(ia); + } + + for(int i = 0; i < length; i++) { + ia[i] = Float.floatToRawIntBits(data[i]); + } + + final ByteBuffer byteBuffer = this.mByteBuffer; + byteBuffer.position(byteBuffer.position() + BYTES_PER_FLOAT * length); + final FloatBuffer floatBuffer = this.mFloatBuffer; + floatBuffer.position(floatBuffer.position() + length); + this.mIntBuffer.put(ia, 0, length); + } + + /** + * For use with pre-converted data. This is 50x faster than + * {@link #put(float[])}, and 500x faster than + * {@link FloatBuffer#put(float[])}, so if you've got float[] data that + * won't change, {@link #convert(float...)} it to an int[] once and use this + * method to put it in the buffer + * + * @param data floats that have been converted with {@link Float#floatToIntBits(float)} + */ + public void put(final int[] data) { + final ByteBuffer byteBuffer = this.mByteBuffer; + byteBuffer.position(byteBuffer.position() + BYTES_PER_FLOAT * data.length); + final FloatBuffer floatBuffer = this.mFloatBuffer; + floatBuffer.position(floatBuffer.position() + data.length); + this.mIntBuffer.put(data, 0, data.length); + } + + /** + * Converts float data to a format that can be quickly added to the buffer + * with {@link #put(int[])} + * + * @param data + * @return the int-formatted data + */ + public static int[] convert(final float ... data) { + final int length = data.length; + final int[] id = new int[length]; + for(int i = 0; i < length; i++) { + id[i] = Float.floatToRawIntBits(data[i]); + } + + return id; + } + + /** + * See {@link FloatBuffer#put(FloatBuffer)} + */ + public void put(final FastFloatBuffer b) { + final ByteBuffer byteBuffer = this.mByteBuffer; + byteBuffer.put(b.mByteBuffer); + this.mFloatBuffer.position(byteBuffer.position() >> 2); + this.mIntBuffer.position(byteBuffer.position() >> 2); + } + + /** + * @return See {@link FloatBuffer#capacity()} + */ + public int capacity() { + return this.mFloatBuffer.capacity(); + } + + /** + * @return See {@link FloatBuffer#position()} + */ + public int position() { + return this.mFloatBuffer.position(); + } + + /** + * See {@link FloatBuffer#position(int)} + */ + public void position(final int p) { + this.mByteBuffer.position(p * BYTES_PER_FLOAT); + this.mFloatBuffer.position(p); + this.mIntBuffer.position(p); + } + + /** + * @return See {@link FloatBuffer#slice()} + */ + public FloatBuffer slice() { + return this.mFloatBuffer.slice(); + } + + /** + * @return See {@link FloatBuffer#remaining()} + */ + public int remaining() { + return this.mFloatBuffer.remaining(); + } + + /** + * @return See {@link FloatBuffer#limit()} + */ + public int limit() { + return this.mFloatBuffer.limit(); + } + + /** + * See {@link FloatBuffer#clear()} + */ + public void clear() { + this.mByteBuffer.clear(); + this.mFloatBuffer.clear(); + this.mIntBuffer.clear(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/util/GLHelper.java b/AndEngine/src/org/anddev/andengine/opengl/util/GLHelper.java new file mode 100644 index 0000000..7aa3ce5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/util/GLHelper.java @@ -0,0 +1,437 @@ +package org.anddev.andengine.opengl.util; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.IntBuffer; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.engine.options.RenderOptions; +import org.anddev.andengine.util.Debug; + +import android.graphics.Bitmap; +import android.opengl.GLUtils; +import android.os.Build; + +/** + * @author Nicolas Gramlich + * @since 18:00:43 - 08.03.2010 + */ +public class GLHelper { + // =========================================================== + // Constants + // =========================================================== + + public static final int BYTES_PER_FLOAT = 4; + public static final int BYTES_PER_PIXEL_RGBA = 4; + + private static final boolean IS_LITTLE_ENDIAN = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN); + + private static final int[] HARDWARETEXTUREID_CONTAINER = new int[1]; + private static final int[] HARDWAREBUFFERID_CONTAINER = new int[1]; + + // =========================================================== + // Fields + // =========================================================== + + private static int sCurrentHardwareBufferID = -1; + private static int sCurrentHardwareTextureID = -1; + private static int sCurrentMatrix = -1; + + private static int sCurrentSourceBlendMode = -1; + private static int sCurrentDestinationBlendMode = -1; + + private static FastFloatBuffer sCurrentTextureFloatBuffer = null; + private static FastFloatBuffer sCurrentVertexFloatBuffer = null; + + private static boolean sEnableDither = true; + private static boolean sEnableLightning = true; + private static boolean sEnableDepthTest = true; + private static boolean sEnableMultisample = true; + + private static boolean sEnableScissorTest = false; + private static boolean sEnableBlend = false; + private static boolean sEnableCulling = false; + private static boolean sEnableTextures = false; + private static boolean sEnableTexCoordArray = false; + private static boolean sEnableVertexArray = false; + + private static float sLineWidth = 1; + + private static float sRed = -1; + private static float sGreen = -1; + private static float sBlue = -1; + private static float sAlpha = -1; + + public static boolean EXTENSIONS_VERTEXBUFFEROBJECTS = false; + public static boolean EXTENSIONS_DRAWTEXTURE = false; + + // =========================================================== + // Methods + // =========================================================== + + public static void reset(final GL10 pGL) { + GLHelper.sCurrentHardwareBufferID = -1; + GLHelper.sCurrentHardwareTextureID = -1; + GLHelper.sCurrentMatrix = -1; + + GLHelper.sCurrentSourceBlendMode = -1; + GLHelper.sCurrentDestinationBlendMode = -1; + + GLHelper.sCurrentTextureFloatBuffer = null; + GLHelper.sCurrentVertexFloatBuffer = null; + + GLHelper.enableDither(pGL); + GLHelper.enableLightning(pGL); + GLHelper.enableDepthTest(pGL); + GLHelper.enableMultisample(pGL); + + GLHelper.disableBlend(pGL); + GLHelper.disableCulling(pGL); + GLHelper.disableTextures(pGL); + GLHelper.disableTexCoordArray(pGL); + GLHelper.disableVertexArray(pGL); + + GLHelper.sLineWidth = 1; + + GLHelper.sRed = -1; + GLHelper.sGreen = -1; + GLHelper.sBlue = -1; + GLHelper.sAlpha = -1; + + GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS = false; + GLHelper.EXTENSIONS_DRAWTEXTURE = false; + } + + public static void enableExtensions(final GL10 pGL, final RenderOptions pRenderOptions) { + final String version = pGL.glGetString(GL10.GL_VERSION); + final String renderer = pGL.glGetString(GL10.GL_RENDERER); + final String extensions = pGL.glGetString(GL10.GL_EXTENSIONS); + + Debug.d("RENDERER: " + renderer); + Debug.d("VERSION: " + version); + Debug.d("EXTENSIONS: " + extensions); + + final boolean isOpenGL10 = version.contains("1.0"); + final boolean isSoftwareRenderer = renderer.contains("PixelFlinger"); + final boolean isVBOCapable = extensions.contains("_vertex_buffer_object"); + final boolean isDrawTextureCapable = extensions.contains("draw_texture"); + + GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS = !pRenderOptions.isDisableExtensionVertexBufferObjects() && !isSoftwareRenderer && (isVBOCapable || !isOpenGL10); + GLHelper.EXTENSIONS_DRAWTEXTURE = isDrawTextureCapable; + + GLHelper.hackBrokenDevices(); + Debug.d("EXTENSIONS_VERXTEXBUFFEROBJECTS = " + GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS); + Debug.d("EXTENSIONS_DRAWTEXTURE = " + GLHelper.EXTENSIONS_DRAWTEXTURE); + } + + private static void hackBrokenDevices() { + if (Build.PRODUCT.contains("morrison")) { + // This is the Motorola Cliq. This device LIES and says it supports + // VBOs, which it actually does not (or, more likely, the extensions string + // is correct and the GL JNI glue is broken). + GLHelper.EXTENSIONS_VERTEXBUFFEROBJECTS = false; + // TODO: if Motorola fixes this, I should switch to using the fingerprint + // (blur/morrison/morrison/morrison:1.5/CUPCAKE/091007:user/ota-rel-keys,release-keys) + // instead of the product name so that newer versions use VBOs + } + } + + public static void setColor(final GL10 pGL, final float pRed, final float pGreen, final float pBlue, final float pAlpha) { + if(pAlpha != GLHelper.sAlpha || pRed != GLHelper.sRed || pGreen != GLHelper.sGreen || pBlue != GLHelper.sBlue) { + GLHelper.sAlpha = pAlpha; + GLHelper.sRed = pRed; + GLHelper.sGreen = pGreen; + GLHelper.sBlue = pBlue; + pGL.glColor4f(pRed, pGreen, pBlue, pAlpha); + } + } + + public static void enableVertexArray(final GL10 pGL) { + if(!GLHelper.sEnableVertexArray) { + GLHelper.sEnableVertexArray = true; + pGL.glEnableClientState(GL10.GL_VERTEX_ARRAY); + } + } + public static void disableVertexArray(final GL10 pGL) { + if(GLHelper.sEnableVertexArray) { + GLHelper.sEnableVertexArray = false; + pGL.glDisableClientState(GL10.GL_VERTEX_ARRAY); + } + } + + public static void enableTexCoordArray(final GL10 pGL) { + if(!GLHelper.sEnableTexCoordArray) { + GLHelper.sEnableTexCoordArray = true; + pGL.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); + } + } + public static void disableTexCoordArray(final GL10 pGL) { + if(GLHelper.sEnableTexCoordArray) { + GLHelper.sEnableTexCoordArray = false; + pGL.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); + } + } + + public static void enableScissorTest(final GL10 pGL) { + if(!GLHelper.sEnableScissorTest) { + GLHelper.sEnableScissorTest = true; + pGL.glEnable(GL10.GL_SCISSOR_TEST); + } + } + public static void disableScissorTest(final GL10 pGL) { + if(GLHelper.sEnableScissorTest) { + GLHelper.sEnableScissorTest = false; + pGL.glDisable(GL10.GL_SCISSOR_TEST); + } + } + + public static void enableBlend(final GL10 pGL) { + if(!GLHelper.sEnableBlend) { + GLHelper.sEnableBlend = true; + pGL.glEnable(GL10.GL_BLEND); + } + } + public static void disableBlend(final GL10 pGL) { + if(GLHelper.sEnableBlend) { + GLHelper.sEnableBlend = false; + pGL.glDisable(GL10.GL_BLEND); + } + } + + public static void enableCulling(final GL10 pGL) { + if(!GLHelper.sEnableCulling) { + GLHelper.sEnableCulling = true; + pGL.glEnable(GL10.GL_CULL_FACE); + } + } + public static void disableCulling(final GL10 pGL) { + if(GLHelper.sEnableCulling) { + GLHelper.sEnableCulling = false; + pGL.glDisable(GL10.GL_CULL_FACE); + } + } + + public static void enableTextures(final GL10 pGL) { + if(!GLHelper.sEnableTextures) { + GLHelper.sEnableTextures = true; + pGL.glEnable(GL10.GL_TEXTURE_2D); + } + } + public static void disableTextures(final GL10 pGL) { + if(GLHelper.sEnableTextures) { + GLHelper.sEnableTextures = false; + pGL.glDisable(GL10.GL_TEXTURE_2D); + } + } + + public static void enableLightning(final GL10 pGL) { + if(!GLHelper.sEnableLightning) { + GLHelper.sEnableLightning = true; + pGL.glEnable(GL10.GL_LIGHTING); + } + } + public static void disableLightning(final GL10 pGL) { + if(GLHelper.sEnableLightning) { + GLHelper.sEnableLightning = false; + pGL.glDisable(GL10.GL_LIGHTING); + } + } + + public static void enableDither(final GL10 pGL) { + if(!GLHelper.sEnableDither) { + GLHelper.sEnableDither = true; + pGL.glEnable(GL10.GL_DITHER); + } + } + public static void disableDither(final GL10 pGL) { + if(GLHelper.sEnableDither) { + GLHelper.sEnableDither = false; + pGL.glDisable(GL10.GL_DITHER); + } + } + + public static void enableDepthTest(final GL10 pGL) { + if(!GLHelper.sEnableDepthTest) { + GLHelper.sEnableDepthTest = true; + pGL.glEnable(GL10.GL_DEPTH_TEST); + } + } + public static void disableDepthTest(final GL10 pGL) { + if(GLHelper.sEnableDepthTest) { + GLHelper.sEnableDepthTest = false; + pGL.glDisable(GL10.GL_DEPTH_TEST); + } + } + + public static void enableMultisample(final GL10 pGL) { + if(!GLHelper.sEnableMultisample) { + GLHelper.sEnableMultisample = true; + pGL.glEnable(GL10.GL_MULTISAMPLE); + } + } + public static void disableMultisample(final GL10 pGL) { + if(GLHelper.sEnableMultisample) { + GLHelper.sEnableMultisample = false; + pGL.glDisable(GL10.GL_MULTISAMPLE); + } + } + + public static void bindBuffer(final GL11 pGL11, final int pHardwareBufferID) { + /* Reduce unnecessary buffer switching calls. */ + if(GLHelper.sCurrentHardwareBufferID != pHardwareBufferID) { + GLHelper.sCurrentHardwareBufferID = pHardwareBufferID; + pGL11.glBindBuffer(GL11.GL_ARRAY_BUFFER, pHardwareBufferID); + } + } + + public static void deleteBuffer(final GL11 pGL11, final int pHardwareBufferID) { + GLHelper.HARDWAREBUFFERID_CONTAINER[0] = pHardwareBufferID; + pGL11.glDeleteBuffers(1, GLHelper.HARDWAREBUFFERID_CONTAINER, 0); + } + + public static void bindTexture(final GL10 pGL, final int pHardwareTextureID) { + /* Reduce unnecessary texture switching calls. */ + if(GLHelper.sCurrentHardwareTextureID != pHardwareTextureID) { + GLHelper.sCurrentHardwareTextureID = pHardwareTextureID; + pGL.glBindTexture(GL10.GL_TEXTURE_2D, pHardwareTextureID); + } + } + + public static void deleteTexture(final GL10 pGL, final int pHardwareTextureID) { + GLHelper.HARDWARETEXTUREID_CONTAINER[0] = pHardwareTextureID; + pGL.glDeleteTextures(1, GLHelper.HARDWARETEXTUREID_CONTAINER, 0); + } + + public static void texCoordPointer(final GL10 pGL, final FastFloatBuffer pTextureFloatBuffer) { + if(GLHelper.sCurrentTextureFloatBuffer != pTextureFloatBuffer) { + GLHelper.sCurrentTextureFloatBuffer = pTextureFloatBuffer; + pGL.glTexCoordPointer(2, GL10.GL_FLOAT, 0, pTextureFloatBuffer.mByteBuffer); + } + } + + public static void texCoordZeroPointer(final GL11 pGL11) { + pGL11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 0); + } + + public static void vertexPointer(final GL10 pGL, final FastFloatBuffer pVertexFloatBuffer) { + if(GLHelper.sCurrentVertexFloatBuffer != pVertexFloatBuffer) { + GLHelper.sCurrentVertexFloatBuffer = pVertexFloatBuffer; + pGL.glVertexPointer(2, GL10.GL_FLOAT, 0, pVertexFloatBuffer.mByteBuffer); + } + } + + public static void vertexZeroPointer(final GL11 pGL11) { + pGL11.glVertexPointer(2, GL10.GL_FLOAT, 0, 0); + } + + public static void blendFunction(final GL10 pGL, final int pSourceBlendMode, final int pDestinationBlendMode) { + if(GLHelper.sCurrentSourceBlendMode != pSourceBlendMode || GLHelper.sCurrentDestinationBlendMode != pDestinationBlendMode) { + GLHelper.sCurrentSourceBlendMode = pSourceBlendMode; + GLHelper.sCurrentDestinationBlendMode = pDestinationBlendMode; + pGL.glBlendFunc(pSourceBlendMode, pDestinationBlendMode); + } + } + + public static void lineWidth(final GL10 pGL, final float pLineWidth) { + if(GLHelper.sLineWidth != pLineWidth) { + GLHelper.sLineWidth = pLineWidth; + pGL.glLineWidth(pLineWidth); + } + } + + public static void switchToModelViewMatrix(final GL10 pGL) { + /* Reduce unnecessary matrix switching calls. */ + if(GLHelper.sCurrentMatrix != GL10.GL_MODELVIEW) { + GLHelper.sCurrentMatrix = GL10.GL_MODELVIEW; + pGL.glMatrixMode(GL10.GL_MODELVIEW); + } + } + + public static void switchToProjectionMatrix(final GL10 pGL) { + /* Reduce unnecessary matrix switching calls. */ + if(GLHelper.sCurrentMatrix != GL10.GL_PROJECTION) { + GLHelper.sCurrentMatrix = GL10.GL_PROJECTION; + pGL.glMatrixMode(GL10.GL_PROJECTION); + } + } + + public static void setProjectionIdentityMatrix(final GL10 pGL) { + GLHelper.switchToProjectionMatrix(pGL); + pGL.glLoadIdentity(); + } + + public static void setModelViewIdentityMatrix(final GL10 pGL) { + GLHelper.switchToModelViewMatrix(pGL); + pGL.glLoadIdentity(); + } + + public static void setShadeModelFlat(final GL10 pGL) { + pGL.glShadeModel(GL10.GL_FLAT); + } + + public static void setPerspectiveCorrectionHintFastest(final GL10 pGL) { + pGL.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); + } + + public static void bufferData(final GL11 pGL11, final ByteBuffer pByteBuffer, final int pUsage) { + pGL11.glBufferData(GL11.GL_ARRAY_BUFFER, pByteBuffer.capacity(), pByteBuffer, pUsage); + } + + /** + * Note: does not pre-multiply the alpha channel!
+ * Except that difference, same as: {@link GLUtils#texSubImage2D(int, int, int, int, Bitmap, int, int)}
+ *
+ * See topic: 'PNG loading that doesn't premultiply alpha?' + */ + public static void glTexSubImage2D(final GL10 pGL, final int target, final int level, final int xoffset, final int yoffset, final Bitmap bitmap, final int format, final int type) { + final int[] pixels = GLHelper.getPixels(bitmap); + + final Buffer pixelBuffer = GLHelper.convertARGBtoRGBABuffer(pixels); + + pGL.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, xoffset, yoffset, bitmap.getWidth(), bitmap.getHeight(), GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuffer); + } + + private static Buffer convertARGBtoRGBABuffer(final int[] pPixels) { + if(GLHelper.IS_LITTLE_ENDIAN) { + for(int i = pPixels.length - 1; i >= 0; i--) { + final int pixel = pPixels[i]; + + final int red = ((pixel >> 16) & 0xFF); + final int green = ((pixel >> 8) & 0xFF); + final int blue = ((pixel) & 0xFF); + final int alpha = (pixel >> 24); + + pPixels[i] = alpha << 24 | blue << 16 | green << 8 | red; + } + } else { + for(int i = pPixels.length - 1; i >= 0; i--) { + final int pixel = pPixels[i]; + + final int red = ((pixel >> 16) & 0xFF); + final int green = ((pixel >> 8) & 0xFF); + final int blue = ((pixel) & 0xFF); + final int alpha = (pixel >> 24); + + pPixels[i] = red << 24 | green << 16 | blue << 8 | alpha; + } + } + return IntBuffer.wrap(pPixels); + } + + public static int[] getPixels(final Bitmap pBitmap) { + final int w = pBitmap.getWidth(); + final int h = pBitmap.getHeight(); + + final int[] pixels = new int[w * h]; + pBitmap.getPixels(pixels, 0, w, 0, 0, w, h); + + return pixels; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/vertex/LineVertexBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/vertex/LineVertexBuffer.java new file mode 100644 index 0000000..87beee6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/vertex/LineVertexBuffer.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.opengl.vertex; + +import org.anddev.andengine.opengl.util.FastFloatBuffer; + +/** + * @author Nicolas Gramlich + * @since 13:07:25 - 13.03.2010 + */ +public class LineVertexBuffer extends VertexBuffer { + // =========================================================== + // Constants + // =========================================================== + + public static final int VERTICES_PER_LINE = 2; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public LineVertexBuffer(final int pDrawType) { + super(2 * VERTICES_PER_LINE, pDrawType); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void update(final float pX1, final float pY1, final float pX2, final float pY2) { + final int[] bufferData = this.mBufferData; + + bufferData[0] = Float.floatToRawIntBits(pX1); + bufferData[1] = Float.floatToRawIntBits(pY1); + + bufferData[2] = Float.floatToRawIntBits(pX2); + bufferData[3] = Float.floatToRawIntBits(pY2); + + final FastFloatBuffer buffer = this.getFloatBuffer(); + buffer.position(0); + buffer.put(bufferData); + buffer.position(0); + + super.setHardwareBufferNeedsUpdate(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/vertex/RectangleVertexBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/vertex/RectangleVertexBuffer.java new file mode 100644 index 0000000..1ccdbd2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/vertex/RectangleVertexBuffer.java @@ -0,0 +1,72 @@ +package org.anddev.andengine.opengl.vertex; + +import org.anddev.andengine.opengl.util.FastFloatBuffer; + +/** + * @author Nicolas Gramlich + * @since 13:07:25 - 13.03.2010 + */ +public class RectangleVertexBuffer extends VertexBuffer { + // =========================================================== + // Constants + // =========================================================== + + public static final int VERTICES_PER_RECTANGLE = 4; + + private static final int FLOAT_TO_RAW_INT_BITS_ZERO = Float.floatToRawIntBits(0); + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RectangleVertexBuffer(final int pDrawType) { + super(2 * VERTICES_PER_RECTANGLE, pDrawType); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void update(final float pWidth, final float pHeight) { + final int x = FLOAT_TO_RAW_INT_BITS_ZERO; + final int y = FLOAT_TO_RAW_INT_BITS_ZERO; + final int x2 = Float.floatToRawIntBits(pWidth); + final int y2 = Float.floatToRawIntBits(pHeight); + + final int[] bufferData = this.mBufferData; + bufferData[0] = x; + bufferData[1] = y; + + bufferData[2] = x; + bufferData[3] = y2; + + bufferData[4] = x2; + bufferData[5] = y; + + bufferData[6] = x2; + bufferData[7] = y2; + + final FastFloatBuffer buffer = this.getFloatBuffer(); + buffer.position(0); + buffer.put(bufferData); + buffer.position(0); + + super.setHardwareBufferNeedsUpdate(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/vertex/TextVertexBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/vertex/TextVertexBuffer.java new file mode 100644 index 0000000..9aa73f4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/vertex/TextVertexBuffer.java @@ -0,0 +1,117 @@ +package org.anddev.andengine.opengl.vertex; + +import org.anddev.andengine.opengl.font.Font; +import org.anddev.andengine.opengl.font.Letter; +import org.anddev.andengine.opengl.util.FastFloatBuffer; +import org.anddev.andengine.util.HorizontalAlign; + +/** + * @author Nicolas Gramlich + * @since 18:05:08 - 07.04.2010 + */ +public class TextVertexBuffer extends VertexBuffer { + // =========================================================== + // Constants + // =========================================================== + + public static final int VERTICES_PER_CHARACTER = 6; + + // =========================================================== + // Fields + // =========================================================== + + private final HorizontalAlign mHorizontalAlign; + + // =========================================================== + // Constructors + // =========================================================== + + public TextVertexBuffer(final int pCharacterCount, final HorizontalAlign pHorizontalAlign, final int pDrawType) { + super(2 * VERTICES_PER_CHARACTER * pCharacterCount, pDrawType); + + this.mHorizontalAlign = pHorizontalAlign; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public synchronized void update(final Font font, final int pMaximumLineWidth, final int[] pWidths, final String[] pLines) { + final int[] bufferData = this.mBufferData; + int i = 0; + + final int lineHeight = font.getLineHeight(); + + final int lineCount = pLines.length; + for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) { + final String line = pLines[lineIndex]; + + int lineX; + switch(this.mHorizontalAlign) { + case RIGHT: + lineX = pMaximumLineWidth - pWidths[lineIndex]; + break; + case CENTER: + lineX = (pMaximumLineWidth - pWidths[lineIndex]) >> 1; + break; + case LEFT: + default: + lineX = 0; + } + + final int lineY = lineIndex * (font.getLineHeight() + font.getLineGap()); + final int lineYBits = Float.floatToRawIntBits(lineY); + + final int lineLength = line.length(); + for (int letterIndex = 0; letterIndex < lineLength; letterIndex++) { + final Letter letter = font.getLetter(line.charAt(letterIndex)); + + final int lineY2 = lineY + lineHeight; + final int lineX2 = lineX + letter.mWidth; + + final int lineXBits = Float.floatToRawIntBits(lineX); + final int lineX2Bits = Float.floatToRawIntBits(lineX2); + final int lineY2Bits = Float.floatToRawIntBits(lineY2); + + bufferData[i++] = lineXBits; + bufferData[i++] = lineYBits; + + bufferData[i++] = lineXBits; + bufferData[i++] = lineY2Bits; + + bufferData[i++] = lineX2Bits; + bufferData[i++] = lineY2Bits; + + bufferData[i++] = lineX2Bits; + bufferData[i++] = lineY2Bits; + + bufferData[i++] = lineX2Bits; + bufferData[i++] = lineYBits; + + bufferData[i++] = lineXBits; + bufferData[i++] = lineYBits; + + lineX += letter.mAdvance; + } + } + + final FastFloatBuffer vertexFloatBuffer = this.getFloatBuffer(); + vertexFloatBuffer.position(0); + vertexFloatBuffer.put(bufferData); + vertexFloatBuffer.position(0); + + super.setHardwareBufferNeedsUpdate(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/vertex/VertexBuffer.java b/AndEngine/src/org/anddev/andengine/opengl/vertex/VertexBuffer.java new file mode 100644 index 0000000..fbe1872 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/vertex/VertexBuffer.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.opengl.vertex; + +import org.anddev.andengine.opengl.buffer.BufferObject; + +/** + * @author Nicolas Gramlich + * @since 12:16:18 - 09.03.2010 + */ +public abstract class VertexBuffer extends BufferObject { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public VertexBuffer(final int pCapacity, final int pDrawType) { + super(pCapacity, pDrawType); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/BaseConfigChooser.java b/AndEngine/src/org/anddev/andengine/opengl/view/BaseConfigChooser.java new file mode 100644 index 0000000..1934dd0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/BaseConfigChooser.java @@ -0,0 +1,70 @@ +/** + * + */ +package org.anddev.andengine.opengl.view; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLDisplay; + +/** + * @author Nicolas Gramlich + * @since 20:42:29 - 28.06.2010 + */ +abstract class BaseConfigChooser implements EGLConfigChooser { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final int[] mConfigSpec; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseConfigChooser(final int[] pConfigSpec) { + this.mConfigSpec = pConfigSpec; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + abstract EGLConfig chooseConfig(final EGL10 pEGL, final EGLDisplay pEGLDisplay, final EGLConfig[] pEGLConfigs); + + @Override + public EGLConfig chooseConfig(final EGL10 pEGL, final EGLDisplay pEGLDisplay) { + final int[] num_config = new int[1]; + pEGL.eglChooseConfig(pEGLDisplay, this.mConfigSpec, null, 0, num_config); + + final int numConfigs = num_config[0]; + + if(numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + + final EGLConfig[] configs = new EGLConfig[numConfigs]; + pEGL.eglChooseConfig(pEGLDisplay, this.mConfigSpec, configs, numConfigs, num_config); + final EGLConfig config = this.chooseConfig(pEGL, pEGLDisplay, configs); + if(config == null) { + throw new IllegalArgumentException("No config chosen"); + } + return config; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/ComponentSizeChooser.java b/AndEngine/src/org/anddev/andengine/opengl/view/ComponentSizeChooser.java new file mode 100644 index 0000000..b013205 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/ComponentSizeChooser.java @@ -0,0 +1,86 @@ +package org.anddev.andengine.opengl.view; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLDisplay; + +/** + * @author Nicolas Gramlich + * @since 20:54:06 - 28.06.2010 + */ +public class ComponentSizeChooser extends BaseConfigChooser { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int[] mValue; + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + + // =========================================================== + // Constructors + // =========================================================== + + public ComponentSizeChooser(final int pRedSize, final int pGreenSize, final int pBlueSize, final int pAlphaSize, final int pDepthSize, final int pStencilSize) { + super(new int[] { EGL10.EGL_RED_SIZE, pRedSize, EGL10.EGL_GREEN_SIZE, pGreenSize, EGL10.EGL_BLUE_SIZE, pBlueSize, EGL10.EGL_ALPHA_SIZE, pAlphaSize, EGL10.EGL_DEPTH_SIZE, pDepthSize, EGL10.EGL_STENCIL_SIZE, pStencilSize, EGL10.EGL_NONE }); + this.mValue = new int[1]; + this.mRedSize = pRedSize; + this.mGreenSize = pGreenSize; + this.mBlueSize = pBlueSize; + this.mAlphaSize = pAlphaSize; + this.mDepthSize = pDepthSize; + this.mStencilSize = pStencilSize; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public EGLConfig chooseConfig(final EGL10 pEGL, final EGLDisplay pEGLDisplay, final EGLConfig[] pEGLConfigs) { + EGLConfig closestConfig = null; + int closestDistance = 1000; + for(final EGLConfig config : pEGLConfigs) { + final int r = this.findConfigAttrib(pEGL, pEGLDisplay, config, EGL10.EGL_RED_SIZE, 0); + final int g = this.findConfigAttrib(pEGL, pEGLDisplay, config, EGL10.EGL_GREEN_SIZE, 0); + final int b = this.findConfigAttrib(pEGL, pEGLDisplay, config, EGL10.EGL_BLUE_SIZE, 0); + final int a = this.findConfigAttrib(pEGL, pEGLDisplay, config, EGL10.EGL_ALPHA_SIZE, 0); + final int d = this.findConfigAttrib(pEGL, pEGLDisplay, config, EGL10.EGL_DEPTH_SIZE, 0); + final int s = this.findConfigAttrib(pEGL, pEGLDisplay, config, EGL10.EGL_STENCIL_SIZE, 0); + final int distance = Math.abs(r - this.mRedSize) + Math.abs(g - this.mGreenSize) + Math.abs(b - this.mBlueSize) + Math.abs(a - this.mAlphaSize) + Math.abs(d - this.mDepthSize) + Math.abs(s - this.mStencilSize); + if(distance < closestDistance) { + closestDistance = distance; + closestConfig = config; + } + } + return closestConfig; + } + + // =========================================================== + // Methods + // =========================================================== + + private int findConfigAttrib(final EGL10 pEGL, final EGLDisplay pEGLDisplay, final EGLConfig pEGLConfig, final int pAttribute, final int pDefaultValue) { + if(pEGL.eglGetConfigAttrib(pEGLDisplay, pEGLConfig, pAttribute, this.mValue)) { + return this.mValue[0]; + } + return pDefaultValue; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/EGLConfigChooser.java b/AndEngine/src/org/anddev/andengine/opengl/view/EGLConfigChooser.java new file mode 100644 index 0000000..79e0fbb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/EGLConfigChooser.java @@ -0,0 +1,38 @@ +package org.anddev.andengine.opengl.view; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLDisplay; + +/** + * An interface for choosing an EGLConfig configuration from a list of + * potential configurations. + *

+ * This interface must be implemented by clients wishing to call + * {@link GLSurfaceView#setEGLConfigChooser(EGLConfigChooser)} + * + * @author Nicolas Gramlich + * @since 20:53:49 - 28.06.2010 + */ +public interface EGLConfigChooser { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * Choose a configuration from the list. Implementors typically + * implement this method by calling {@link EGL10#eglChooseConfig} and + * iterating through the results. Please consult the EGL specification + * available from The Khronos Group to learn how to call + * eglChooseConfig. + * + * @param pEGL the EGL10 for the current display. + * @param pEGLDisplay the current display. + * @return the chosen configuration. + */ + public EGLConfig chooseConfig(final EGL10 pEGL, final EGLDisplay pEGLDisplay); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/GLSurfaceView.java b/AndEngine/src/org/anddev/andengine/opengl/view/GLSurfaceView.java new file mode 100644 index 0000000..e31cad1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/GLSurfaceView.java @@ -0,0 +1,991 @@ +// ############################################################ +// ############################################################ +// +// This class is a replacement for the original GLSurfaceView, due to issue: +// http://code.google.com/p/android/issues/detail?id=2828 +// +// Reason: Two sequential Activities using a GLSurfaceView leads to a deadlock in the GLThread! +// +// ############################################################ +// ############################################################ + +package org.anddev.andengine.opengl.view; + +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGL11; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.egl.EGLSurface; +import javax.microedition.khronos.opengles.GL; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying OpenGL rendering. + *

+ * A GLSurfaceView provides the following features: + *

+ *

    + *
  • Manages a surface, which is a special piece of memory that can be + * composited into the Android view system. + *
  • Manages an EGL display, which enables OpenGL to render into a surface. + *
  • Accepts a user-provided Renderer object that does the actual rendering. + *
  • Renders on a dedicated thread to decouple rendering performance from the + * UI thread. + *
  • Supports both on-demand and continuous rendering. + *
  • Optionally wraps, traces, and/or error-checks the renderer's OpenGL + * calls. + *
+ * + *

Using GLSurfaceView

+ *

+ * Typically you use GLSurfaceView by subclassing it and overriding one or more + * of the View system input event methods. If your application does not need to + * override event methods then GLSurfaceView can be used as-is. For the most + * part GLSurfaceView behavior is customized by calling "set" methods rather + * than by subclassing. For example, unlike a regular View, drawing is delegated + * to a separate Renderer object which is registered with the GLSurfaceView + * using the {@link #setRenderer(Renderer)} call. + *

+ *

Initializing GLSurfaceView

+ * All you have to do to initialize a GLSurfaceView is call + * {@link #setRenderer(Renderer)}. However, if desired, you can modify the + * default behavior of GLSurfaceView by calling one or more of these methods + * before calling setRenderer: + *
    + *
  • {@link #setDebugFlags(int)} + *
  • {@link #setEGLConfigChooser(boolean)} + *
  • {@link #setEGLConfigChooser(EGLConfigChooser)} + *
  • {@link #setEGLConfigChooser(int, int, int, int, int, int)} + *
  • {@link #setGLWrapper(GLWrapper)} + *
+ *

+ *

Choosing an EGL Configuration

+ * A given Android device may support multiple possible types of drawing + * surfaces. The available surfaces may differ in how may channels of data are + * present, as well as how many bits are allocated to each channel. Therefore, + * the first thing GLSurfaceView has to do when starting to render is choose + * what type of surface to use. + *

+ * By default GLSurfaceView chooses an available surface that's closest to a + * 16-bit R5G6B5 surface with a 16-bit depth buffer and no stencil. If you would + * prefer a different surface (for example, if you do not need a depth buffer) + * you can override the default behavior by calling one of the + * setEGLConfigChooser methods. + *

+ *

Debug Behavior

+ * You can optionally modify the behavior of GLSurfaceView by calling one or + * more of the debugging methods {@link #setDebugFlags(int)}, and + * {@link #setGLWrapper}. These methods may be called before and/or after + * setRenderer, but typically they are called before setRenderer so that they + * take effect immediately. + *

+ *

Setting a Renderer

+ * Finally, you must call {@link #setRenderer} to register a {@link Renderer}. + * The renderer is responsible for doing the actual OpenGL rendering. + *

+ *

Rendering Mode

+ * Once the renderer is set, you can control whether the renderer draws + * continuously or on-demand by calling {@link #setRenderMode}. The default is + * continuous rendering. + *

+ *

Activity Life-cycle

+ * A GLSurfaceView must be notified when the activity is paused and resumed. + * GLSurfaceView clients are required to call {@link #onPause()} when the + * activity pauses and {@link #onResume()} when the activity resumes. These + * calls allow GLSurfaceView to pause and resume the rendering thread, and also + * allow GLSurfaceView to release and recreate the OpenGL display. + *

+ *

Handling events

+ *

+ * To handle an event you will typically subclass GLSurfaceView and override the + * appropriate method, just as you would with any other View. However, when + * handling the event, you may need to communicate with the Renderer object + * that's running in the rendering thread. You can do this using any standard + * Java cross-thread communication mechanism. In addition, one relatively easy + * way to communicate with your renderer is to call + * {@link #queueEvent(Runnable)}. For example: + * + *

+ * class MyGLSurfaceView extends GLSurfaceView {
+ * 
+ * 	private MyRenderer mMyRenderer;
+ * 
+ * 	public void start() {
+ *         mMyRenderer = ...;
+ *         setRenderer(mMyRenderer);
+ *     }
+ * 
+ * 	public boolean onKeyDown(int keyCode, KeyEvent event) {
+ * 		if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
+ * 			queueEvent(new Runnable() {
+ * 				// This method will be called on the rendering
+ * 				// thread:
+ * 				public void run() {
+ * 					mMyRenderer.handleDpadCenter();
+ * 				}
+ * 			});
+ * 			return true;
+ * 		}
+ * 		return super.onKeyDown(keyCode, event);
+ * 	}
+ * }
+ * 
+ * + */ +public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + // =========================================================== + // Constants + // =========================================================== + + /** + * The renderer only renders when the surface is created, or when + * {@link #requestRender} is called. + * + * @see #getRenderMode() + * @see #setRenderMode(int) + */ + public final static int RENDERMODE_WHEN_DIRTY = 0; + /** + * The renderer is called continuously to re-render the scene. + * + * @see #getRenderMode() + * @see #setRenderMode(int) + * @see #requestRender() + */ + public final static int RENDERMODE_CONTINUOUSLY = 1; + + /** + * Check glError() after every GL call and throw an exception if glError + * indicates that an error has occurred. This can be used to help track down + * which OpenGL ES call is causing an error. + * + * @see #getDebugFlags + * @see #setDebugFlags + */ + public final static int DEBUG_CHECK_GL_ERROR = 1; + + /** + * Log GL calls to the system log at "verbose" level with tag + * "GLSurfaceView". + * + * @see #getDebugFlags + * @see #setDebugFlags + */ + public final static int DEBUG_LOG_GL_CALLS = 2; + + private static final Semaphore sEglSemaphore = new Semaphore(1); + + // =========================================================== + // Fields + // =========================================================== + + private GLThread mGLThread; + private EGLConfigChooser mEGLConfigChooser; + private GLWrapper mGLWrapper; + private int mDebugFlags; + private int mRenderMode; + private Renderer mRenderer; + private int mSurfaceWidth; + private int mSurfaceHeight; + private boolean mHasSurface; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * Standard View constructor. In order to render something, you must call + * {@link #setRenderer} to register a renderer. + */ + public GLSurfaceView(final Context context) { + super(context); + this.init(); + } + + /** + * Standard View constructor. In order to render something, you must call + * {@link #setRenderer} to register a renderer. + */ + public GLSurfaceView(final Context context, final AttributeSet attrs) { + super(context, attrs); + this.init(); + } + + private void init() { + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed + final SurfaceHolder holder = this.getHolder(); + holder.addCallback(this); + holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); + this.mRenderMode = RENDERMODE_CONTINUOUSLY; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + /** + * Set the glWrapper. If the glWrapper is not null, its + * {@link GLWrapper#wrap(GL)} method is called whenever a surface is + * created. A GLWrapper can be used to wrap the GL object that's passed to + * the renderer. Wrapping a GL object enables examining and modifying the + * behavior of the GL calls made by the renderer. + *

+ * Wrapping is typically used for debugging purposes. + *

+ * The default value is null. + * + * @param glWrapper + * the new GLWrapper + */ + public void setGLWrapper(final GLWrapper glWrapper) { + this.mGLWrapper = glWrapper; + } + + /** + * Set the debug flags to a new value. The value is constructed by + * OR-together zero or more of the DEBUG_CHECK_* constants. The debug flags + * take effect whenever a surface is created. The default value is zero. + * + * @param debugFlags + * the new debug flags + * @see #DEBUG_CHECK_GL_ERROR + * @see #DEBUG_LOG_GL_CALLS + */ + public void setDebugFlags(final int debugFlags) { + this.mDebugFlags = debugFlags; + } + + /** + * Get the current value of the debug flags. + * + * @return the current value of the debug flags. + */ + public int getDebugFlags() { + return this.mDebugFlags; + } + + /** + * Set the renderer associated with this view. Also starts the thread that + * will call the renderer, which in turn causes the rendering to start. + *

+ * This method should be called once and only once in the life-cycle of a + * GLSurfaceView. + *

+ * The following GLSurfaceView methods can only be called before + * setRenderer is called: + *

    + *
  • {@link #setEGLConfigChooser(boolean)} + *
  • {@link #setEGLConfigChooser(EGLConfigChooser)} + *
  • {@link #setEGLConfigChooser(int, int, int, int, int, int)} + *
+ *

+ * The following GLSurfaceView methods can only be called after + * setRenderer is called: + *

    + *
  • {@link #getRenderMode()} + *
  • {@link #onPause()} + *
  • {@link #onResume()} + *
  • {@link #queueEvent(Runnable)} + *
  • {@link #requestRender()} + *
  • {@link #setRenderMode(int)} + *
+ * + * @param renderer + * the renderer to use to perform OpenGL drawing. + */ + public void setRenderer(final Renderer renderer) { + if(this.mRenderer != null) { + throw new IllegalStateException("setRenderer has already been called for this instance."); + } + + this.mRenderer = renderer; + } + + /** + * Install a custom EGLConfigChooser. + *

+ * If this method is called, it must be called before + * {@link #setRenderer(Renderer)} is called. + *

+ * If no setEGLConfigChooser method is called, then by default the view will + * choose a config as close to 16-bit RGB as possible, with a depth buffer + * as close to 16 bits as possible. + * + * @param configChooser + */ + public void setEGLConfigChooser(final EGLConfigChooser configChooser) { + if(this.mRenderer != null) { + throw new IllegalStateException("setRenderer has already been called for this instance."); + } + this.mEGLConfigChooser = configChooser; + } + + /** + * Install a config chooser which will choose a config as close to 16-bit + * RGB as possible, with or without an optional depth buffer as close to + * 16-bits as possible. + *

+ * If this method is called, it must be called before + * {@link #setRenderer(Renderer)} is called. + *

+ * If no setEGLConfigChooser method is called, then by default the view will + * choose a config as close to 16-bit RGB as possible, with a depth buffer + * as close to 16 bits as possible. + * + * @param needDepth + */ + public void setEGLConfigChooser(final boolean needDepth) { + this.setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth)); + } + + /** + * Install a config chooser which will choose a config with at least the + * specified component sizes, and as close to the specified component sizes + * as possible. + *

+ * If this method is called, it must be called before + * {@link #setRenderer(Renderer)} is called. + *

+ * If no setEGLConfigChooser method is called, then by default the view will + * choose a config as close to 16-bit RGB as possible, with a depth buffer + * as close to 16 bits as possible. + * + */ + public void setEGLConfigChooser(final int redSize, final int greenSize, final int blueSize, final int alphaSize, final int depthSize, final int stencilSize) { + this.setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize)); + } + + /** + * Set the rendering mode. When renderMode is RENDERMODE_CONTINUOUSLY, the + * renderer is called repeatedly to re-render the scene. When renderMode is + * RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface is + * created, or when {@link #requestRender} is called. Defaults to + * RENDERMODE_CONTINUOUSLY. + *

+ * Using RENDERMODE_WHEN_DIRTY can improve battery life and overall system + * performance by allowing the GPU and CPU to idle when the view does not + * need to be updated. + *

+ * This method can only be called after {@link #setRenderer(Renderer)} + * + * @param renderMode + * one of the RENDERMODE_X constants + * @see #RENDERMODE_CONTINUOUSLY + * @see #RENDERMODE_WHEN_DIRTY + */ + public void setRenderMode(final int renderMode) { + this.mRenderMode = renderMode; + if(this.mGLThread != null) { + this.mGLThread.setRenderMode(renderMode); + } + } + + /** + * Get the current rendering mode. May be called from any thread. Must not + * be called before a renderer has been set. + * + * @return the current rendering mode. + * @see #RENDERMODE_CONTINUOUSLY + * @see #RENDERMODE_WHEN_DIRTY + */ + public int getRenderMode() { + return this.mRenderMode; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + /** + * Request that the renderer render a frame. This method is typically used + * when the render mode has been set to {@link #RENDERMODE_WHEN_DIRTY}, so + * that frames are only rendered on demand. May be called from any thread. + * Must be called after onResume() and before onPause(). + */ + public void requestRender() { + this.mGLThread.requestRender(); + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is not + * normally called or subclassed by clients of GLSurfaceView. + */ + @Override + public void surfaceCreated(final SurfaceHolder holder) { + if(this.mGLThread != null) { + this.mGLThread.surfaceCreated(); + } + this.mHasSurface = true; + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is not + * normally called or subclassed by clients of GLSurfaceView. + */ + @Override + public void surfaceDestroyed(final SurfaceHolder holder) { + // Surface will be destroyed when we return + if(this.mGLThread != null) { + this.mGLThread.surfaceDestroyed(); + } + this.mHasSurface = false; + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is not + * normally called or subclassed by clients of GLSurfaceView. + */ + @Override + public void surfaceChanged(final SurfaceHolder holder, final int format, final int w, final int h) { + if(this.mGLThread != null) { + this.mGLThread.onWindowResize(w, h); + } + this.mSurfaceWidth = w; + this.mSurfaceHeight = h; + } + + /** + * Inform the view that the activity is paused. The owner of this view must + * call this method when the activity is paused. Calling this method will + * pause the rendering thread. Must not be called before a renderer has been + * set. + */ + public void onPause() { + this.mGLThread.onPause(); + this.mGLThread.requestExitAndWait(); + this.mGLThread = null; + } + + /** + * Inform the view that the activity is resumed. The owner of this view must + * call this method when the activity is resumed. Calling this method will + * recreate the OpenGL display and resume the rendering thread. Must not be + * called before a renderer has been set. + */ + public void onResume() { + if(this.mEGLConfigChooser == null) { + this.mEGLConfigChooser = new SimpleEGLConfigChooser(true); + } + this.mGLThread = new GLThread(this.mRenderer); + this.mGLThread.start(); + this.mGLThread.setRenderMode(this.mRenderMode); + if(this.mHasSurface) { + this.mGLThread.surfaceCreated(); + } + if(this.mSurfaceWidth > 0 && this.mSurfaceHeight > 0) { + this.mGLThread.onWindowResize(this.mSurfaceWidth, this.mSurfaceHeight); + } + this.mGLThread.onResume(); + } + + /** + * Queue a runnable to be run on the GL rendering thread. This can be used + * to communicate with the Renderer on the rendering thread. Must be called + * after onResume() and before onPause(). + * + * @param r + * the runnable to be run on the GL rendering thread. + */ + public void queueEvent(final Runnable r) { + if(this.mGLThread != null) { + this.mGLThread.queueEvent(r); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + /** + * A generic GL Thread. Takes care of initializing EGL and GL. Delegates to + * a Renderer instance to do the actual drawing. Can be configured to render + * continuously or on request. + * + */ + class GLThread extends Thread { + GLThread(final Renderer renderer) { + super(); + this.mDone = false; + this.mWidth = 0; + this.mHeight = 0; + this.mRequestRender = true; + this.mRenderMode = RENDERMODE_CONTINUOUSLY; + this.mRenderer = renderer; + this.mSizeChanged = true; + this.setName("GLThread"); + } + + @Override + public void run() { + /* + * When the android framework launches a second instance of an + * activity, the new instance's onCreate() method may be called + * before the first instance returns from onDestroy(). + * + * This semaphore ensures that only one instance at a time accesses + * EGL. + */ + try { + try { + sEglSemaphore.acquire(); + } catch (final InterruptedException e) { + return; + } + this.guardedRun(); + } catch (final InterruptedException e) { + // fall thru and exit normally + } finally { + sEglSemaphore.release(); + } + } + + private void guardedRun() throws InterruptedException { + this.mEglHelper = new EglHelper(); + this.mEglHelper.start(); + + GL10 gl = null; + boolean tellRendererSurfaceCreated = true; + boolean tellRendererSurfaceChanged = true; + + /* + * This is our main activity thread's loop, we go until asked to + * quit. + */ + while(!this.mDone) { + + /* + * Update the asynchronous state (window size) + */ + int w, h; + boolean changed; + boolean needStart = false; + synchronized (this) { + Runnable r; + while((r = this.getEvent()) != null) { + r.run(); + } + if(this.mPaused) { + this.mEglHelper.finish(); + needStart = true; + } + while(this.needToWait()) { + this.wait(); + } + if(this.mDone) { + break; + } + changed = this.mSizeChanged; + w = this.mWidth; + h = this.mHeight; + this.mSizeChanged = false; + this.mRequestRender = false; + } + if(needStart) { + this.mEglHelper.start(); + tellRendererSurfaceCreated = true; + changed = true; + } + if(changed) { + gl = (GL10) this.mEglHelper.createSurface(GLSurfaceView.this.getHolder()); + tellRendererSurfaceChanged = true; + } + if(tellRendererSurfaceCreated) { + this.mRenderer.onSurfaceCreated(gl, this.mEglHelper.mEglConfig); + tellRendererSurfaceCreated = false; + } + if(tellRendererSurfaceChanged) { + this.mRenderer.onSurfaceChanged(gl, w, h); + tellRendererSurfaceChanged = false; + } + if((w > 0) && (h > 0)) { + /* draw a frame here */ + this.mRenderer.onDrawFrame(gl); + + /* + * Once we're done with GL, we need to call swapBuffers() to + * instruct the system to display the rendered frame + */ + this.mEglHelper.swap(); + } + } + + /* + * clean-up everything... + */ + this.mEglHelper.finish(); + } + + private boolean needToWait() { + if(this.mDone) { + return false; + } + + if(this.mPaused || (!this.mHasSurface)) { + return true; + } + + if((this.mWidth > 0) && (this.mHeight > 0) && (this.mRequestRender || (this.mRenderMode == RENDERMODE_CONTINUOUSLY))) { + return false; + } + + return true; + } + + public void setRenderMode(final int renderMode) { + if(!((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY))) { + throw new IllegalArgumentException("renderMode"); + } + synchronized (this) { + this.mRenderMode = renderMode; + if(renderMode == RENDERMODE_CONTINUOUSLY) { + this.notify(); + } + } + } + + public int getRenderMode() { + synchronized (this) { + return this.mRenderMode; + } + } + + public void requestRender() { + synchronized (this) { + this.mRequestRender = true; + this.notify(); + } + } + + public void surfaceCreated() { + synchronized (this) { + this.mHasSurface = true; + this.notify(); + } + } + + public void surfaceDestroyed() { + synchronized (this) { + this.mHasSurface = false; + this.notify(); + } + } + + public void onPause() { + synchronized (this) { + this.mPaused = true; + } + } + + public void onResume() { + synchronized (this) { + this.mPaused = false; + this.notify(); + } + } + + public void onWindowResize(final int w, final int h) { + synchronized (this) { + this.mWidth = w; + this.mHeight = h; + this.mSizeChanged = true; + this.notify(); + } + } + + public void requestExitAndWait() { + // don't call this from GLThread thread or it is a guaranteed + // deadlock! + synchronized (this) { + this.mDone = true; + this.notify(); + } + try { + this.join(); + } catch (final InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + + /** + * Queue an "event" to be run on the GL rendering thread. + * + * @param r + * the runnable to be run on the GL rendering thread. + */ + public void queueEvent(final Runnable r) { + synchronized (this) { + this.mEventQueue.add(r); + } + } + + private Runnable getEvent() { + synchronized (this) { + if(this.mEventQueue.size() > 0) { + return this.mEventQueue.remove(0); + } + + } + return null; + } + + private boolean mDone; + private boolean mPaused; + private boolean mHasSurface; + private int mWidth; + private int mHeight; + private int mRenderMode; + private boolean mRequestRender; + private final Renderer mRenderer; + private final ArrayList mEventQueue = new ArrayList(); + private EglHelper mEglHelper; + private boolean mSizeChanged; + } + + /** + * An EGL helper class. + */ + + class EglHelper { + public EglHelper() { + + } + + /** + * Initialize EGL for a given configuration spec. + * + * @param configSpec + */ + public void start() { + /* + * Get an EGL instance + */ + this.mEgl = (EGL10) EGLContext.getEGL(); + + /* + * Get to the default display. + */ + this.mEglDisplay = this.mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); + + /* + * We can now initialize EGL for that display + */ + final int[] version = new int[2]; + this.mEgl.eglInitialize(this.mEglDisplay, version); + this.mEglConfig = GLSurfaceView.this.mEGLConfigChooser.chooseConfig(this.mEgl, this.mEglDisplay); + + /* + * Create an OpenGL ES context. This must be done only once, an + * OpenGL context is a somewhat heavy object. + */ + this.mEglContext = this.mEgl.eglCreateContext(this.mEglDisplay, this.mEglConfig, EGL10.EGL_NO_CONTEXT, null); + + this.mEglSurface = null; + } + + /* + * React to the creation of a new surface by creating and returning an + * OpenGL interface that renders to that surface. + */ + public GL createSurface(final SurfaceHolder holder) { + /* + * The window size has changed, so we need to create a new surface. + */ + if(this.mEglSurface != null) { + + /* + * Unbind and destroy the old EGL surface, if there is one. + */ + this.mEgl.eglMakeCurrent(this.mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + this.mEgl.eglDestroySurface(this.mEglDisplay, this.mEglSurface); + } + + /* + * Create an EGL surface we can render into. + */ + this.mEglSurface = this.mEgl.eglCreateWindowSurface(this.mEglDisplay, this.mEglConfig, holder, null); + + /* + * Before we can issue GL commands, we need to make sure the context + * is current and bound to a surface. + */ + this.mEgl.eglMakeCurrent(this.mEglDisplay, this.mEglSurface, this.mEglSurface, this.mEglContext); + + GL gl = this.mEglContext.getGL(); + if(GLSurfaceView.this.mGLWrapper != null) { + gl = GLSurfaceView.this.mGLWrapper.wrap(gl); + } + + /* Debugging disabled */ + /* + * if ((mDebugFlags & (DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS))!= + * 0) { int configFlags = 0; Writer log = null; if ((mDebugFlags & + * DEBUG_CHECK_GL_ERROR) != 0) { configFlags |= + * GLDebugHelper.CONFIG_CHECK_GL_ERROR; } if ((mDebugFlags & + * DEBUG_LOG_GL_CALLS) != 0) { log = new LogWriter(); } gl = + * GLDebugHelper.wrap(gl, configFlags, log); } + */ + return gl; + } + + /** + * Display the current render surface. + * + * @return false if the context has been lost. + */ + public boolean swap() { + this.mEgl.eglSwapBuffers(this.mEglDisplay, this.mEglSurface); + + /* + * Always check for EGL_CONTEXT_LOST, which means the context and + * all associated data were lost (For instance because the device + * went to sleep). We need to sleep until we get a new surface. + */ + return this.mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST; + } + + public void finish() { + if(this.mEglSurface != null) { + this.mEgl.eglMakeCurrent(this.mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + this.mEgl.eglDestroySurface(this.mEglDisplay, this.mEglSurface); + this.mEglSurface = null; + } + if(this.mEglContext != null) { + this.mEgl.eglDestroyContext(this.mEglDisplay, this.mEglContext); + this.mEglContext = null; + } + if(this.mEglDisplay != null) { + this.mEgl.eglTerminate(this.mEglDisplay); + this.mEglDisplay = null; + } + } + + EGL10 mEgl; + EGLDisplay mEglDisplay; + EGLSurface mEglSurface; + EGLConfig mEglConfig; + EGLContext mEglContext; + } + + /** + * A generic renderer interface. + *

+ * The renderer is responsible for making OpenGL calls to render a frame. + *

+ * GLSurfaceView clients typically create their own classes that implement + * this interface, and then call {@link GLSurfaceView#setRenderer} to + * register the renderer with the GLSurfaceView. + *

+ *

Threading

+ * The renderer will be called on a separate thread, so that rendering + * performance is decoupled from the UI thread. Clients typically need to + * communicate with the renderer from the UI thread, because that's where + * input events are received. Clients can communicate using any of the + * standard Java techniques for cross-thread communication, or they can use + * the {@link GLSurfaceView#queueEvent(Runnable)} convenience method. + *

+ *

EGL Context Lost

+ * There are situations where the EGL rendering context will be lost. This + * typically happens when device wakes up after going to sleep. When the EGL + * context is lost, all OpenGL resources (such as textures) that are + * associated with that context will be automatically deleted. In order to + * keep rendering correctly, a renderer must recreate any lost resources + * that it still needs. The {@link #onSurfaceCreated(GL10, EGLConfig)} + * method is a convenient place to do this. + * + * + * @see #setRenderer(Renderer) + */ + public interface Renderer { + /** + * Called when the surface is created or recreated. + *

+ * Called when the rendering thread starts and whenever the EGL context + * is lost. The context will typically be lost when the Android device + * awakes after going to sleep. + *

+ * Since this method is called at the beginning of rendering, as well as + * every time the EGL context is lost, this method is a convenient place + * to put code to create resources that need to be created when the + * rendering starts, and that need to be recreated when the EGL context + * is lost. Textures are an example of a resource that you might want to + * create here. + *

+ * Note that when the EGL context is lost, all OpenGL resources + * associated with that context will be automatically deleted. You do + * not need to call the corresponding "glDelete" methods such as + * glDeleteTextures to manually delete these lost resources. + *

+ * + * @param gl + * the GL interface. Use instanceof to test if + * the interface supports GL11 or higher interfaces. + * @param config + * the EGLConfig of the created surface. Can be used to + * create matching pbuffers. + */ + void onSurfaceCreated(GL10 gl, EGLConfig config); + + /** + * Called when the surface changed size. + *

+ * Called after the surface is created and whenever the OpenGL ES + * surface size changes. + *

+ * Typically you will set your viewport here. If your camera is fixed + * then you could also set your projection matrix here: + * + *

+		 * void onSurfaceChanged(GL10 gl, int width, int height) {
+		 * 	gl.glViewport(0, 0, width, height);
+		 * 	// for a fixed camera, set the projection too
+		 * 	float ratio = (float) width / height;
+		 * 	gl.glMatrixMode(GL10.GL_PROJECTION);
+		 * 	gl.glLoadIdentity();
+		 * 	gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+		 * }
+		 * 
+ * + * @param gl + * the GL interface. Use instanceof to test if + * the interface supports GL11 or higher interfaces. + * @param width + * @param height + */ + void onSurfaceChanged(GL10 gl, int width, int height); + + /** + * Called to draw the current frame. + *

+ * This method is responsible for drawing the current frame. + *

+ * The implementation of this method typically looks like this: + * + *

+		 * void onDrawFrame(GL10 gl) {
+		 * 	gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+		 * 	//... other gl calls to render the scene ...
+		 * }
+		 * 
+ * + * @param gl + * the GL interface. Use instanceof to test if + * the interface supports GL11 or higher interfaces. + */ + void onDrawFrame(GL10 gl); + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/GLWrapper.java b/AndEngine/src/org/anddev/andengine/opengl/view/GLWrapper.java new file mode 100644 index 0000000..b3e95d9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/GLWrapper.java @@ -0,0 +1,47 @@ +package org.anddev.andengine.opengl.view; + +import javax.microedition.khronos.opengles.GL; + +/** + * An interface used to wrap a GL interface. + *

+ * Typically used for implementing debugging and tracing on top of the default + * GL interface. You would typically use this by creating your own class that + * implemented all the GL methods by delegating to another GL instance. Then you + * could add your own behavior before or after calling the delegate. All the + * GLWrapper would do was instantiate and return the wrapper GL instance: + * + *

+ * class MyGLWrapper implements GLWrapper {
+ *     GL wrap(GL gl) {
+ *         return new MyGLImplementation(gl);
+ *     }
+ *     static class MyGLImplementation implements GL,GL10,GL11,... {
+ *         ...
+ *     }
+ * }
+ * 
+ * + * @see #setGLWrapper(GLWrapper) + * + * @author Nicolas Gramlich + * @since 20:53:38 - 28.06.2010 + */ +public interface GLWrapper { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * Wraps a gl interface in another gl interface. + * + * @param pGL a GL interface that is to be wrapped. + * @return either the input argument or another GL object that wraps the + * input argument. + */ + public GL wrap(final GL pGL); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/LogWriter.java b/AndEngine/src/org/anddev/andengine/opengl/view/LogWriter.java new file mode 100644 index 0000000..d5bf7f7 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/LogWriter.java @@ -0,0 +1,73 @@ +/** + * + */ +package org.anddev.andengine.opengl.view; + +import java.io.Writer; + +import android.util.Log; + +/** + * @author Nicolas Gramlich + * @since 20:42:02 - 28.06.2010 + */ +class LogWriter extends Writer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final StringBuilder mBuilder = new StringBuilder(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void close() { + this.flushBuilder(); + } + + @Override + public void flush() { + this.flushBuilder(); + } + + @Override + public void write(final char[] buf, final int offset, final int count) { + for(int i = 0; i < count; i++) { + final char c = buf[offset + i]; + if(c == '\n') { + this.flushBuilder(); + } else { + this.mBuilder.append(c); + } + } + } + + // =========================================================== + // Methods + // =========================================================== + + private void flushBuilder() { + if(this.mBuilder.length() > 0) { + Log.v("GLSurfaceView", this.mBuilder.toString()); + this.mBuilder.delete(0, this.mBuilder.length()); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/RenderSurfaceView.java b/AndEngine/src/org/anddev/andengine/opengl/view/RenderSurfaceView.java new file mode 100644 index 0000000..7363430 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/RenderSurfaceView.java @@ -0,0 +1,162 @@ +package org.anddev.andengine.opengl.view; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import org.anddev.andengine.engine.Engine; +import org.anddev.andengine.opengl.util.GLHelper; +import org.anddev.andengine.util.Debug; + +import android.content.Context; +import android.util.AttributeSet; + +/** + * @author Nicolas Gramlich + * @since 11:57:29 - 08.03.2010 + */ +public class RenderSurfaceView extends GLSurfaceView { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private Renderer mRenderer; + + // =========================================================== + // Constructors + // =========================================================== + + public RenderSurfaceView(final Context pContext) { + super(pContext); + } + + public RenderSurfaceView(final Context pContext, final AttributeSet pAttrs) { + super(pContext, pAttrs); + } + + public void setRenderer(final Engine pEngine) { + this.setOnTouchListener(pEngine); + this.mRenderer = new Renderer(pEngine); + this.setRenderer(this.mRenderer); + } + + /** + * @see android.view.View#measure(int, int) + */ + @Override + protected void onMeasure(final int pWidthMeasureSpec, final int pHeightMeasureSpec) { + this.mRenderer.mEngine.getEngineOptions().getResolutionPolicy().onMeasure(this, pWidthMeasureSpec, pHeightMeasureSpec); + } + + public void setMeasuredDimensionProxy(final int pMeasuredWidth, final int pMeasuredHeight) { + this.setMeasuredDimension(pMeasuredWidth, pMeasuredHeight); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + /** + * @author Nicolas Gramlich + * @since 11:45:59 - 08.03.2010 + */ + public static class Renderer implements GLSurfaceView.Renderer { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Engine mEngine; + + // =========================================================== + // Constructors + // =========================================================== + + public Renderer(final Engine pEngine) { + this.mEngine = pEngine; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onSurfaceChanged(final GL10 pGL, final int pWidth, final int pHeight) { + Debug.d("onSurfaceChanged: pWidth=" + pWidth + " pHeight=" + pHeight); + this.mEngine.setSurfaceSize(pWidth, pHeight); + pGL.glViewport(0, 0, pWidth, pHeight); + pGL.glLoadIdentity(); + } + + @Override + public void onSurfaceCreated(final GL10 pGL, final EGLConfig pConfig) { + Debug.d("onSurfaceCreated"); + GLHelper.reset(pGL); + + GLHelper.setPerspectiveCorrectionHintFastest(pGL); + // pGL.glEnable(GL10.GL_POLYGON_SMOOTH); + // pGL.glHint(GL10.GL_POLYGON_SMOOTH_HINT, GL10.GL_NICEST); + // pGL.glEnable(GL10.GL_LINE_SMOOTH); + // pGL.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST); + // pGL.glEnable(GL10.GL_POINT_SMOOTH); + // pGL.glHint(GL10.GL_POINT_SMOOTH_HINT, GL10.GL_NICEST); + + GLHelper.setShadeModelFlat(pGL); + + GLHelper.disableLightning(pGL); + GLHelper.disableDither(pGL); + GLHelper.disableDepthTest(pGL); + GLHelper.disableMultisample(pGL); + + GLHelper.enableBlend(pGL); + GLHelper.enableTextures(pGL); + GLHelper.enableTexCoordArray(pGL); + GLHelper.enableVertexArray(pGL); + + GLHelper.enableCulling(pGL); + pGL.glFrontFace(GL10.GL_CCW); + pGL.glCullFace(GL10.GL_BACK); + + GLHelper.enableExtensions(pGL, this.mEngine.getEngineOptions().getRenderOptions()); + } + + @Override + public void onDrawFrame(final GL10 pGL) { + try { + this.mEngine.onDrawFrame(pGL); + } catch (final InterruptedException e) { + Debug.e("GLThread interrupted!", e); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/opengl/view/SimpleEGLConfigChooser.java b/AndEngine/src/org/anddev/andengine/opengl/view/SimpleEGLConfigChooser.java new file mode 100644 index 0000000..86a37c5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/opengl/view/SimpleEGLConfigChooser.java @@ -0,0 +1,48 @@ +package org.anddev.andengine.opengl.view; + + +/** + * This class will choose a supported surface as close to RGB565 as + * possible, with or without a depth buffer. + * + * @author Nicolas Gramlich + * @since 20:53:29 - 28.06.2010 + */ +class SimpleEGLConfigChooser extends ComponentSizeChooser { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SimpleEGLConfigChooser(final boolean pWithDepthBuffer) { + super(4, 4, 4, 0, pWithDepthBuffer ? 16 : 0, 0); + // Adjust target values. This way we'll accept a 4444 or + // 555 buffer if there's no 565 buffer available. + this.mRedSize = 5; + this.mGreenSize = 6; + this.mBlueSize = 5; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/sensor/BaseSensorData.java b/AndEngine/src/org/anddev/andengine/sensor/BaseSensorData.java new file mode 100644 index 0000000..2c77924 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/BaseSensorData.java @@ -0,0 +1,65 @@ +package org.anddev.andengine.sensor; + +import java.util.Arrays; + +/** + * @author Nicolas Gramlich + * @since 16:50:44 - 10.03.2010 + */ +public class BaseSensorData { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final float[] mValues; + protected int mAccuracy; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseSensorData(final int pValueCount) { + this.mValues = new float[pValueCount]; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float[] getValues() { + return this.mValues; + } + + public void setValues(final float[] pValues) { + System.arraycopy(pValues, 0, mValues, 0, pValues.length); + } + + public void setAccuracy(final int pAccuracy) { + this.mAccuracy = pAccuracy; + } + + public int getAccuracy() { + return this.mAccuracy; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public String toString() { + return "Values: " + Arrays.toString(this.mValues); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/SensorDelay.java b/AndEngine/src/org/anddev/andengine/sensor/SensorDelay.java new file mode 100644 index 0000000..5c3bfa5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/SensorDelay.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.sensor; + +import android.hardware.SensorManager; + + +/** + * @author Nicolas Gramlich + * @since 11:14:38 - 31.10.2010 + */ +public enum SensorDelay { + // =========================================================== + // Elements + // =========================================================== + + NORMAL(SensorManager.SENSOR_DELAY_NORMAL), + UI(SensorManager.SENSOR_DELAY_UI), + GAME(SensorManager.SENSOR_DELAY_GAME), + FASTEST(SensorManager.SENSOR_DELAY_FASTEST); + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mDelay; + + // =========================================================== + // Constructors + // =========================================================== + + private SensorDelay(final int pDelay) { + this.mDelay = pDelay; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getDelay() { + return this.mDelay; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/accelerometer/AccelerometerData.java b/AndEngine/src/org/anddev/andengine/sensor/accelerometer/AccelerometerData.java new file mode 100644 index 0000000..b734e8a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/accelerometer/AccelerometerData.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.sensor.accelerometer; + +import java.util.Arrays; + +import org.anddev.andengine.sensor.BaseSensorData; + +import android.hardware.SensorManager; + +/** + * @author Nicolas Gramlich + * @since 16:50:44 - 10.03.2010 + */ +public class AccelerometerData extends BaseSensorData { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public AccelerometerData() { + super(3); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getX() { + return this.mValues[SensorManager.DATA_X]; + } + + public float getY() { + return this.mValues[SensorManager.DATA_Y]; + } + + public float getZ() { + return this.mValues[SensorManager.DATA_Z]; + } + + public void setX(final float pX) { + this.mValues[SensorManager.DATA_X] = pX; + } + + public void setY(final float pY) { + this.mValues[SensorManager.DATA_Y] = pY; + } + + public void setZ(final float pZ) { + this.mValues[SensorManager.DATA_Z] = pZ; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public String toString() { + return "Accelerometer: " + Arrays.toString(this.mValues); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/accelerometer/AccelerometerSensorOptions.java b/AndEngine/src/org/anddev/andengine/sensor/accelerometer/AccelerometerSensorOptions.java new file mode 100644 index 0000000..ce9b3f3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/accelerometer/AccelerometerSensorOptions.java @@ -0,0 +1,47 @@ +package org.anddev.andengine.sensor.accelerometer; + +import org.anddev.andengine.sensor.SensorDelay; + +/** + * @author Nicolas Gramlich + * @since 11:10:34 - 31.10.2010 + */ +public class AccelerometerSensorOptions { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + final SensorDelay mSensorDelay; + + // =========================================================== + // Constructors + // =========================================================== + + public AccelerometerSensorOptions(final SensorDelay pSensorDelay) { + this.mSensorDelay = pSensorDelay; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public SensorDelay getSensorDelay() { + return this.mSensorDelay; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/accelerometer/IAccelerometerListener.java b/AndEngine/src/org/anddev/andengine/sensor/accelerometer/IAccelerometerListener.java new file mode 100644 index 0000000..eb33153 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/accelerometer/IAccelerometerListener.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.sensor.accelerometer; + +/** + * @author Nicolas Gramlich + * @since 16:58:38 - 10.03.2010 + */ +public interface IAccelerometerListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onAccelerometerChanged(final AccelerometerData pAccelerometerData); +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/location/ILocationListener.java b/AndEngine/src/org/anddev/andengine/sensor/location/ILocationListener.java new file mode 100644 index 0000000..1a499eb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/location/ILocationListener.java @@ -0,0 +1,41 @@ +package org.anddev.andengine.sensor.location; + +import android.location.Location; +import android.location.LocationListener; +import android.os.Bundle; + +/** + * @author Nicolas Gramlich + * @since 10:39:23 - 31.10.2010 + */ +public interface ILocationListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * @see {@link LocationListener#onProviderEnabled(String)} + */ + public void onLocationProviderEnabled(); + + /** + * @see {@link LocationListener#onLocationChanged(Location)} + */ + public void onLocationChanged(final Location pLocation); + + public void onLocationLost(); + + /** + * @see {@link LocationListener#onProviderDisabled(String)} + */ + public void onLocationProviderDisabled(); + + /** + * @see {@link LocationListener#onStatusChanged(String, int, android.os.Bundle)} + */ + public void onLocationProviderStatusChanged(final LocationProviderStatus pLocationProviderStatus, final Bundle pBundle); +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/location/LocationProviderStatus.java b/AndEngine/src/org/anddev/andengine/sensor/location/LocationProviderStatus.java new file mode 100644 index 0000000..a86b103 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/location/LocationProviderStatus.java @@ -0,0 +1,43 @@ +package org.anddev.andengine.sensor.location; + +/** + * @author Nicolas Gramlich + * @since 10:55:57 - 31.10.2010 + */ +public enum LocationProviderStatus { + // =========================================================== + // Elements + // =========================================================== + + AVAILABLE, + OUT_OF_SERVICE, + TEMPORARILY_UNAVAILABLE; + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/location/LocationSensorOptions.java b/AndEngine/src/org/anddev/andengine/sensor/location/LocationSensorOptions.java new file mode 100644 index 0000000..881f753 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/location/LocationSensorOptions.java @@ -0,0 +1,110 @@ +package org.anddev.andengine.sensor.location; + +import org.anddev.andengine.util.constants.TimeConstants; + +import android.location.Criteria; + +/** + * @author Nicolas Gramlich + * @since 11:02:12 - 31.10.2010 + */ +public class LocationSensorOptions extends Criteria { + // =========================================================== + // Constants + // =========================================================== + + private static final long MINIMUMTRIGGERTIME_DEFAULT = 1 * TimeConstants.MILLISECONDSPERSECOND; + private static final long MINIMUMTRIGGERDISTANCE_DEFAULT = 10; + + // =========================================================== + // Fields + // =========================================================== + + private boolean mEnabledOnly = true; + + private long mMinimumTriggerTime = MINIMUMTRIGGERTIME_DEFAULT; + private long mMinimumTriggerDistance = MINIMUMTRIGGERDISTANCE_DEFAULT; + + // =========================================================== + // Constructors + // =========================================================== + + /** + * @see {@link LocationSensorOptions#setAccuracy(int)}, + * {@link LocationSensorOptions#setAltitudeRequired(boolean)}, + * {@link LocationSensorOptions#setBearingRequired(boolean)}, + * {@link LocationSensorOptions#setCostAllowed(boolean)}, + * {@link LocationSensorOptions#setEnabledOnly(boolean)}, + * {@link LocationSensorOptions#setMinimumTriggerDistance(long)}, + * {@link LocationSensorOptions#setMinimumTriggerTime(long)}, + * {@link LocationSensorOptions#setPowerRequirement(int)}, + * {@link LocationSensorOptions#setSpeedRequired(boolean)}. + */ + public LocationSensorOptions() { + + } + + /** + * @param pAccuracy + * @param pAltitudeRequired + * @param pBearingRequired + * @param pCostAllowed + * @param pPowerRequirement + * @param pSpeedRequired + * @param pEnabledOnly + * @param pMinimumTriggerTime + * @param pMinimumTriggerDistance + */ + public LocationSensorOptions(final int pAccuracy, final boolean pAltitudeRequired, final boolean pBearingRequired, final boolean pCostAllowed, final int pPowerRequirement, final boolean pSpeedRequired, final boolean pEnabledOnly, final long pMinimumTriggerTime, final long pMinimumTriggerDistance) { + this.mEnabledOnly = pEnabledOnly; + this.mMinimumTriggerTime = pMinimumTriggerTime; + this.mMinimumTriggerDistance = pMinimumTriggerDistance; + + this.setAccuracy(pAccuracy); + this.setAltitudeRequired(pAltitudeRequired); + this.setBearingRequired(pBearingRequired); + this.setCostAllowed(pCostAllowed); + this.setPowerRequirement(pPowerRequirement); + this.setSpeedRequired(pSpeedRequired); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void setEnabledOnly(final boolean pEnabledOnly) { + this.mEnabledOnly = pEnabledOnly; + } + + public boolean isEnabledOnly() { + return this.mEnabledOnly; + } + + public long getMinimumTriggerTime() { + return this.mMinimumTriggerTime; + } + + public void setMinimumTriggerTime(final long pMinimumTriggerTime) { + this.mMinimumTriggerTime = pMinimumTriggerTime; + } + + public long getMinimumTriggerDistance() { + return this.mMinimumTriggerDistance; + } + + public void setMinimumTriggerDistance(final long pMinimumTriggerDistance) { + this.mMinimumTriggerDistance = pMinimumTriggerDistance; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/orientation/IOrientationListener.java b/AndEngine/src/org/anddev/andengine/sensor/orientation/IOrientationListener.java new file mode 100644 index 0000000..8f79329 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/orientation/IOrientationListener.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.sensor.orientation; + +/** + * @author Nicolas Gramlich + * @since 11:30:42 - 25.05.2010 + */ +public interface IOrientationListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onOrientationChanged(final OrientationData pOrientationData); +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/orientation/OrientationData.java b/AndEngine/src/org/anddev/andengine/sensor/orientation/OrientationData.java new file mode 100644 index 0000000..25d6e17 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/orientation/OrientationData.java @@ -0,0 +1,139 @@ +package org.anddev.andengine.sensor.orientation; + +import java.util.Arrays; + +import org.anddev.andengine.sensor.BaseSensorData; +import org.anddev.andengine.util.constants.MathConstants; + +import android.hardware.SensorManager; +import android.view.Surface; + +/** + * @author Nicolas Gramlich + * @since 11:30:33 - 25.05.2010 + */ +public class OrientationData extends BaseSensorData { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float[] mAccelerometerValues = new float[3]; + private final float[] mMagneticFieldValues = new float[3]; + private final float[] mRotationMatrix = new float[16]; + + private int mMagneticFieldAccuracy; + + private final int mDisplayRotation; + + // =========================================================== + // Constructors + // =========================================================== + + public OrientationData(final int mDisplayRotation) { + super(3); + + this.mDisplayRotation = mDisplayRotation; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public float getRoll() { + return super.mValues[SensorManager.DATA_Z]; + } + + public float getPitch() { + return super.mValues[SensorManager.DATA_Y]; + } + + public float getYaw() { + return super.mValues[SensorManager.DATA_X]; + } + + @Override + @Deprecated + public void setValues(final float[] pValues) { + super.setValues(pValues); + } + + @Override + @Deprecated + public void setAccuracy(final int pAccuracy) { + super.setAccuracy(pAccuracy); + } + + public void setAccelerometerValues(final float[] pValues) { + System.arraycopy(pValues, 0, this.mAccelerometerValues, 0, pValues.length); + this.updateOrientation(); + } + + public void setMagneticFieldValues(final float[] pValues) { + System.arraycopy(pValues, 0, this.mMagneticFieldValues, 0, pValues.length); + this.updateOrientation(); + } + + private void updateOrientation() { + SensorManager.getRotationMatrix(this.mRotationMatrix, null, this.mAccelerometerValues, this.mMagneticFieldValues); + + // TODO Use dont't use identical matrixes in remapCoordinateSystem, due to performance reasons. + switch(this.mDisplayRotation) { + case Surface.ROTATION_90: + SensorManager.remapCoordinateSystem(this.mRotationMatrix, SensorManager.AXIS_Y, SensorManager.AXIS_MINUS_X, this.mRotationMatrix); + break; +// case Surface.ROTATION_180: +// SensorManager.remapCoordinateSystem(this.mRotationMatrix, SensorManager.AXIS_?, SensorManager.AXIS_?, this.mRotationMatrix); +// break; +// case Surface.ROTATION_270: +// SensorManager.remapCoordinateSystem(this.mRotationMatrix, SensorManager.AXIS_?, SensorManager.AXIS_?, this.mRotationMatrix); +// break; + case Surface.ROTATION_0: + /* Nothing. */ + break; + } + + final float[] values = this.mValues; + SensorManager.getOrientation(this.mRotationMatrix, values); + + for(int i = values.length - 1; i >= 0; i--) { + values[i] = values[i] * MathConstants.RAD_TO_DEG; + } + } + + public int getAccelerometerAccuracy() { + return this.getAccuracy(); + } + + public void setAccelerometerAccuracy(final int pAccelerometerAccuracy) { + super.setAccuracy(pAccelerometerAccuracy); + } + + public int getMagneticFieldAccuracy() { + return this.mMagneticFieldAccuracy; + } + + public void setMagneticFieldAccuracy(final int pMagneticFieldAccuracy) { + this.mMagneticFieldAccuracy = pMagneticFieldAccuracy; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public String toString() { + return "Orientation: " + Arrays.toString(this.mValues); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/sensor/orientation/OrientationSensorOptions.java b/AndEngine/src/org/anddev/andengine/sensor/orientation/OrientationSensorOptions.java new file mode 100644 index 0000000..e4e2f91 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/sensor/orientation/OrientationSensorOptions.java @@ -0,0 +1,47 @@ +package org.anddev.andengine.sensor.orientation; + +import org.anddev.andengine.sensor.SensorDelay; + +/** + * @author Nicolas Gramlich + * @since 11:12:36 - 31.10.2010 + */ +public class OrientationSensorOptions { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + final SensorDelay mSensorDelay; + + // =========================================================== + // Constructors + // =========================================================== + + public OrientationSensorOptions(final SensorDelay pSensorDelay) { + this.mSensorDelay = pSensorDelay; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public SensorDelay getSensorDelay() { + return this.mSensorDelay; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/ui/IGameInterface.java b/AndEngine/src/org/anddev/andengine/ui/IGameInterface.java new file mode 100644 index 0000000..818d330 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/IGameInterface.java @@ -0,0 +1,27 @@ +package org.anddev.andengine.ui; + +import org.anddev.andengine.engine.Engine; +import org.anddev.andengine.entity.scene.Scene; + +/** + * @author Nicolas Gramlich + * @since 12:03:08 - 14.03.2010 + */ +public interface IGameInterface { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public Engine onLoadEngine(); + public void onLoadResources(); + public void onUnloadResources(); + public Scene onLoadScene(); + public void onLoadComplete(); + + public void onGamePaused(); + public void onGameResumed(); +} diff --git a/AndEngine/src/org/anddev/andengine/ui/activity/BaseActivity.java b/AndEngine/src/org/anddev/andengine/ui/activity/BaseActivity.java new file mode 100644 index 0000000..a2138d9 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/activity/BaseActivity.java @@ -0,0 +1,127 @@ +package org.anddev.andengine.ui.activity; + +import java.util.concurrent.Callable; + +import org.anddev.andengine.util.ActivityUtils; +import org.anddev.andengine.util.AsyncCallable; +import org.anddev.andengine.util.Callback; +import org.anddev.andengine.util.progress.ProgressCallable; + +import android.app.Activity; +import android.app.ProgressDialog; + +/** + * @author Nicolas Gramlich + * @since 18:35:28 - 29.08.2009 + */ +public abstract class BaseActivity extends Activity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * Performs a task in the background, showing a {@link ProgressDialog}, + * while the {@link Callable} is being processed. + * + * @param + * @param pTitleResID + * @param pMessageResID + * @param pErrorMessageResID + * @param pCallable + * @param pCallback + */ + protected void doAsync(final int pTitleResID, final int pMessageResID, final Callable pCallable, final Callback pCallback) { + this.doAsync(pTitleResID, pMessageResID, pCallable, pCallback, null); + } + + /** + * Performs a task in the background, showing a indeterminate {@link ProgressDialog}, + * while the {@link Callable} is being processed. + * + * @param + * @param pTitleResID + * @param pMessageResID + * @param pErrorMessageResID + * @param pCallable + * @param pCallback + * @param pExceptionCallback + */ + protected void doAsync(final int pTitleResID, final int pMessageResID, final Callable pCallable, final Callback pCallback, final Callback pExceptionCallback) { + ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback); + } + + /** + * Performs a task in the background, showing a {@link ProgressDialog} with an ProgressBar, + * while the {@link AsyncCallable} is being processed. + * + * @param + * @param pTitleResID + * @param pMessageResID + * @param pErrorMessageResID + * @param pAsyncCallable + * @param pCallback + */ + protected void doProgressAsync(final int pTitleResID, final ProgressCallable pCallable, final Callback pCallback) { + this.doProgressAsync(pTitleResID, pCallable, pCallback, null); + } + + /** + * Performs a task in the background, showing a {@link ProgressDialog} with a ProgressBar, + * while the {@link AsyncCallable} is being processed. + * + * @param + * @param pTitleResID + * @param pMessageResID + * @param pErrorMessageResID + * @param pAsyncCallable + * @param pCallback + * @param pExceptionCallback + */ + protected void doProgressAsync(final int pTitleResID, final ProgressCallable pCallable, final Callback pCallback, final Callback pExceptionCallback) { + ActivityUtils.doProgressAsync(this, pTitleResID, pCallable, pCallback, pExceptionCallback); + } + + /** + * Performs a task in the background, showing an indeterminate {@link ProgressDialog}, + * while the {@link AsyncCallable} is being processed. + * + * @param + * @param pTitleResID + * @param pMessageResID + * @param pErrorMessageResID + * @param pAsyncCallable + * @param pCallback + * @param pExceptionCallback + */ + protected void doAsync(final int pTitleResID, final int pMessageResID, final AsyncCallable pAsyncCallable, final Callback pCallback, final Callback pExceptionCallback) { + ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pAsyncCallable, pCallback, pExceptionCallback); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class CancelledException extends Exception { + private static final long serialVersionUID = -78123211381435596L; + } +} diff --git a/AndEngine/src/org/anddev/andengine/ui/activity/BaseGameActivity.java b/AndEngine/src/org/anddev/andengine/ui/activity/BaseGameActivity.java new file mode 100644 index 0000000..87bdd34 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/activity/BaseGameActivity.java @@ -0,0 +1,303 @@ +package org.anddev.andengine.ui.activity; + +import static android.view.ViewGroup.LayoutParams.FILL_PARENT; + +import org.anddev.andengine.audio.music.MusicManager; +import org.anddev.andengine.audio.sound.SoundManager; +import org.anddev.andengine.engine.Engine; +import org.anddev.andengine.engine.options.EngineOptions; +import org.anddev.andengine.engine.options.WakeLockOptions; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.opengl.view.RenderSurfaceView; +import org.anddev.andengine.sensor.accelerometer.AccelerometerSensorOptions; +import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener; +import org.anddev.andengine.sensor.location.ILocationListener; +import org.anddev.andengine.sensor.location.LocationSensorOptions; +import org.anddev.andengine.sensor.orientation.IOrientationListener; +import org.anddev.andengine.sensor.orientation.OrientationSensorOptions; +import org.anddev.andengine.ui.IGameInterface; +import org.anddev.andengine.util.ActivityUtils; +import org.anddev.andengine.util.Debug; + +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.media.AudioManager; +import android.os.Bundle; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.view.Gravity; +import android.widget.FrameLayout.LayoutParams; + +/** + * @author Nicolas Gramlich + * @since 11:27:06 - 08.03.2010 + */ +public abstract class BaseGameActivity extends BaseActivity implements IGameInterface { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected Engine mEngine; + private WakeLock mWakeLock; + protected RenderSurfaceView mRenderSurfaceView; + protected boolean mHasWindowFocused; + private boolean mPaused; + private boolean mGameLoaded; + + // =========================================================== + // Constructors + // =========================================================== + + @Override + protected void onCreate(final Bundle pSavedInstanceState) { + super.onCreate(pSavedInstanceState); + this.mPaused = true; + + this.mEngine = this.onLoadEngine(); + + this.applyEngineOptions(this.mEngine.getEngineOptions()); + + this.onSetContentView(); + } + + @Override + protected void onResume() { + super.onResume(); + + if(this.mPaused && this.mHasWindowFocused) { + this.doResume(); + } + } + + @Override + public void onWindowFocusChanged(final boolean pHasWindowFocus) { + super.onWindowFocusChanged(pHasWindowFocus); + + if(pHasWindowFocus) { + if(this.mPaused) { + this.doResume(); + } + this.mHasWindowFocused = true; + } else { + if(!this.mPaused) { + this.doPause(); + } + this.mHasWindowFocused = false; + } + } + + @Override + protected void onPause() { + super.onPause(); + + if(!this.mPaused) { + this.doPause(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + this.mEngine.interruptUpdateThread(); + + this.onUnloadResources(); + } + + @Override + public void onUnloadResources() { + if(this.mEngine.getEngineOptions().needsMusic()) { + this.getMusicManager().releaseAll(); + } + if(this.mEngine.getEngineOptions().needsSound()) { + this.getSoundManager().releaseAll(); + } + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public Engine getEngine() { + return this.mEngine; + } + + public SoundManager getSoundManager() { + return this.mEngine.getSoundManager(); + } + + public MusicManager getMusicManager() { + return this.mEngine.getMusicManager(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onGameResumed() { + + } + + @Override + public void onGamePaused() { + + } + + // =========================================================== + // Methods + // =========================================================== + + private void doResume() { + if(!this.mGameLoaded) { + this.onLoadResources(); + final Scene scene = this.onLoadScene(); + this.mEngine.onLoadComplete(scene); + this.onLoadComplete(); + this.mGameLoaded = true; + } + + this.mPaused = false; + this.acquireWakeLock(this.mEngine.getEngineOptions().getWakeLockOptions()); + this.mEngine.onResume(); + + this.mRenderSurfaceView.onResume(); + this.mEngine.start(); + this.onGameResumed(); + } + + private void doPause() { + this.mPaused = true; + this.releaseWakeLock(); + + this.mEngine.onPause(); + this.mEngine.stop(); + this.mRenderSurfaceView.onPause(); + this.onGamePaused(); + } + + public void runOnUpdateThread(final Runnable pRunnable) { + this.mEngine.runOnUpdateThread(pRunnable); + } + + protected void onSetContentView() { + this.mRenderSurfaceView = new RenderSurfaceView(this); + this.mRenderSurfaceView.setEGLConfigChooser(false); + this.mRenderSurfaceView.setRenderer(this.mEngine); + + this.setContentView(this.mRenderSurfaceView, this.createSurfaceViewLayoutParams()); + } + + private void acquireWakeLock(final WakeLockOptions pWakeLockOptions) { + if(pWakeLockOptions == WakeLockOptions.SCREEN_ON) { + ActivityUtils.keepScreenOn(this); + } else { + final PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE); + this.mWakeLock = pm.newWakeLock(pWakeLockOptions.getFlag() | PowerManager.ON_AFTER_RELEASE, "AndEngine"); + try { + this.mWakeLock.acquire(); + } catch (final SecurityException e) { + Debug.e("You have to add\n\t\nto your AndroidManifest.xml !", e); + } + } + } + + private void releaseWakeLock() { + if(this.mWakeLock != null && this.mWakeLock.isHeld()) { + this.mWakeLock.release(); + } + } + + private void applyEngineOptions(final EngineOptions pEngineOptions) { + if(pEngineOptions.isFullscreen()) { + ActivityUtils.requestFullscreen(this); + } + + if(pEngineOptions.needsMusic() || pEngineOptions.needsSound()) { + this.setVolumeControlStream(AudioManager.STREAM_MUSIC); + } + + switch(pEngineOptions.getScreenOrientation()) { + case LANDSCAPE: + this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + break; + case PORTRAIT: + this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + break; + } + } + + protected LayoutParams createSurfaceViewLayoutParams() { + final LayoutParams layoutParams = new LayoutParams(FILL_PARENT, FILL_PARENT); + layoutParams.gravity = Gravity.CENTER; + return layoutParams; + } + + protected void enableVibrator() { + this.mEngine.enableVibrator(this); + } + + /** + * @see {@link Engine#enableLocationSensor(Context, ILocationListener, LocationSensorOptions)} + */ + protected void enableLocationSensor(final ILocationListener pLocationListener, final LocationSensorOptions pLocationSensorOptions) { + this.mEngine.enableLocationSensor(this, pLocationListener, pLocationSensorOptions); + } + + /** + * @see {@link Engine#disableLocationSensor(Context)} + */ + protected void disableLocationSensor() { + this.mEngine.disableLocationSensor(this); + } + + /** + * @see {@link Engine#enableAccelerometerSensor(Context, IAccelerometerListener)} + */ + protected boolean enableAccelerometerSensor(final IAccelerometerListener pAccelerometerListener) { + return this.mEngine.enableAccelerometerSensor(this, pAccelerometerListener); + } + + /** + * @see {@link Engine#enableAccelerometerSensor(Context, IAccelerometerListener, AccelerometerSensorOptions)} + */ + protected boolean enableAccelerometerSensor(final IAccelerometerListener pAccelerometerListener, final AccelerometerSensorOptions pAccelerometerSensorOptions) { + return this.mEngine.enableAccelerometerSensor(this, pAccelerometerListener, pAccelerometerSensorOptions); + } + + /** + * @see {@link Engine#disableAccelerometerSensor(Context)} + */ + protected boolean disableAccelerometerSensor() { + return this.mEngine.disableAccelerometerSensor(this); + } + + /** + * @see {@link Engine#enableOrientationSensor(Context, IOrientationListener)} + */ + protected boolean enableOrientationSensor(final IOrientationListener pOrientationListener) { + return this.mEngine.enableOrientationSensor(this, pOrientationListener); + } + + /** + * @see {@link Engine#enableOrientationSensor(Context, IOrientationListener, OrientationSensorOptions)} + */ + protected boolean enableOrientationSensor(final IOrientationListener pOrientationListener, final OrientationSensorOptions pLocationSensorOptions) { + return this.mEngine.enableOrientationSensor(this, pOrientationListener, pLocationSensorOptions); + } + + /** + * @see {@link Engine#disableOrientationSensor(Context)} + */ + protected boolean disableOrientationSensor() { + return this.mEngine.disableOrientationSensor(this); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/ui/activity/BaseSplashActivity.java b/AndEngine/src/org/anddev/andengine/ui/activity/BaseSplashActivity.java new file mode 100644 index 0000000..1ca0d49 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/activity/BaseSplashActivity.java @@ -0,0 +1,123 @@ +package org.anddev.andengine.ui.activity; + +import org.anddev.andengine.engine.Engine; +import org.anddev.andengine.engine.camera.Camera; +import org.anddev.andengine.engine.handler.timer.ITimerCallback; +import org.anddev.andengine.engine.handler.timer.TimerHandler; +import org.anddev.andengine.engine.options.EngineOptions; +import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation; +import org.anddev.andengine.engine.options.resolutionpolicy.IResolutionPolicy; +import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; +import org.anddev.andengine.entity.scene.Scene; +import org.anddev.andengine.entity.scene.SplashScene; +import org.anddev.andengine.opengl.texture.Texture; +import org.anddev.andengine.opengl.texture.TextureFactory; +import org.anddev.andengine.opengl.texture.TextureOptions; +import org.anddev.andengine.opengl.texture.region.TextureRegion; +import org.anddev.andengine.opengl.texture.region.TextureRegionFactory; +import org.anddev.andengine.opengl.texture.source.ITextureSource; + +import android.app.Activity; +import android.content.Intent; + +/** + * @author Nicolas Gramlich + * @since 08:25:31 - 03.05.2010 + */ +public abstract class BaseSplashActivity extends BaseGameActivity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private Camera mCamera; + private ITextureSource mSplashTextureSource; + private TextureRegion mLoadingScreenTextureRegion; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract ScreenOrientation getScreenOrientation(); + + protected abstract ITextureSource onGetSplashTextureSource(); + + protected abstract float getSplashDuration(); + + protected abstract Class getFollowUpActivity(); + + protected float getSplashScaleFrom() { + return 1f; + } + + protected float getSplashScaleTo() { + return 1f; + } + + @Override + public void onLoadComplete() { + } + + @Override + public Engine onLoadEngine() { + this.mSplashTextureSource = this.onGetSplashTextureSource(); + + final int width = this.mSplashTextureSource.getWidth(); + final int height = this.mSplashTextureSource.getHeight(); + + this.mCamera = this.getSplashCamera(width, height); + return new Engine(new EngineOptions(true, this.getScreenOrientation(), this.getSplashResolutionPolicy(width, height), this.mCamera)); + } + + @Override + public void onLoadResources() { + final Texture loadingScreenTexture = TextureFactory.createForTextureSourceSize(this.mSplashTextureSource, TextureOptions.BILINEAR_PREMULTIPLYALPHA); + this.mLoadingScreenTextureRegion = TextureRegionFactory.createFromSource(loadingScreenTexture, this.mSplashTextureSource, 0, 0); + + this.getEngine().getTextureManager().loadTexture(loadingScreenTexture); + } + + @Override + public Scene onLoadScene() { + final float splashDuration = this.getSplashDuration(); + + final SplashScene splashScene = new SplashScene(this.mCamera, this.mLoadingScreenTextureRegion, splashDuration, this.getSplashScaleFrom(), this.getSplashScaleTo()); + + splashScene.registerUpdateHandler(new TimerHandler(splashDuration, new ITimerCallback() { + @Override + public void onTimePassed(final TimerHandler pTimerHandler) { + BaseSplashActivity.this.startActivity(new Intent(BaseSplashActivity.this, BaseSplashActivity.this.getFollowUpActivity())); + BaseSplashActivity.this.finish(); + } + })); + + return splashScene; + } + + // =========================================================== + // Methods + // =========================================================== + + protected Camera getSplashCamera(final int pSplashwidth, final int pSplashHeight) { + return new Camera(0, 0, pSplashwidth, pSplashHeight); + } + + protected IResolutionPolicy getSplashResolutionPolicy(final int pSplashwidth, final int pSplashHeight) { + return new RatioResolutionPolicy(pSplashwidth, pSplashHeight); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/ui/activity/LayoutGameActivity.java b/AndEngine/src/org/anddev/andengine/ui/activity/LayoutGameActivity.java new file mode 100644 index 0000000..19528ca --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/activity/LayoutGameActivity.java @@ -0,0 +1,50 @@ +package org.anddev.andengine.ui.activity; + +import org.anddev.andengine.opengl.view.RenderSurfaceView; + +/** + * @author Nicolas Gramlich + * @since 10:18:50 - 06.10.2010 + */ +public abstract class LayoutGameActivity extends BaseGameActivity { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract int getLayoutID(); + protected abstract int getRenderSurfaceViewID(); + + @Override + protected void onSetContentView() { + super.setContentView(this.getLayoutID()); + + this.mRenderSurfaceView = (RenderSurfaceView) this.findViewById(this.getRenderSurfaceViewID()); + + this.mRenderSurfaceView.setEGLConfigChooser(false); + this.mRenderSurfaceView.setRenderer(this.mEngine); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/ui/dialog/GenericInputDialogBuilder.java b/AndEngine/src/org/anddev/andengine/ui/dialog/GenericInputDialogBuilder.java new file mode 100644 index 0000000..d3d9b1c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/dialog/GenericInputDialogBuilder.java @@ -0,0 +1,120 @@ +package org.anddev.andengine.ui.dialog; + +import org.anddev.andengine.util.Callback; +import org.anddev.andengine.util.Debug; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; +import android.content.DialogInterface.OnClickListener; +import android.widget.EditText; +import android.widget.Toast; + +/** + * @author Nicolas Gramlich + * @since 09:35:55 - 14.12.2009 + */ +public abstract class GenericInputDialogBuilder { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final Callback mSuccessCallback; + protected final OnCancelListener mOnCancelListener; + protected final int mTitleResID; + protected final int mMessageResID; + protected final int mIconResID; + protected final Context mContext; + private final int mErrorResID; + private final String mDefaultText; + + // =========================================================== + // Constructors + // =========================================================== + + public GenericInputDialogBuilder(final Context pContext, final int pTitleResID, final int pMessageResID, final int pErrorResID, final int pIconResID, final Callback pSuccessCallback, final OnCancelListener pOnCancelListener){ + this(pContext, pTitleResID, pMessageResID, pErrorResID, pIconResID, "", pSuccessCallback, pOnCancelListener); + } + + public GenericInputDialogBuilder(final Context pContext, final int pTitleResID, final int pMessageResID, final int pErrorResID, final int pIconResID, final String pDefaultText, final Callback pSuccessCallback, final OnCancelListener pOnCancelListener){ + this.mContext = pContext; + this.mTitleResID = pTitleResID; + this.mMessageResID = pMessageResID; + this.mErrorResID = pErrorResID; + this.mIconResID = pIconResID; + this.mDefaultText = pDefaultText; + this.mSuccessCallback = pSuccessCallback; + this.mOnCancelListener = pOnCancelListener; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract T generateResult(final String pInput); + + // =========================================================== + // Methods + // =========================================================== + + public Dialog create() { + final EditText etInput = new EditText(this.mContext); + etInput.setText(this.mDefaultText); + + final AlertDialog.Builder ab = new AlertDialog.Builder(this.mContext); + if(this.mTitleResID != 0) { + ab.setTitle(this.mTitleResID); + } + if(this.mMessageResID != 0) { + ab.setMessage(this.mMessageResID); + } + if(this.mIconResID != 0) { + ab.setIcon(this.mIconResID); + } + + this.setView(ab, etInput); + ab.setOnCancelListener(this.mOnCancelListener) + .setPositiveButton(android.R.string.ok, new OnClickListener() { + @Override + public void onClick(final DialogInterface pDialog, final int pWhich) { + final T result; + try{ + result = GenericInputDialogBuilder.this.generateResult(etInput.getText().toString()); + } catch (final IllegalArgumentException e) { + Debug.e("Error in GenericInputDialogBuilder.generateResult()", e); + Toast.makeText(GenericInputDialogBuilder.this.mContext, GenericInputDialogBuilder.this.mErrorResID, Toast.LENGTH_SHORT).show(); + return; + } + GenericInputDialogBuilder.this.mSuccessCallback.onCallback(result); + pDialog.dismiss(); + } + }) + .setNegativeButton(android.R.string.cancel, new OnClickListener() { + @Override + public void onClick(final DialogInterface pDialog, final int pWhich) { + GenericInputDialogBuilder.this.mOnCancelListener.onCancel(pDialog); + pDialog.dismiss(); + } + }); + + return ab.create(); + } + + protected void setView(final AlertDialog.Builder pBuilder, final EditText pInputEditText) { + pBuilder.setView(pInputEditText); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/ui/dialog/StringInputDialogBuilder.java b/AndEngine/src/org/anddev/andengine/ui/dialog/StringInputDialogBuilder.java new file mode 100644 index 0000000..8a5ac82 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/ui/dialog/StringInputDialogBuilder.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.ui.dialog; + +import org.anddev.andengine.util.Callback; + +import android.content.Context; +import android.content.DialogInterface.OnCancelListener; + +/** + * @author Nicolas Gramlich + * @since 09:46:00 - 14.12.2009 + */ +public class StringInputDialogBuilder extends GenericInputDialogBuilder { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public StringInputDialogBuilder(final Context pContext, final int pTitleResID, final int pMessageResID, final int pErrorResID, final int pIconResID, final Callback pSuccessCallback, final OnCancelListener pOnCancelListener) { + super(pContext, pTitleResID, pMessageResID, pErrorResID, pIconResID, pSuccessCallback, pOnCancelListener); + } + + public StringInputDialogBuilder(final Context pContext, final int pTitleResID, final int pMessageResID, final int pErrorResID, final int pIconResID, final String pDefaultText, final Callback pSuccessCallback, final OnCancelListener pOnCancelListener) { + super(pContext, pTitleResID, pMessageResID, pErrorResID, pIconResID, pDefaultText, pSuccessCallback, pOnCancelListener); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected String generateResult(final String pInput) { + return pInput; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/ActivityUtils.java b/AndEngine/src/org/anddev/andengine/util/ActivityUtils.java new file mode 100644 index 0000000..8da5851 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ActivityUtils.java @@ -0,0 +1,242 @@ +package org.anddev.andengine.util; + +import java.util.concurrent.Callable; + +import org.anddev.andengine.ui.activity.BaseActivity.CancelledException; +import org.anddev.andengine.util.progress.IProgressListener; +import org.anddev.andengine.util.progress.ProgressCallable; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; +import android.os.AsyncTask; +import android.view.Window; +import android.view.WindowManager; + +/** + * @author Nicolas Gramlich + * @since 18:11:54 - 07.03.2011 + */ +public class ActivityUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static void requestFullscreen(final Activity pActivity) { + final Window window = pActivity.getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + window.requestFeature(Window.FEATURE_NO_TITLE); + } + + /** + * @param pActivity + * @param pScreenBrightness [0..1] + */ + public static void setScreenBrightness(final Activity pActivity, final float pScreenBrightness) { + final Window window = pActivity.getWindow(); + final WindowManager.LayoutParams windowLayoutParams = window.getAttributes(); + windowLayoutParams.screenBrightness = pScreenBrightness; + window.setAttributes(windowLayoutParams); + } + + public static void keepScreenOn(final Activity pActivity) { + pActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + public static void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable pCallable, final Callback pCallback) { + ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, false); + } + + public static void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable pCallable, final Callback pCallback) { + ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, false); + } + + public static void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable pCallable, final Callback pCallback, final boolean pCancelable) { + ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, pCancelable); + } + + public static void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable pCallable, final Callback pCallback, final boolean pCancelable) { + ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, pCancelable); + } + + public static void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable pCallable, final Callback pCallback, final Callback pExceptionCallback) { + ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback, false); + } + + public static void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable pCallable, final Callback pCallback, final Callback pExceptionCallback) { + ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, pExceptionCallback, false); + } + + public static void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable pCallable, final Callback pCallback, final Callback pExceptionCallback, final boolean pCancelable) { + ActivityUtils.doAsync(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID), pCallable, pCallback, pExceptionCallback, pCancelable); + } + + public static void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable pCallable, final Callback pCallback, final Callback pExceptionCallback, final boolean pCancelable) { + new AsyncTask() { + private ProgressDialog mPD; + private Exception mException = null; + + @Override + public void onPreExecute() { + this.mPD = ProgressDialog.show(pContext, pTitle, pMessage, true, pCancelable); + if(pCancelable) { + this.mPD.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(final DialogInterface pDialogInterface) { + pExceptionCallback.onCallback(new CancelledException()); + pDialogInterface.dismiss(); + } + }); + } + super.onPreExecute(); + } + + @Override + public T doInBackground(final Void... params) { + try { + return pCallable.call(); + } catch (final Exception e) { + this.mException = e; + } + return null; + } + + @Override + public void onPostExecute(final T result) { + try { + this.mPD.dismiss(); + } catch (final Exception e) { + Debug.e("Error", e); + } + + if(this.isCancelled()) { + this.mException = new CancelledException(); + } + + if(this.mException == null) { + pCallback.onCallback(result); + } else { + if(pExceptionCallback == null) { + Debug.e("Error", this.mException); + } else { + pExceptionCallback.onCallback(this.mException); + } + } + + super.onPostExecute(result); + } + }.execute((Void[]) null); + } + + public static void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable pCallable, final Callback pCallback) { + ActivityUtils.doProgressAsync(pContext, pTitleResID, pCallable, pCallback, null); + } + + public static void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable pCallable, final Callback pCallback, final Callback pExceptionCallback) { + new AsyncTask() { + private ProgressDialog mPD; + private Exception mException = null; + + @Override + public void onPreExecute() { + this.mPD = new ProgressDialog(pContext); + this.mPD.setTitle(pTitleResID); + this.mPD.setIcon(android.R.drawable.ic_menu_save); + this.mPD.setIndeterminate(false); + this.mPD.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + this.mPD.show(); + super.onPreExecute(); + } + + @Override + public T doInBackground(final Void... params) { + try { + return pCallable.call(new IProgressListener() { + @Override + public void onProgressChanged(final int pProgress) { + onProgressUpdate(pProgress); + } + }); + } catch (final Exception e) { + this.mException = e; + } + return null; + } + + @Override + public void onProgressUpdate(final Integer... values) { + this.mPD.setProgress(values[0]); + } + + @Override + public void onPostExecute(final T result) { + try { + this.mPD.dismiss(); + } catch (final Exception e) { + Debug.e("Error", e); + /* Nothing. */ + } + + if(this.isCancelled()) { + this.mException = new CancelledException(); + } + + if(this.mException == null) { + pCallback.onCallback(result); + } else { + if(pExceptionCallback == null) { + Debug.e("Error", this.mException); + } else { + pExceptionCallback.onCallback(this.mException); + } + } + + super.onPostExecute(result); + } + }.execute((Void[]) null); + } + + public static void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final AsyncCallable pAsyncCallable, final Callback pCallback, final Callback pExceptionCallback) { + final ProgressDialog pd = ProgressDialog.show(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID)); + pAsyncCallable.call(new Callback() { + @Override + public void onCallback(final T result) { + try { + pd.dismiss(); + } catch (final Exception e) { + Debug.e("Error", e); + /* Nothing. */ + } + + pCallback.onCallback(result); + } + }, pExceptionCallback); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/ArrayUtils.java b/AndEngine/src/org/anddev/andengine/util/ArrayUtils.java new file mode 100644 index 0000000..9731b01 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ArrayUtils.java @@ -0,0 +1,39 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 22:35:42 - 01.05.2011 + */ +public class ArrayUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static T random(final T[] pArray) { + return pArray[MathUtils.random(0, pArray.length - 1)]; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/AsyncCallable.java b/AndEngine/src/org/anddev/andengine/util/AsyncCallable.java new file mode 100644 index 0000000..910aa8e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/AsyncCallable.java @@ -0,0 +1,25 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 15:00:30 - 14.05.2010 + * @param + */ +public interface AsyncCallable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * Computes a result asynchronously, return values and exceptions are to be handled through the callbacks. + * This method is expected to return almost immediately, after starting a {@link Thread} or similar. + * + * @return computed result + * @throws Exception if unable to compute a result + */ + public void call(final Callback pCallback, final Callback pExceptionCallback); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/Base64.java b/AndEngine/src/org/anddev/andengine/util/Base64.java new file mode 100644 index 0000000..4e3957a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Base64.java @@ -0,0 +1,759 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.anddev.andengine.util; + +import java.io.UnsupportedEncodingException; + +/** + * Utilities for encoding and decoding the Base64 representation of + * binary data. See RFCs 2045 and 3548. + */ +public class Base64 { + /** + * Default values for encoder/decoder flags. + */ + public static final int DEFAULT = 0; + + /** + * Encoder flag bit to omit the padding '=' characters at the end + * of the output (if any). + */ + public static final int NO_PADDING = 1; + + /** + * Encoder flag bit to omit all line terminators (i.e., the output + * will be on one long line). + */ + public static final int NO_WRAP = 2; + + /** + * Encoder flag bit to indicate lines should be terminated with a + * CRLF pair instead of just an LF. Has no effect if {@code + * NO_WRAP} is specified as well. + */ + public static final int CRLF = 4; + + /** + * Encoder/decoder flag bit to indicate using the "URL and + * filename safe" variant of Base64 (see RFC 3548 section 4) where + * {@code -} and {@code _} are used in place of {@code +} and + * {@code /}. + */ + public static final int URL_SAFE = 8; + + /** + * Flag to pass to {@link Base64OutputStream} to indicate that it + * should not close the output stream it is wrapping when it + * itself is closed. + */ + public static final int NO_CLOSE = 16; + + // -------------------------------------------------------- + // shared code + // -------------------------------------------------------- + + /* package */ static abstract class Coder { + public byte[] output; + public int op; + + /** + * Encode/decode another block of input data. this.output is + * provided by the caller, and must be big enough to hold all + * the coded data. On exit, this.opwill be set to the length + * of the coded data. + * + * @param finish true if this is the final call to process for + * this object. Will finalize the coder state and + * include any final bytes in the output. + * + * @return true if the input so far is good; false if some + * error has been detected in the input stream.. + */ + public abstract boolean process(byte[] input, int offset, int len, boolean finish); + + /** + * @return the maximum number of bytes a call to process() + * could produce for the given number of input bytes. This may + * be an overestimate. + */ + public abstract int maxOutputSize(int len); + } + + // -------------------------------------------------------- + // decoding + // -------------------------------------------------------- + + /** + * Decode the Base64-encoded data in input and return the data in + * a new byte array. + * + *

The padding '=' characters at the end are considered optional, but + * if any are present, there must be the correct number of them. + * + * @param str the input String to decode, which is converted to + * bytes using the default charset + * @param flags controls certain features of the decoded output. + * Pass {@code DEFAULT} to decode standard Base64. + * + * @throws IllegalArgumentException if the input contains + * incorrect padding + */ + public static byte[] decode(final String str, final int flags) { + return Base64.decode(str.getBytes(), flags); + } + + /** + * Decode the Base64-encoded data in input and return the data in + * a new byte array. + * + *

The padding '=' characters at the end are considered optional, but + * if any are present, there must be the correct number of them. + * + * @param input the input array to decode + * @param flags controls certain features of the decoded output. + * Pass {@code DEFAULT} to decode standard Base64. + * + * @throws IllegalArgumentException if the input contains + * incorrect padding + */ + public static byte[] decode(final byte[] input, final int flags) { + return Base64.decode(input, 0, input.length, flags); + } + + /** + * Decode the Base64-encoded data in input and return the data in + * a new byte array. + * + *

The padding '=' characters at the end are considered optional, but + * if any are present, there must be the correct number of them. + * + * @param input the data to decode + * @param offset the position within the input array at which to start + * @param len the number of bytes of input to decode + * @param flags controls certain features of the decoded output. + * Pass {@code DEFAULT} to decode standard Base64. + * + * @throws IllegalArgumentException if the input contains + * incorrect padding + */ + public static byte[] decode(final byte[] input, final int offset, final int len, final int flags) { + // Allocate space for the most data the input could represent. + // (It could contain less if it contains whitespace, etc.) + final Decoder decoder = new Decoder(flags, new byte[len*3/4]); + + if (!decoder.process(input, offset, len, true)) { + throw new IllegalArgumentException("bad base-64"); + } + + // Maybe we got lucky and allocated exactly enough output space. + if (decoder.op == decoder.output.length) { + return decoder.output; + } + + // Need to shorten the array, so allocate a new one of the + // right size and copy. + final byte[] temp = new byte[decoder.op]; + System.arraycopy(decoder.output, 0, temp, 0, decoder.op); + return temp; + } + + /* package */ static class Decoder extends Coder { + /** + * Lookup table for turning bytes into their position in the + * Base64 alphabet. + */ + private static final int DECODE[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + /** + * Decode lookup table for the "web safe" variant (RFC 3548 + * sec. 4) where - and _ replace + and /. + */ + private static final int DECODE_WEBSAFE[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + /** Non-data values in the DECODE arrays. */ + private static final int SKIP = -1; + private static final int EQUALS = -2; + + /** + * States 0-3 are reading through the next input tuple. + * State 4 is having read one '=' and expecting exactly + * one more. + * State 5 is expecting no more data or padding characters + * in the input. + * State 6 is the error state; an error has been detected + * in the input and no future input can "fix" it. + */ + private int state; // state number (0 to 6) + private int value; + + final private int[] alphabet; + + public Decoder(final int flags, final byte[] output) { + this.output = output; + + this.alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE; + this.state = 0; + this.value = 0; + } + + /** + * @return an overestimate for the number of bytes {@code + * len} bytes could decode to. + */ + @Override + public int maxOutputSize(final int len) { + return len * 3/4 + 10; + } + + /** + * Decode another block of input data. + * + * @return true if the state machine is still healthy. false if + * bad base-64 data has been detected in the input stream. + */ + @Override + public boolean process(final byte[] input, final int offset, int len, final boolean finish) { + if (this.state == 6) { + return false; + } + + int p = offset; + len += offset; + + // Using local variables makes the decoder about 12% + // faster than if we manipulate the member variables in + // the loop. (Even alphabet makes a measurable + // difference, which is somewhat surprising to me since + // the member variable is final.) + int state = this.state; + int value = this.value; + int op = 0; + final byte[] output = this.output; + final int[] alphabet = this.alphabet; + + while (p < len) { + // Try the fast path: we're starting a new tuple and the + // next four bytes of the input stream are all data + // bytes. This corresponds to going through states + // 0-1-2-3-0. We expect to use this method for most of + // the data. + // + // If any of the next four bytes of input are non-data + // (whitespace, etc.), value will end up negative. (All + // the non-data values in decode are small negative + // numbers, so shifting any of them up and or'ing them + // together will result in a value with its top bit set.) + // + // You can remove this whole block and the output should + // be the same, just slower. + if (state == 0) { + while (p+4 <= len && + (value = ((alphabet[input[p] & 0xff] << 18) | + (alphabet[input[p+1] & 0xff] << 12) | + (alphabet[input[p+2] & 0xff] << 6) | + (alphabet[input[p+3] & 0xff]))) >= 0) { + output[op+2] = (byte) value; + output[op+1] = (byte) (value >> 8); + output[op] = (byte) (value >> 16); + op += 3; + p += 4; + } + if (p >= len) { + break; + } + } + + // The fast path isn't available -- either we've read a + // partial tuple, or the next four input bytes aren't all + // data, or whatever. Fall back to the slower state + // machine implementation. + + final int d = alphabet[input[p++] & 0xff]; + + switch (state) { + case 0: + if (d >= 0) { + value = d; + ++state; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + + case 1: + if (d >= 0) { + value = (value << 6) | d; + ++state; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + + case 2: + if (d >= 0) { + value = (value << 6) | d; + ++state; + } else if (d == EQUALS) { + // Emit the last (partial) output tuple; + // expect exactly one more padding character. + output[op++] = (byte) (value >> 4); + state = 4; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + + case 3: + if (d >= 0) { + // Emit the output triple and return to state 0. + value = (value << 6) | d; + output[op+2] = (byte) value; + output[op+1] = (byte) (value >> 8); + output[op] = (byte) (value >> 16); + op += 3; + state = 0; + } else if (d == EQUALS) { + // Emit the last (partial) output tuple; + // expect no further data or padding characters. + output[op+1] = (byte) (value >> 2); + output[op] = (byte) (value >> 10); + op += 2; + state = 5; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + + case 4: + if (d == EQUALS) { + ++state; + } else if (d != SKIP) { + this.state = 6; + return false; + } + break; + + case 5: + if (d != SKIP) { + this.state = 6; + return false; + } + break; + } + } + + if (!finish) { + // We're out of input, but a future call could provide + // more. + this.state = state; + this.value = value; + this.op = op; + return true; + } + + // Done reading input. Now figure out where we are left in + // the state machine and finish up. + + switch (state) { + case 0: + // Output length is a multiple of three. Fine. + break; + case 1: + // Read one extra input byte, which isn't enough to + // make another output byte. Illegal. + this.state = 6; + return false; + case 2: + // Read two extra input bytes, enough to emit 1 more + // output byte. Fine. + output[op++] = (byte) (value >> 4); + break; + case 3: + // Read three extra input bytes, enough to emit 2 more + // output bytes. Fine. + output[op++] = (byte) (value >> 10); + output[op++] = (byte) (value >> 2); + break; + case 4: + // Read one padding '=' when we expected 2. Illegal. + this.state = 6; + return false; + case 5: + // Read all the padding '='s we expected and no more. + // Fine. + break; + } + + this.state = state; + this.op = op; + return true; + } + } + + // -------------------------------------------------------- + // encoding + // -------------------------------------------------------- + + /** + * Base64-encode the given data and return a newly allocated + * String with the result. + * + * @param input the data to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static String encodeToString(final byte[] input, final int flags) { + try { + return new String(Base64.encode(input, flags), "US-ASCII"); + } catch (final UnsupportedEncodingException e) { + // US-ASCII is guaranteed to be available. + throw new AssertionError(e); + } + } + + /** + * Base64-encode the given data and return a newly allocated + * String with the result. + * + * @param input the data to encode + * @param offset the position within the input array at which to + * start + * @param len the number of bytes of input to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static String encodeToString(final byte[] input, final int offset, final int len, final int flags) { + try { + return new String(Base64.encode(input, offset, len, flags), "US-ASCII"); + } catch (final UnsupportedEncodingException e) { + // US-ASCII is guaranteed to be available. + throw new AssertionError(e); + } + } + + /** + * Base64-encode the given data and return a newly allocated + * byte[] with the result. + * + * @param input the data to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static byte[] encode(final byte[] input, final int flags) { + return Base64.encode(input, 0, input.length, flags); + } + + /** + * Base64-encode the given data and return a newly allocated + * byte[] with the result. + * + * @param input the data to encode + * @param offset the position within the input array at which to + * start + * @param len the number of bytes of input to encode + * @param flags controls certain features of the encoded output. + * Passing {@code DEFAULT} results in output that + * adheres to RFC 2045. + */ + public static byte[] encode(final byte[] input, final int offset, final int len, final int flags) { + final Encoder encoder = new Encoder(flags, null); + + // Compute the exact length of the array we will produce. + int output_len = len / 3 * 4; + + // Account for the tail of the data and the padding bytes, if any. + if (encoder.do_padding) { + if (len % 3 > 0) { + output_len += 4; + } + } else { + switch (len % 3) { + case 0: break; + case 1: output_len += 2; break; + case 2: output_len += 3; break; + } + } + + // Account for the newlines, if any. + if (encoder.do_newline && len > 0) { + output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) * + (encoder.do_cr ? 2 : 1); + } + + encoder.output = new byte[output_len]; + encoder.process(input, offset, len, true); + + assert encoder.op == output_len; + + return encoder.output; + } + + /* package */ static class Encoder extends Coder { + /** + * Emit a new line every this many output tuples. Corresponds to + * a 76-character line length (the maximum allowable according to + * RFC 2045). + */ + public static final int LINE_GROUPS = 19; + + /** + * Lookup table for turning Base64 alphabet positions (6 bits) + * into output bytes. + */ + private static final byte ENCODE[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', + }; + + /** + * Lookup table for turning Base64 alphabet positions (6 bits) + * into output bytes. + */ + private static final byte ENCODE_WEBSAFE[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_', + }; + + final private byte[] tail; + /* package */ int tailLen; + private int count; + + final public boolean do_padding; + final public boolean do_newline; + final public boolean do_cr; + final private byte[] alphabet; + + public Encoder(final int flags, final byte[] output) { + this.output = output; + + this.do_padding = (flags & NO_PADDING) == 0; + this.do_newline = (flags & NO_WRAP) == 0; + this.do_cr = (flags & CRLF) != 0; + this.alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE; + + this.tail = new byte[2]; + this.tailLen = 0; + + this.count = this.do_newline ? LINE_GROUPS : -1; + } + + /** + * @return an overestimate for the number of bytes {@code + * len} bytes could encode to. + */ + @Override + public int maxOutputSize(final int len) { + return len * 8/5 + 10; + } + + @Override + public boolean process(final byte[] input, final int offset, int len, final boolean finish) { + // Using local variables makes the encoder about 9% faster. + final byte[] alphabet = this.alphabet; + final byte[] output = this.output; + int op = 0; + int count = this.count; + + int p = offset; + len += offset; + int v = -1; + + // First we need to concatenate the tail of the previous call + // with any input bytes available now and see if we can empty + // the tail. + + switch (this.tailLen) { + case 0: + // There was no tail. + break; + + case 1: + if (p+2 <= len) { + // A 1-byte tail with at least 2 bytes of + // input available now. + v = ((this.tail[0] & 0xff) << 16) | + ((input[p++] & 0xff) << 8) | + (input[p++] & 0xff); + this.tailLen = 0; + }; + break; + + case 2: + if (p+1 <= len) { + // A 2-byte tail with at least 1 byte of input. + v = ((this.tail[0] & 0xff) << 16) | + ((this.tail[1] & 0xff) << 8) | + (input[p++] & 0xff); + this.tailLen = 0; + } + break; + } + + if (v != -1) { + output[op++] = alphabet[(v >> 18) & 0x3f]; + output[op++] = alphabet[(v >> 12) & 0x3f]; + output[op++] = alphabet[(v >> 6) & 0x3f]; + output[op++] = alphabet[v & 0x3f]; + if (--count == 0) { + if (this.do_cr) { + output[op++] = '\r'; + } + output[op++] = '\n'; + count = LINE_GROUPS; + } + } + + // At this point either there is no tail, or there are fewer + // than 3 bytes of input available. + + // The main loop, turning 3 input bytes into 4 output bytes on + // each iteration. + while (p+3 <= len) { + v = ((input[p] & 0xff) << 16) | + ((input[p+1] & 0xff) << 8) | + (input[p+2] & 0xff); + output[op] = alphabet[(v >> 18) & 0x3f]; + output[op+1] = alphabet[(v >> 12) & 0x3f]; + output[op+2] = alphabet[(v >> 6) & 0x3f]; + output[op+3] = alphabet[v & 0x3f]; + p += 3; + op += 4; + if (--count == 0) { + if (this.do_cr) { + output[op++] = '\r'; + } + output[op++] = '\n'; + count = LINE_GROUPS; + } + } + + if (finish) { + // Finish up the tail of the input. Note that we need to + // consume any bytes in tail before any bytes + // remaining in input; there should be at most two bytes + // total. + + if (p-this.tailLen == len-1) { + int t = 0; + v = ((this.tailLen > 0 ? this.tail[t++] : input[p++]) & 0xff) << 4; + this.tailLen -= t; + output[op++] = alphabet[(v >> 6) & 0x3f]; + output[op++] = alphabet[v & 0x3f]; + if (this.do_padding) { + output[op++] = '='; + output[op++] = '='; + } + if (this.do_newline) { + if (this.do_cr) { + output[op++] = '\r'; + } + output[op++] = '\n'; + } + } else if (p-this.tailLen == len-2) { + int t = 0; + v = (((this.tailLen > 1 ? this.tail[t++] : input[p++]) & 0xff) << 10) | + (((this.tailLen > 0 ? this.tail[t++] : input[p++]) & 0xff) << 2); + this.tailLen -= t; + output[op++] = alphabet[(v >> 12) & 0x3f]; + output[op++] = alphabet[(v >> 6) & 0x3f]; + output[op++] = alphabet[v & 0x3f]; + if (this.do_padding) { + output[op++] = '='; + } + if (this.do_newline) { + if (this.do_cr) { + output[op++] = '\r'; + } + output[op++] = '\n'; + } + } else if (this.do_newline && op > 0 && count != LINE_GROUPS) { + if (this.do_cr) { + output[op++] = '\r'; + } + output[op++] = '\n'; + } + + assert this.tailLen == 0; + assert p == len; + } else { + // Save the leftovers in tail to be consumed on the next + // call to encodeInternal. + + if (p == len-1) { + this.tail[this.tailLen++] = input[p]; + } else if (p == len-2) { + this.tail[this.tailLen++] = input[p]; + this.tail[this.tailLen++] = input[p+1]; + } + } + + this.op = op; + this.count = count; + + return true; + } + } + + private Base64() { } // don't instantiate +} diff --git a/AndEngine/src/org/anddev/andengine/util/Base64InputStream.java b/AndEngine/src/org/anddev/andengine/util/Base64InputStream.java new file mode 100644 index 0000000..8671ed6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Base64InputStream.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.anddev.andengine.util; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * An InputStream that does Base64 decoding on the data read through + * it. + */ +public class Base64InputStream extends FilterInputStream { + private final Base64.Coder coder; + + private static byte[] EMPTY = new byte[0]; + + private static final int BUFFER_SIZE = 2048; + private boolean eof; + private byte[] inputBuffer; + private int outputStart; + private int outputEnd; + + /** + * An InputStream that performs Base64 decoding on the data read + * from the wrapped stream. + * + * @param in the InputStream to read the source data from + * @param flags bit flags for controlling the decoder; see the + * constants in {@link Base64} + */ + public Base64InputStream(final InputStream in, final int flags) { + this(in, flags, false); + } + + /** + * Performs Base64 encoding or decoding on the data read from the + * wrapped InputStream. + * + * @param in the InputStream to read the source data from + * @param flags bit flags for controlling the decoder; see the + * constants in {@link Base64} + * @param encode true to encode, false to decode + * + * @hide + */ + public Base64InputStream(final InputStream in, final int flags, final boolean encode) { + super(in); + this.eof = false; + this.inputBuffer = new byte[BUFFER_SIZE]; + if (encode) { + this.coder = new Base64.Encoder(flags, null); + } else { + this.coder = new Base64.Decoder(flags, null); + } + this.coder.output = new byte[this.coder.maxOutputSize(BUFFER_SIZE)]; + this.outputStart = 0; + this.outputEnd = 0; + } + + @Override + public boolean markSupported() { + return false; + } + + @Override + public void mark(final int readlimit) { + throw new UnsupportedOperationException(); + } + + @Override + public void reset() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() throws IOException { + this.in.close(); + this.inputBuffer = null; + } + + @Override + public int available() { + return this.outputEnd - this.outputStart; + } + + @Override + public long skip(final long n) throws IOException { + if (this.outputStart >= this.outputEnd) { + this.refill(); + } + if (this.outputStart >= this.outputEnd) { + return 0; + } + final long bytes = Math.min(n, this.outputEnd-this.outputStart); + this.outputStart += bytes; + return bytes; + } + + @Override + public int read() throws IOException { + if (this.outputStart >= this.outputEnd) { + this.refill(); + } + if (this.outputStart >= this.outputEnd) { + return -1; + } else { + return this.coder.output[this.outputStart++]; + } + } + + @Override + public int read(final byte[] b, final int off, final int len) throws IOException { + if (this.outputStart >= this.outputEnd) { + this.refill(); + } + if (this.outputStart >= this.outputEnd) { + return -1; + } + final int bytes = Math.min(len, this.outputEnd-this.outputStart); + System.arraycopy(this.coder.output, this.outputStart, b, off, bytes); + this.outputStart += bytes; + return bytes; + } + + /** + * Read data from the input stream into inputBuffer, then + * decode/encode it into the empty coder.output, and reset the + * outputStart and outputEnd pointers. + */ + private void refill() throws IOException { + if (this.eof) { + return; + } + final int bytesRead = this.in.read(this.inputBuffer); + boolean success; + if (bytesRead == -1) { + this.eof = true; + success = this.coder.process(EMPTY, 0, 0, true); + } else { + success = this.coder.process(this.inputBuffer, 0, bytesRead, false); + } + if (!success) { + throw new IOException("bad base-64"); + } + this.outputEnd = this.coder.op; + this.outputStart = 0; + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/BetaUtils.java b/AndEngine/src/org/anddev/andengine/util/BetaUtils.java new file mode 100644 index 0000000..415c15d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/BetaUtils.java @@ -0,0 +1,96 @@ +package org.anddev.andengine.util; + +import java.util.GregorianCalendar; + +import org.anddev.andengine.util.constants.Constants; + +import android.R; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.content.SharedPreferences; + + +/** + * @author Nicolas Gramlich + * @since 22:43:32 - 02.11.2010 + */ +public class BetaUtils implements Constants { + // =========================================================== + // Constants + // =========================================================== + + private static final String PREFERENCES_BETAUTILS_ID = "preferences.betautils.lastuse"; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean finishWhenExpired(final Activity pActivity, final GregorianCalendar pExpirationDate, final int pTitleResourceID, final int pMessageResourceID) { + return BetaUtils.finishWhenExpired(pActivity, pExpirationDate, pTitleResourceID, pMessageResourceID, null, null); + } + + public static boolean finishWhenExpired(final Activity pActivity, final GregorianCalendar pExpirationDate, final int pTitleResourceID, final int pMessageResourceID, final Intent pOkIntent, final Intent pCancelIntent) { + final SharedPreferences spref = SimplePreferences.getInstance(pActivity); + + final long now = System.currentTimeMillis(); + final long lastuse = Math.max(now, spref.getLong(PREFERENCES_BETAUTILS_ID, -1)); + spref.edit().putLong(PREFERENCES_BETAUTILS_ID, lastuse).commit(); + + final GregorianCalendar lastuseDate = new GregorianCalendar(); + lastuseDate.setTimeInMillis(lastuse); + + if(lastuseDate.after(pExpirationDate)){ + final Builder alertDialogBuilder = new AlertDialog.Builder(pActivity) + .setTitle(pTitleResourceID) + .setIcon(R.drawable.ic_dialog_alert) + .setMessage(pMessageResourceID); + + alertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){ + @Override + public void onClick(final DialogInterface pDialog, final int pWhich) { + if(pOkIntent != null) { + pActivity.startActivity(pOkIntent); + } + pActivity.finish(); + } + }); + alertDialogBuilder.setNegativeButton(android.R.string.cancel, new OnClickListener() { + @Override + public void onClick(final DialogInterface pDialog, final int pWhich) { + if(pCancelIntent != null) { + pActivity.startActivity(pCancelIntent); + } + pActivity.finish(); + } + }) + .create().show(); + return true; + }else{ + return false; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/Callable.java b/AndEngine/src/org/anddev/andengine/util/Callable.java new file mode 100644 index 0000000..970f414 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Callable.java @@ -0,0 +1,23 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 20:52:44 - 03.01.2010 + */ +public interface Callable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * Computes a result, or throws an exception if unable to do so. + * + * @return the computed result. + * @throws Exception if unable to compute a result. + */ + public T call() throws Exception; +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/Callback.java b/AndEngine/src/org/anddev/andengine/util/Callback.java new file mode 100644 index 0000000..5147706 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Callback.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 09:40:55 - 14.12.2009S + */ +public interface Callback { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onCallback(final T pCallbackValue); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/ColorUtils.java b/AndEngine/src/org/anddev/andengine/util/ColorUtils.java new file mode 100644 index 0000000..ed52c43 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ColorUtils.java @@ -0,0 +1,60 @@ +package org.anddev.andengine.util; + +import android.graphics.Color; + +/** + * @author Nicolas Gramlich + * @since 11:13:45 - 04.08.2010 + */ +public class ColorUtils { + // =========================================================== + // Constants + // =========================================================== + + private static final float[] HSV_TO_COLOR = new float[3]; + private static final int HSV_TO_COLOR_HUE_INDEX = 0; + private static final int HSV_TO_COLOR_SATURATION_INDEX = 1; + private static final int HSV_TO_COLOR_VALUE_INDEX = 2; + + private static final int COLOR_FLOAT_TO_INT_FACTOR = 255; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + /** + * @param pHue [0 .. 360) + * @param pSaturation [0...1] + * @param pValue [0...1] + */ + public static int HSVToColor(final float pHue, final float pSaturation, final float pValue) { + HSV_TO_COLOR[HSV_TO_COLOR_HUE_INDEX] = pHue; + HSV_TO_COLOR[HSV_TO_COLOR_SATURATION_INDEX] = pSaturation; + HSV_TO_COLOR[HSV_TO_COLOR_VALUE_INDEX] = pValue; + return Color.HSVToColor(HSV_TO_COLOR); + } + + public static int RGBToColor(final float pRed, final float pGreen, final float pBlue) { + return Color.rgb((int)(pRed * COLOR_FLOAT_TO_INT_FACTOR), (int)(pGreen * COLOR_FLOAT_TO_INT_FACTOR), (int)(pBlue * COLOR_FLOAT_TO_INT_FACTOR)); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/DataUtils.java b/AndEngine/src/org/anddev/andengine/util/DataUtils.java new file mode 100644 index 0000000..6f013dd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/DataUtils.java @@ -0,0 +1,39 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 15:01:49 - 20.03.2011 + */ +public class DataUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public static int unsignedByteToInt(final byte bByte) { + return bByte & 0xFF; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/Debug.java b/AndEngine/src/org/anddev/andengine/util/Debug.java new file mode 100644 index 0000000..9f86739 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Debug.java @@ -0,0 +1,142 @@ +package org.anddev.andengine.util; + +import org.anddev.andengine.util.constants.Constants; + +import android.util.Log; + +/** + * @author Nicolas Gramlich + * @since 13:29:16 - 08.03.2010 + */ +public class Debug implements Constants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static String sDebugTag = DEBUGTAG; + private static DebugLevel sDebugLevel = DebugLevel.VERBOSE; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public static String getDebugTag() { + return Debug.sDebugTag; + } + + public static void setDebugTag(final String pDebugTag) { + Debug.sDebugTag = pDebugTag; + } + + public static DebugLevel getDebugLevel() { + return Debug.sDebugLevel; + } + + public static void setDebugLevel(final DebugLevel pDebugLevel) { + if(pDebugLevel == null) { + throw new IllegalArgumentException("pDebugLevel must not be null!"); + } + Debug.sDebugLevel = pDebugLevel; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static void v(final String pMessage) { + Debug.v(pMessage, null); + } + + public static void v(final String pMessage, final Throwable pThrowable) { + if(sDebugLevel.isSameOrLessThan(DebugLevel.VERBOSE)) { + Log.v(sDebugTag, pMessage, pThrowable); + } + } + + public static void d(final String pMessage) { + Debug.d(pMessage, null); + } + + public static void d(final String pMessage, final Throwable pThrowable) { + if(sDebugLevel.isSameOrLessThan(DebugLevel.DEBUG)) { + Log.d(sDebugTag, pMessage, pThrowable); + } + } + + public static void i(final String pMessage) { + Debug.i(pMessage, null); + } + + public static void i(final String pMessage, final Throwable pThrowable) { + if(sDebugLevel.isSameOrLessThan(DebugLevel.INFO)) { + Log.i(sDebugTag, pMessage, pThrowable); + } + } + + public static void w(final String pMessage) { + Debug.w(pMessage, null); + } + + public static void w(final Throwable pThrowable) { + Debug.w(sDebugTag, pThrowable); + } + + public static void w(final String pMessage, final Throwable pThrowable) { + if(sDebugLevel.isSameOrLessThan(DebugLevel.WARNING)) { + if(pThrowable == null) { + Log.w(sDebugTag, pMessage, new Exception()); + } else { + Log.w(sDebugTag, pMessage, pThrowable); + } + } + } + + public static void e(final String pMessage) { + Debug.e(pMessage, null); + } + + public static void e(final Throwable pThrowable) { + Debug.e(sDebugTag, pThrowable); + } + + public static void e(final String pMessage, final Throwable pThrowable) { + if(sDebugLevel.isSameOrLessThan(DebugLevel.ERROR)) { + if(pThrowable == null) { + Log.e(sDebugTag, pMessage, new Exception()); + } else { + Log.e(sDebugTag, pMessage, pThrowable); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static enum DebugLevel implements Comparable { + NONE, + ERROR, + WARNING, + INFO, + DEBUG, + VERBOSE; + + public static DebugLevel ALL = DebugLevel.VERBOSE; + + private boolean isSameOrLessThan(final DebugLevel pDebugLevel) { + return this.compareTo(pDebugLevel) >= 0; + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/FileUtils.java b/AndEngine/src/org/anddev/andengine/util/FileUtils.java new file mode 100644 index 0000000..32301b6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/FileUtils.java @@ -0,0 +1,159 @@ +package org.anddev.andengine.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; + +import android.content.Context; +import android.os.Environment; + +/** + * @author Nicolas Gramlich + * @since 13:53:33 - 20.06.2010 + */ +public class FileUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static void copyToExternalStorage(final Context pContext, final int pSourceResourceID, final String pFilename) throws FileNotFoundException { + FileUtils.copyToExternalStorage(pContext, pContext.getResources().openRawResource(pSourceResourceID), pFilename); + } + + public static void copyToExternalStorage(final Context pContext, final String pSourceAssetPath, final String pFilename) throws IOException { + FileUtils.copyToExternalStorage(pContext, pContext.getAssets().open(pSourceAssetPath), pFilename); + } + + public static void copyToExternalStorage(final Context pContext, final InputStream pInputStream, final String pFilename) throws FileNotFoundException { + if (FileUtils.isExternalStorageWriteable()) { + final String absoluteFilePath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pFilename); + StreamUtils.copyAndClose(pInputStream, new FileOutputStream(absoluteFilePath)); + } else { + throw new IllegalStateException("External Storage is not writeable."); + } + } + + public static boolean isFileExistingOnExternalStorage(final Context pContext, final String pFilename) { + if (FileUtils.isExternalStorageReadable()) { + final String absoluteFilePath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pFilename); + final File file = new File(absoluteFilePath); + return file.exists()&& file.isFile(); + } else { + throw new IllegalStateException("External Storage is not readable."); + } + } + + public static boolean isDirectoryExistingOnExternalStorage(final Context pContext, final String pDirectory) { + if (FileUtils.isExternalStorageReadable()) { + final String absoluteFilePath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pDirectory); + final File file = new File(absoluteFilePath); + return file.exists() && file.isDirectory(); + } else { + throw new IllegalStateException("External Storage is not readable."); + } + } + + public static boolean ensureDirectoriesExistOnExternalStorage(final Context pContext, final String pDirectory) { + if(FileUtils.isDirectoryExistingOnExternalStorage(pContext, pDirectory)) { + return true; + } + + if (FileUtils.isExternalStorageWriteable()) { + final String absoluteDirectoryPath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pDirectory); + return new File(absoluteDirectoryPath).mkdirs(); + } else { + throw new IllegalStateException("External Storage is not writeable."); + } + } + + public static InputStream openOnExternalStorage(final Context pContext, final String pFilename) throws FileNotFoundException { + final String absoluteFilePath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pFilename); + return new FileInputStream(absoluteFilePath); + } + + public static String[] getDirectoryListOnExternalStorage(final Context pContext, final String pFilename) throws FileNotFoundException { + final String absoluteFilePath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pFilename); + return new File(absoluteFilePath).list(); + } + + public static String[] getDirectoryListOnExternalStorage(final Context pContext, final String pFilename, final FilenameFilter pFilenameFilter) throws FileNotFoundException { + final String absoluteFilePath = FileUtils.getAbsolutePathOnExternalStorage(pContext, pFilename); + return new File(absoluteFilePath).list(pFilenameFilter); + } + + public static String getAbsolutePathOnExternalStorage(final Context pContext, final String pFilename) { + return Environment.getExternalStorageDirectory() + "/Android/data/" + pContext.getApplicationInfo().packageName + "/files/" + pFilename; + } + + public static boolean isExternalStorageWriteable() { + return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); + } + + public static boolean isExternalStorageReadable() { + final String state = Environment.getExternalStorageState(); + return state.equals(Environment.MEDIA_MOUNTED) || state.equals(Environment.MEDIA_MOUNTED_READ_ONLY); + } + + public static void copyFile(final File pIn, final File pOut) throws IOException { + final FileInputStream fis = new FileInputStream(pIn); + final FileOutputStream fos = new FileOutputStream(pOut); + try { + StreamUtils.copy(fis, fos); + } finally { + StreamUtils.close(fis); + StreamUtils.close(fos); + } + } + + /** + * Deletes all files and sub-directories under dir. Returns + * true if all deletions were successful. If a deletion fails, the method + * stops attempting to delete and returns false. + * + * @param pFileOrDirectory + * @return + */ + public static boolean deleteDirectory(final File pFileOrDirectory) { + if(pFileOrDirectory.isDirectory()) { + final String[] children = pFileOrDirectory.list(); + final int childrenCount = children.length; + for(int i = 0; i < childrenCount; i++) { + final boolean success = FileUtils.deleteDirectory(new File(pFileOrDirectory, children[i])); + if(!success) { + return false; + } + } + } + + // The directory is now empty so delete it + return pFileOrDirectory.delete(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/HorizontalAlign.java b/AndEngine/src/org/anddev/andengine/util/HorizontalAlign.java new file mode 100644 index 0000000..5ef20cd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/HorizontalAlign.java @@ -0,0 +1,43 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 10:47:33 - 11.05.2010 + */ +public enum HorizontalAlign { + // =========================================================== + // Elements + // =========================================================== + + LEFT, + CENTER, + RIGHT; + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/IMatcher.java b/AndEngine/src/org/anddev/andengine/util/IMatcher.java new file mode 100644 index 0000000..dff0419 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/IMatcher.java @@ -0,0 +1,18 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 12:32:22 - 26.12.2010 + */ +public interface IMatcher { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public boolean matches(final T pObject); +} + diff --git a/AndEngine/src/org/anddev/andengine/util/Library.java b/AndEngine/src/org/anddev/andengine/util/Library.java new file mode 100644 index 0000000..431b9c6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Library.java @@ -0,0 +1,65 @@ +package org.anddev.andengine.util; + +import android.util.SparseArray; + +/** + * @author Nicolas Gramlich + * @since 11:51:29 - 20.08.2010 + * @param + */ +public class Library { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected final SparseArray mItems; + + // =========================================================== + // Constructors + // =========================================================== + + public Library() { + this.mItems = new SparseArray(); + } + + public Library(final int pInitialCapacity) { + this.mItems = new SparseArray(pInitialCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void put(final int pID, final T pItem) { + final T existingItem = this.mItems.get(pID); + if(existingItem == null) { + this.mItems.put(pID, pItem); + } else { + throw new IllegalArgumentException("ID: '" + pID + "' is already associated with item: '" + existingItem.toString() + "'."); + } + } + + public void remove(final int pID) { + this.mItems.remove(pID); + } + + public T get(final int pID) { + return this.mItems.get(pID); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/ListUtils.java b/AndEngine/src/org/anddev/andengine/util/ListUtils.java new file mode 100644 index 0000000..e6b27c0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ListUtils.java @@ -0,0 +1,43 @@ +package org.anddev.andengine.util; + +import java.util.ArrayList; + +/** + * @author Nicolas Gramlich + * @since 12:43:39 - 11.03.2010 + */ +public class ListUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static ArrayList toList(final T pElement) { + final ArrayList out = new ArrayList(); + out.add(pElement); + return out; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/MathUtils.java b/AndEngine/src/org/anddev/andengine/util/MathUtils.java new file mode 100644 index 0000000..3c257df --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/MathUtils.java @@ -0,0 +1,207 @@ +package org.anddev.andengine.util; + +import java.util.Random; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 20:42:15 - 17.12.2009 + */ +public class MathUtils implements MathConstants { + // =========================================================== + // Constants + // =========================================================== + + public static Random RANDOM = new Random(System.nanoTime()); + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static float atan2(final float dY, final float dX) { + return (float)Math.atan2(dY, dX); + } + + public static final float radToDeg(final float pRad) { + return RAD_TO_DEG * pRad; + } + + public static final float degToRad(final float pDegree) { + return DEG_TO_RAD * pDegree; + } + + public static final int randomSign() { + if(RANDOM.nextBoolean()) { + return 1; + } else { + return -1; + } + } + + public static final float random(final float pMin, final float pMax) { + return pMin + RANDOM.nextFloat() * (pMax - pMin); + } + + /** + * @param pMin inclusive! + * @param pMax inclusive! + * @return + */ + public static final int random(final int pMin, final int pMax) { + return pMin + RANDOM.nextInt(pMax - pMin + 1); + } + + public static final boolean isPowerOfTwo(final int n) { + return ((n != 0) && (n & (n - 1)) == 0); + } + + public static final int nextPowerOfTwo(final int n) { + int k = n; + + if (k == 0) { + return 1; + } + + k--; + + for (int i = 1; i < 32; i <<= 1) { + k = k | k >> i; + } + + return k + 1; + } + + public static final int sum(final int[] pValues) { + int sum = 0; + for(int i = pValues.length - 1; i >= 0; i--) { + sum += pValues[i]; + } + + return sum; + } + + public static final void arraySumInternal(final int[] pValues) { + final int valueCount = pValues.length; + for(int i = 1; i < valueCount; i++) { + pValues[i] = pValues[i-1] + pValues[i]; + } + } + + public static final void arraySumInternal(final long[] pValues) { + final int valueCount = pValues.length; + for(int i = 1; i < valueCount; i++) { + pValues[i] = pValues[i-1] + pValues[i]; + } + } + + public static final void arraySumInternal(final long[] pValues, final long pFactor) { + pValues[0] = pValues[0] * pFactor; + final int valueCount = pValues.length; + for(int i = 1; i < valueCount; i++) { + pValues[i] = pValues[i-1] + pValues[i] * pFactor; + } + } + + public static final void arraySumInto(final long[] pValues, final long[] pTargetValues, final long pFactor) { + pTargetValues[0] = pValues[0] * pFactor; + final int valueCount = pValues.length; + for(int i = 1; i < valueCount; i++) { + pTargetValues[i] = pTargetValues[i-1] + pValues[i] * pFactor; + } + } + + public static final float arraySum(final float[] pValues) { + float sum = 0; + final int valueCount = pValues.length; + for(int i = 0; i < valueCount; i++) { + sum += pValues[i]; + } + return sum; + } + + public static final float arrayAverage(final float[] pValues) { + return MathUtils.arraySum(pValues) / pValues.length; + } + + public static float[] rotateAroundCenter(final float[] pVertices, final float pRotation, final float pRotationCenterX, final float pRotationCenterY) { + if(pRotation != 0) { + final float rotationRad = MathUtils.degToRad(pRotation); + final float sinRotationRad = FloatMath.sin(rotationRad); + final float cosRotationInRad = FloatMath.cos(rotationRad); + + for(int i = pVertices.length - 2; i >= 0; i -= 2) { + final float pX = pVertices[i]; + final float pY = pVertices[i + 1]; + pVertices[i] = pRotationCenterX + (cosRotationInRad * (pX - pRotationCenterX) - sinRotationRad * (pY - pRotationCenterY)); + pVertices[i + 1] = pRotationCenterY + (sinRotationRad * (pX - pRotationCenterX) + cosRotationInRad * (pY - pRotationCenterY)); + } + } + return pVertices; + } + + public static float[] scaleAroundCenter(final float[] pVertices, final float pScaleX, final float pScaleY, final float pScaleCenterX, final float pScaleCenterY) { + if(pScaleX != 1 || pScaleY != 1) { + for(int i = pVertices.length - 2; i >= 0; i -= 2) { + pVertices[i] = pScaleCenterX + (pVertices[i] - pScaleCenterX) * pScaleX; + pVertices[i + 1] = pScaleCenterY + (pVertices[i + 1] - pScaleCenterY) * pScaleY; + } + } + + return pVertices; + } + + public static float[] rotateAndScaleAroundCenter(final float[] pVertices, final float pRotation, final float pRotationCenterX, final float pRotationCenterY, final float pScaleX, final float pScaleY, final float pScaleCenterX, final float pScaleCenterY) { + MathUtils.rotateAroundCenter(pVertices, pRotation, pRotationCenterX, pRotationCenterY); + return MathUtils.scaleAroundCenter(pVertices, pScaleX, pScaleY, pScaleCenterX, pScaleCenterY); + } + + public static float[] revertScaleAroundCenter(final float[] pVertices, final float pScaleX, final float pScaleY, final float pScaleCenterX, final float pScaleCenterY) { + return MathUtils.scaleAroundCenter(pVertices, 1 / pScaleX, 1 / pScaleY, pScaleCenterX, pScaleCenterY); + } + + public static float[] revertRotateAroundCenter(final float[] pVertices, final float pRotation, final float pRotationCenterX, final float pRotationCenterY) { + return MathUtils.rotateAroundCenter(pVertices, -pRotation, pRotationCenterX, pRotationCenterY); + } + + public static float[] revertRotateAndScaleAroundCenter(final float[] pVertices, final float pRotation, final float pRotationCenterX, final float pRotationCenterY, final float pScaleX, final float pScaleY, final float pScaleCenterX, final float pScaleCenterY) { + MathUtils.revertScaleAroundCenter(pVertices, pScaleX, pScaleY, pScaleCenterX, pScaleCenterY); + return MathUtils.revertRotateAroundCenter(pVertices, pRotation, pRotationCenterX, pRotationCenterY); + } + + public static int bringToBounds(final int pMinValue, final int pMaxValue, final int pValue) { + return Math.max(pMinValue, Math.min(pMaxValue, pValue)); + } + + public static float bringToBounds(final float pMinValue, final float pMaxValue, final float pValue) { + return Math.max(pMinValue, Math.min(pMaxValue, pValue)); + } + + public static float distance(final float pX1, final float pY1, final float pX2, final float pY2){ + final float dX = pX2 - pX1; + final float dY = pY2 - pY1; + return FloatMath.sqrt((dX * dX) + (dY * dY)); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/MultiKey.java b/AndEngine/src/org/anddev/andengine/util/MultiKey.java new file mode 100644 index 0000000..c0f139d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/MultiKey.java @@ -0,0 +1,89 @@ +package org.anddev.andengine.util; + +import java.util.Arrays; + +public class MultiKey { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 4465448607415788805L; + + // =========================================================== + // Fields + // =========================================================== + + private final K[] mKeys; + private final int mCachedHashCode; + + // =========================================================== + // Constructors + // =========================================================== + + public MultiKey(final K... pKeys) { + this.mKeys = pKeys; + + this.mCachedHashCode = MultiKey.hash(pKeys); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public K[] getKeys() { + return this.mKeys; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean equals(final Object pOther) { + if(pOther == this) { + return true; + } + if(pOther instanceof MultiKey) { + final MultiKey otherMultiKey = (MultiKey) pOther; + return Arrays.equals(this.mKeys, otherMultiKey.mKeys); + } + return false; + } + + public static int hash(final Object ... pKeys) { + int hashCode = 0; + for(final Object key : pKeys) { + if(key != null) { + hashCode ^= key.hashCode(); + } + } + return hashCode; + } + + + @Override + public int hashCode() { + return this.mCachedHashCode; + } + + @Override + public String toString() { + return "MultiKey" + Arrays.asList(this.mKeys).toString(); + } + + // =========================================================== + // Methods + // =========================================================== + + public K getKey(final int pIndex) { + return this.mKeys[pIndex]; + } + + public int size() { + return this.mKeys.length; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/MultiKeyHashMap.java b/AndEngine/src/org/anddev/andengine/util/MultiKeyHashMap.java new file mode 100644 index 0000000..3a515f0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/MultiKeyHashMap.java @@ -0,0 +1,75 @@ +package org.anddev.andengine.util; + +import java.util.HashMap; +import java.util.Iterator; + +/** + * @author Nicolas Gramlich + * @since 16:54:24 - 07.11.2010 + */ +public class MultiKeyHashMap extends HashMap, V> { + // =========================================================== + // Constants + // ========================================================== + + private static final long serialVersionUID = -6262447639526561122L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public V get(final K ... pKeys) { + final int hashCode = MultiKey.hash(pKeys); + + final Iterator, V>> it = this.entrySet().iterator(); + while(it.hasNext()) { + final Entry, V> entry = it.next(); + final MultiKey entryKey = entry.getKey(); + if (entryKey.hashCode() == hashCode && this.isEqualKey(entryKey.getKeys(), pKeys)) { + return entry.getValue(); + } + } + return null; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + private boolean isEqualKey(final K[] pKeysA, final K[] pKeysB) { + if (pKeysA.length != pKeysB.length) { + return false; + } else { + for (int i = 0; i < pKeysA.length; i++) { + final K keyA = pKeysA[i]; + final K keyB = pKeysB[i]; + if(keyA == null) { + if(keyB != null) { + return false; + } + } else { + if(!keyA.equals(keyB)) { + return false; + } + } + } + } + return true; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/ParameterCallable.java b/AndEngine/src/org/anddev/andengine/util/ParameterCallable.java new file mode 100644 index 0000000..478a0bd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ParameterCallable.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 23:40:42 - 27.12.2010 + */ +public interface ParameterCallable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void call(final T pParameter); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/ProbabilityGenerator.java b/AndEngine/src/org/anddev/andengine/util/ProbabilityGenerator.java new file mode 100644 index 0000000..9c66515 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ProbabilityGenerator.java @@ -0,0 +1,109 @@ +package org.anddev.andengine.util; + +import java.util.ArrayList; + +public class ProbabilityGenerator { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mProbabilitySum; + private final ArrayList> mEntries = new ArrayList>(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void add(final float pFactor, final T ... pElements){ + this.mProbabilitySum += pFactor; + this.mEntries.add(new Entry(pFactor, pElements)); + } + + public T next() { + float random = MathUtils.random(0, this.mProbabilitySum); + + final ArrayList> factors = this.mEntries; + + for(int i = factors.size() - 1; i >= 0; i--){ + final Entry entry = factors.get(i); + random -= entry.mFactor; + if(random <= 0){ + return entry.getReturnValue(); + } + } + + final Entry lastEntry = factors.get(factors.size() - 1); + return lastEntry.getReturnValue(); + } + + public void clear() { + this.mProbabilitySum = 0; + this.mEntries.clear(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private static class Entry { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public final float mFactor; + public final T[] mData; + + // =========================================================== + // Constructors + // =========================================================== + + public Entry(final float pFactor, final T[] pData){ + this.mFactor = pFactor; + this.mData = pData; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public T getReturnValue() { + if(this.mData.length == 1){ + return this.mData[0]; + }else{ + return ArrayUtils.random(mData); + } + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/SAXUtils.java b/AndEngine/src/org/anddev/andengine/util/SAXUtils.java new file mode 100644 index 0000000..14007e5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/SAXUtils.java @@ -0,0 +1,152 @@ +package org.anddev.andengine.util; + +import org.xml.sax.Attributes; + +/** + * @author Nicolas Gramlich + * @since 22:02:09 - 21.07.2010 + */ +public class SAXUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static String getAttribute(final Attributes pAttributes, final String pAttributeName, final String pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? value : pDefaultValue; + } + + public static String getAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + final String value = pAttributes.getValue("", pAttributeName); + if(value != null) { + return value; + } else { + throw new IllegalArgumentException("No value found for attribute: '" + pAttributeName + "'"); + } + } + + public static boolean getBooleanAttribute(final Attributes pAttributes, final String pAttributeName, final boolean pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Boolean.parseBoolean(value) : pDefaultValue; + } + + public static boolean getBooleanAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Boolean.parseBoolean(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + public static byte getByteAttribute(final Attributes pAttributes, final String pAttributeName, final byte pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Byte.parseByte(value) : pDefaultValue; + } + + public static byte getByteAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Byte.parseByte(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + + public static short getShortAttribute(final Attributes pAttributes, final String pAttributeName, final short pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Short.parseShort(value) : pDefaultValue; + } + + public static short getShortAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Short.parseShort(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + + public static int getIntAttribute(final Attributes pAttributes, final String pAttributeName, final int pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Integer.parseInt(value) : pDefaultValue; + } + + public static int getIntAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Integer.parseInt(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + + public static long getLongAttribute(final Attributes pAttributes, final String pAttributeName, final long pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Long.parseLong(value) : pDefaultValue; + } + + public static long getLongAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Long.parseLong(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + + public static float getFloatAttribute(final Attributes pAttributes, final String pAttributeName, final float pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Float.parseFloat(value) : pDefaultValue; + } + + public static float getFloatAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Float.parseFloat(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + + public static double getDoubleAttribute(final Attributes pAttributes, final String pAttributeName, final double pDefaultValue) { + final String value = pAttributes.getValue("", pAttributeName); + return (value != null) ? Double.parseDouble(value) : pDefaultValue; + } + + public static double getDoubleAttributeOrThrow(final Attributes pAttributes, final String pAttributeName) { + return Double.parseDouble(SAXUtils.getAttributeOrThrow(pAttributes, pAttributeName)); + } + + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final boolean pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final byte pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final short pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final int pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final long pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final float pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final double pValue) { + SAXUtils.appendAttribute(pStringBuilder, pName, String.valueOf(pValue)); + } + + public static void appendAttribute(final StringBuilder pStringBuilder, final String pName, final String pValue) { + pStringBuilder.append(' ').append(pName).append('=').append('\"').append(pValue).append('\"'); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/SimplePreferences.java b/AndEngine/src/org/anddev/andengine/util/SimplePreferences.java new file mode 100644 index 0000000..4680019 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/SimplePreferences.java @@ -0,0 +1,78 @@ +package org.anddev.andengine.util; + +import org.anddev.andengine.util.constants.Constants; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; + +/** + * @author Nicolas Gramlich + * @since 18:55:12 - 02.08.2010 + */ +public class SimplePreferences implements Constants { + // =========================================================== + // Constants + // =========================================================== + + private static final String PREFERENCES_NAME = null; + + // =========================================================== + // Fields + // =========================================================== + + private static SharedPreferences INSTANCE; + private static Editor EDITORINSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + public static SharedPreferences getInstance(final Context ctx) { + if(SimplePreferences.INSTANCE == null) { + SimplePreferences.INSTANCE = ctx.getSharedPreferences(SimplePreferences.PREFERENCES_NAME, Context.MODE_PRIVATE); + } + return SimplePreferences.INSTANCE; + } + + public static Editor getEditorInstance(final Context ctx) { + if(SimplePreferences.EDITORINSTANCE == null) { + SimplePreferences.EDITORINSTANCE = SimplePreferences.getInstance(ctx).edit(); + } + return SimplePreferences.EDITORINSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static int incrementAccessCount(final Context pCtx, final String pKey) { + return SimplePreferences.incrementAccessCount(pCtx, pKey, 1); + } + + public static int incrementAccessCount(final Context pCtx, final String pKey, final int pIncrement) { + final SharedPreferences prefs = SimplePreferences.getInstance(pCtx); + final int accessCount = prefs.getInt(pKey, 0); + + final int newAccessCount = accessCount + pIncrement; + prefs.edit().putInt(pKey, newAccessCount).commit(); + + return newAccessCount; + } + + public static int getAccessCount(final Context pCtx, final String pKey) { + return SimplePreferences.getInstance(pCtx).getInt(pKey, 0); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/SmartList.java b/AndEngine/src/org/anddev/andengine/util/SmartList.java new file mode 100644 index 0000000..3005635 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/SmartList.java @@ -0,0 +1,112 @@ +package org.anddev.andengine.util; + +import java.util.ArrayList; + +/** + * @author Nicolas Gramlich + * @since 22:20:08 - 27.12.2010 + */ +public class SmartList extends ArrayList { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = -8335986399182700102L; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public SmartList() { + + } + + public SmartList(final int pCapacity) { + super(pCapacity); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + /** + * @param pItem the item to remove. + * @param pParameterCallable to be called with the removed item, if it was removed. + */ + public boolean remove(final T pItem, final ParameterCallable pParameterCallable) { + final boolean removed = this.remove(pItem); + if(removed) { + pParameterCallable.call(pItem); + } + return removed; + } + + public T remove(final IMatcher pMatcher) { + for(int i = 0; i < this.size(); i++) { + if(pMatcher.matches(this.get(i))) { + return this.remove(i); + } + } + return null; + } + + public boolean removeAll(final IMatcher pMatcher) { + boolean result = false; + for(int i = this.size() - 1; i >= 0; i--) { + if(pMatcher.matches(this.get(i))) { + this.remove(i); + result = true; + } + } + return result; + } + + /** + * @param pMatcher to find the items. + * @param pParameterCallable to be called with each matched item after it was removed. + */ + public boolean removeAll(final IMatcher pMatcher, final ParameterCallable pParameterCallable) { + boolean result = false; + for(int i = this.size() - 1; i >= 0; i--) { + if(pMatcher.matches(this.get(i))) { + final T removed = this.remove(i); + pParameterCallable.call(removed); + result = true; + } + } + return result; + } + + public void clear(final ParameterCallable pParameterCallable) { + for(int i = this.size() - 1; i >= 0; i--) { + final T removed = this.remove(i); + pParameterCallable.call(removed); + } + } + + public T find(final IMatcher pMatcher) { + for(int i = this.size() - 1; i >= 0; i--) { + final T item = this.get(i); + if(pMatcher.matches(item)) { + return item; + } + } + return null; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/SocketUtils.java b/AndEngine/src/org/anddev/andengine/util/SocketUtils.java new file mode 100644 index 0000000..226ac2a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/SocketUtils.java @@ -0,0 +1,62 @@ +package org.anddev.andengine.util; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * @author Nicolas Gramlich + * @since 14:42:15 - 18.09.2009 + */ +public class SocketUtils { + // =========================================================== + // Constants + // =========================================================== + + public static final String SOCKETEXCEPTION_MESSAGE_SOCKET_CLOSED = "socket closed"; + public static final String SOCKETEXCEPTION_MESSAGE_SOCKET_IS_CLOSED = "Socket is closed"; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static void closeSocket(final Socket pSocket) { + if(pSocket != null && !pSocket.isClosed()) { + try { + pSocket.close(); + } catch (final IOException e) { + Debug.e(e); + } + } + } + + public static void closeSocket(final ServerSocket pSocket) { + if(pSocket != null && !pSocket.isClosed()) { + try { + pSocket.close(); + } catch (final IOException e) { + Debug.e(e); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/StreamUtils.java b/AndEngine/src/org/anddev/andengine/util/StreamUtils.java new file mode 100644 index 0000000..0de86e4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/StreamUtils.java @@ -0,0 +1,161 @@ +package org.anddev.andengine.util; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.util.Scanner; + +/** + * @author Nicolas Gramlich + * @since 15:48:56 - 03.09.2009 + */ +public class StreamUtils { + // =========================================================== + // Constants + // =========================================================== + + public static final int IO_BUFFER_SIZE = 8 * 1024; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static final String readFully(final InputStream pInputStream) throws IOException { + final StringBuilder sb = new StringBuilder(); + final Scanner sc = new Scanner(pInputStream); + while(sc.hasNextLine()){ + sb.append(sc.nextLine()); + } + return sb.toString(); + } + + public static byte[] streamToBytes(final InputStream pInputStream) throws IOException { + return StreamUtils.streamToBytes(pInputStream, -1); + } + + public static byte[] streamToBytes(final InputStream pInputStream, final int pReadLimit) throws IOException { + final ByteArrayOutputStream os = new ByteArrayOutputStream(Math.min(pReadLimit, IO_BUFFER_SIZE)); + StreamUtils.copy(pInputStream, os, pReadLimit); + return os.toByteArray(); + } + + public static void copy(final InputStream pInputStream, final OutputStream pOutputStream) throws IOException { + StreamUtils.copy(pInputStream, pOutputStream, -1); + } + + public static boolean copyAndClose(final InputStream pInputStream, final OutputStream pOutputStream) { + try { + StreamUtils.copy(pInputStream, pOutputStream, -1); + return true; + } catch (final IOException e) { + return false; + } finally { + StreamUtils.close(pInputStream); + StreamUtils.close(pOutputStream); + } + } + + /** + * Copy the content of the input stream into the output stream, using a temporary + * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}. + * + * @param pInputStream The input stream to copy from. + * @param pOutputStream The output stream to copy to. + * @param pByteLimit not more than so much bytes to read, or unlimited if smaller than 0. + * + * @throws IOException If any error occurs during the copy. + */ + public static void copy(final InputStream pInputStream, final OutputStream pOutputStream, final long pByteLimit) throws IOException { + final byte[] b = new byte[IO_BUFFER_SIZE]; + long pBytesLeftToRead = pByteLimit; + int read; + if(pByteLimit < 0){ + while ((read = pInputStream.read(b)) != -1) { + pOutputStream.write(b, 0, read); + } + }else{ + while ((read = pInputStream.read(b)) != -1) { + if(pBytesLeftToRead > read){ + pOutputStream.write(b, 0, read); + pBytesLeftToRead -= read; + } else { + pOutputStream.write(b, 0, (int)pBytesLeftToRead); + break; + } + } + } + pOutputStream.flush(); + } + + /** + * Closes the specified stream. + * + * @param pCloseable The stream to close. + */ + public static void close(final Closeable pCloseable) { + if (pCloseable != null) { + try { + pCloseable.close(); + } catch (final IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Flushes and closes the specified stream. + * + * @param pOutputStream The stream to close. + */ + public static void flushCloseStream(final OutputStream pOutputStream) { + if (pOutputStream != null) { + try { + pOutputStream.flush(); + } catch (final IOException e) { + e.printStackTrace(); + } finally { + StreamUtils.close(pOutputStream); + } + } + } + + /** + * Flushes and closes the specified stream. + * + * @param pWriter The Writer to close. + */ + public static void flushCloseWriter(final Writer pWriter) { + if (pWriter != null) { + try { + pWriter.flush(); + } catch (final IOException e) { + e.printStackTrace(); + } finally { + StreamUtils.close(pWriter); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/StringUtils.java b/AndEngine/src/org/anddev/andengine/util/StringUtils.java new file mode 100644 index 0000000..e7eb6d8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/StringUtils.java @@ -0,0 +1,109 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 19:01:08 - 03.04.2010 + */ +public class StringUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static String padFront(final String pString, final char pPadChar, final int pLength) { + final int padCount = pLength - pString.length(); + if(padCount <= 0) { + return pString; + } else { + final StringBuilder sb = new StringBuilder(); + + for(int i = padCount - 1; i >= 0; i--) { + sb.append(pPadChar); + } + sb.append(pString); + + return sb.toString(); + } + } + + public static int countOccurrences(final String pString, final char pCharacter) { + int count = 0; + + int lastOccurrence = pString.indexOf(pCharacter, 0); + + while (lastOccurrence != -1) { + count++; + lastOccurrence = pString.indexOf(pCharacter, lastOccurrence + 1); + } + + return count; + } + + /** + * Split a String by a Character, i.e. Split lines by using '\n'.
+ * Same behavior as String.split("" + pCharacter); . + * + * @param pString + * @param pCharacter + * @return + */ + public static String[] split(final String pString, final char pCharacter) { + return StringUtils.split(pString, pCharacter, null); + } + + /** + * Split a String by a Character, i.e. Split lines by using '\n'.
+ * Same behavior as String.split("" + pCharacter); . + * + * @param pString + * @param pCharacter + * @param pReuse tries to reuse the String[] if the length is the same as the length needed. + * @return + */ + public static String[] split(final String pString, final char pCharacter, final String[] pReuse) { + final int partCount = StringUtils.countOccurrences(pString, pCharacter) + 1; + + final boolean reuseable = pReuse != null && pReuse.length == partCount; + final String[] out = (reuseable) ? pReuse : new String[partCount]; + + if(partCount == 0) { + out[0] = pString; + } else { + int from = 0; + int to; + + for (int i = 0; i < partCount - 1; i++) { + to = pString.indexOf(pCharacter, from); + out[i] = pString.substring(from, to); + from = to + 1; + } + + out[partCount - 1] = pString.substring(from, pString.length()); + } + + return out; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/SystemUtils.java b/AndEngine/src/org/anddev/andengine/util/SystemUtils.java new file mode 100644 index 0000000..aa33695 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/SystemUtils.java @@ -0,0 +1,213 @@ +package org.anddev.andengine.util; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.Scanner; +import java.util.regex.MatchResult; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; + +/** + * @author Nicolas Gramlich + * @since 15:50:31 - 14.07.2010 + */ +public class SystemUtils { + // =========================================================== + // Constants + // =========================================================== + + private static final String BOGOMIPS_PATTERN = "BogoMIPS[\\s]*:[\\s]*(\\d+\\.\\d+)[\\s]*\n"; + private static final String MEMTOTAL_PATTERN = "MemTotal[\\s]*:[\\s]*(\\d+)[\\s]*kB\n"; + private static final String MEMFREE_PATTERN = "MemFree[\\s]*:[\\s]*(\\d+)[\\s]*kB\n"; + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static boolean hasSystemFeature(final Context pContext, final String pFeature) { + try { + final Method PackageManager_hasSystemFeatures = PackageManager.class.getMethod("hasSystemFeature", new Class[] { String.class }); + return (PackageManager_hasSystemFeatures == null) ? false : (Boolean) PackageManager_hasSystemFeatures.invoke(pContext.getPackageManager(), pFeature); + } catch (final Throwable t) { + return false; + } + } + + /** + * @param pBuildVersionCode taken from {@link Build.VERSION_CODES}. + */ + public static boolean isAndroidVersionOrHigher(final int pBuildVersionCode) { + return Integer.parseInt(Build.VERSION.SDK) >= pBuildVersionCode; + } + + public static float getCPUBogoMips() throws SystemUtilsException { + final MatchResult matchResult = SystemUtils.matchSystemFile("/proc/cpuinfo", BOGOMIPS_PATTERN, 1000); + + try { + if(matchResult.groupCount() > 0) { + return Float.parseFloat(matchResult.group(1)); + } else { + throw new SystemUtilsException(); + } + } catch (final NumberFormatException e) { + throw new SystemUtilsException(e); + } + } + + /** + * @return in kiloBytes. + * @throws SystemUtilsException + */ + public static int getMemoryTotal() throws SystemUtilsException { + final MatchResult matchResult = SystemUtils.matchSystemFile("/proc/meminfo", MEMTOTAL_PATTERN, 1000); + + try { + if(matchResult.groupCount() > 0) { + return Integer.parseInt(matchResult.group(1)); + } else { + throw new SystemUtilsException(); + } + } catch (final NumberFormatException e) { + throw new SystemUtilsException(e); + } + } + + /** + * @return in kiloBytes. + * @throws SystemUtilsException + */ + public static int getMemoryFree() throws SystemUtilsException { + final MatchResult matchResult = SystemUtils.matchSystemFile("/proc/meminfo", MEMFREE_PATTERN, 1000); + + try { + if(matchResult.groupCount() > 0) { + return Integer.parseInt(matchResult.group(1)); + } else { + throw new SystemUtilsException(); + } + } catch (final NumberFormatException e) { + throw new SystemUtilsException(e); + } + } + + /** + * @return in kiloHertz. + * @throws SystemUtilsException + */ + public static int getCPUFrequencyCurrent() throws SystemUtilsException { + return SystemUtils.readSystemFileAsInt("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"); + } + + /** + * @return in kiloHertz. + * @throws SystemUtilsException + */ + public static int getCPUFrequencyMin() throws SystemUtilsException { + return SystemUtils.readSystemFileAsInt("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq"); + } + + /** + * @return in kiloHertz. + * @throws SystemUtilsException + */ + public static int getCPUFrequencyMax() throws SystemUtilsException { + return SystemUtils.readSystemFileAsInt("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"); + } + + /** + * @return in kiloHertz. + * @throws SystemUtilsException + */ + public static int getCPUFrequencyMinScaling() throws SystemUtilsException { + return SystemUtils.readSystemFileAsInt("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq"); + } + + /** + * @return in kiloHertz. + * @throws SystemUtilsException + */ + public static int getCPUFrequencyMaxScaling() throws SystemUtilsException { + return SystemUtils.readSystemFileAsInt("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"); + } + + private static MatchResult matchSystemFile(final String pSystemFile, final String pPattern, final int pHorizon) throws SystemUtilsException { + InputStream in = null; + try { + final Process process = new ProcessBuilder(new String[] { "/system/bin/cat", pSystemFile }).start(); + + in = process.getInputStream(); + final Scanner scanner = new Scanner(in); + + final boolean matchFound = scanner.findWithinHorizon(pPattern, pHorizon) != null; + if(matchFound) { + return scanner.match(); + } else { + throw new SystemUtilsException(); + } + } catch (final IOException e) { + throw new SystemUtilsException(e); + } finally { + StreamUtils.close(in); + } + } + + private static int readSystemFileAsInt(final String pSystemFile) throws SystemUtilsException { + InputStream in = null; + try { + final Process process = new ProcessBuilder(new String[] { "/system/bin/cat", pSystemFile }).start(); + + in = process.getInputStream(); + final String content = StreamUtils.readFully(in); + return Integer.parseInt(content); + } catch (final IOException e) { + throw new SystemUtilsException(e); + } catch (final NumberFormatException e) { + throw new SystemUtilsException(e); + } finally { + StreamUtils.close(in); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static class SystemUtilsException extends Exception { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = -7256483361095147596L; + + // =========================================================== + // Methods + // =========================================================== + + public SystemUtilsException() { + + } + + public SystemUtilsException(final Throwable pThrowable) { + super(pThrowable); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/TimeUtils.java b/AndEngine/src/org/anddev/andengine/util/TimeUtils.java new file mode 100644 index 0000000..fd8edc3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/TimeUtils.java @@ -0,0 +1,56 @@ +package org.anddev.andengine.util; + +import org.anddev.andengine.util.constants.TimeConstants; + +/** + * @author Nicolas Gramlich + * @since 22:48:49 - 04.04.2011 + */ +public class TimeUtils implements TimeConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static String formatSeconds(final int pSecondsTotal) { + return formatSeconds(pSecondsTotal, new StringBuilder()); + } + + public static String formatSeconds(final int pSecondsTotal, final StringBuilder pStringBuilder) { + final int minutes = pSecondsTotal / SECONDSPERMINUTE; + final int seconds = pSecondsTotal % SECONDSPERMINUTE; + + pStringBuilder.append(minutes); + pStringBuilder.append(':'); + + if(seconds < 10) { + pStringBuilder.append('0'); + } + pStringBuilder.append(seconds); + + return pStringBuilder.toString(); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/Transformation.java b/AndEngine/src/org/anddev/andengine/util/Transformation.java new file mode 100644 index 0000000..58acc4b --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/Transformation.java @@ -0,0 +1,229 @@ +package org.anddev.andengine.util; + +import android.util.FloatMath; + + +/** + *

This class is basically a java-space replacement for the native {@link android.graphics.Matrix} class.

+ * + *

Math taken from senocular.com.

+ * + * This class represents an affine transformation with the following matrix: + *
 [ a , b , 0 ]
+ * [ c , d , 0 ]
+ * [ tx, ty, 1 ]
+ * where: + *
    + *
  • a is the x scale
  • + *
  • b is the y skew
  • + *
  • c is the x skew
  • + *
  • d is the y scale
  • + *
  • tx is the x translation
  • + *
  • ty is the y translation
  • + *
+ * + *

TODO Think if that caching of Transformation through the TransformationPool really needs to be thread-safe or if one simple reused static Transform object is enough.

+ * + * @author Nicolas Gramlich + * @since 15:47:18 - 23.12.2010 + */ +public class Transformation { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float a; /* x scale */ + private float b; /* y skew */ + private float c; /* x skew */ + private float d; /* y scale */ + private float tx; /* x translation */ + private float ty; /* y translation */ + + // =========================================================== + // Constructors + // =========================================================== + + public Transformation() { + this.a = 1.0f; + this.d = 1.0f; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public String toString() { + return "Transformation{[" + this.a + ", " + this.c + ", " + this.tx + "][" + this.b + ", " + this.d + ", " + this.ty + "][0.0, 0.0, 1.0]}"; + } + + // =========================================================== + // Methods + // =========================================================== + + public void reset() { + this.setToIdentity(); + } + + public void setToIdentity() { + this.a = 1.0f; + this.d = 1.0f; + + this.b = 0.0f; + this.c = 0.0f; + this.tx = 0.0f; + this.ty = 0.0f; + } + + public void preTranslate(final float pX, final float pY) { + final Transformation transformation = TransformationPool.obtain(); + this.preConcat(transformation.setToTranslate(pX, pY)); + TransformationPool.recycle(transformation); + } + + public void postTranslate(final float pX, final float pY) { + final Transformation transformation = TransformationPool.obtain(); + this.postConcat(transformation.setToTranslate(pX, pY)); + TransformationPool.recycle(transformation); + } + + public Transformation setToTranslate(final float pX, final float pY) { + this.a = 1; + this.b = 0; + this.c = 0; + this.d = 1; + this.tx = pX; + this.ty = pY; + + return this; + } + + public void preScale(final float pScaleX, final float pScaleY) { + final Transformation transformation = TransformationPool.obtain(); + this.preConcat(transformation.setToScale(pScaleX, pScaleY)); + TransformationPool.recycle(transformation); + } + + public void postScale(final float pScaleX, final float pScaleY) { + final Transformation transformation = TransformationPool.obtain(); + this.postConcat(transformation.setToScale(pScaleX, pScaleY)); + TransformationPool.recycle(transformation); + } + + public Transformation setToScale(final float pScaleX, final float pScaleY) { + this.a = pScaleX; + this.b = 0; + this.c = 0; + this.d = pScaleY; + this.tx = 0; + this.ty = 0; + + return this; + } + + public void preRotate(final float pAngle) { + final Transformation transformation = TransformationPool.obtain(); + this.preConcat(transformation.setToRotate(pAngle)); + TransformationPool.recycle(transformation); + } + + public void postRotate(final float pAngle) { + final Transformation transformation = TransformationPool.obtain(); + this.postConcat(transformation.setToRotate(pAngle)); + TransformationPool.recycle(transformation); + } + + public Transformation setToRotate(final float pAngle) { + final float angleRad = MathUtils.degToRad(pAngle); + + final float sin = FloatMath.sin(angleRad); + final float cos = FloatMath.cos(angleRad); + + this.a = cos; + this.b = sin; + this.c = -sin; + this.d = cos; + this.tx = 0; + this.ty = 0; + + return this; + } + + public void postConcat(final Transformation pTransformation) { + final float a1 = this.a; + final float a2 = pTransformation.a; + + final float b1 = this.b; + final float b2 = pTransformation.b; + + final float c1 = this.c; + final float c2 = pTransformation.c; + + final float d1 = this.d; + final float d2 = pTransformation.d; + + final float tx1 = this.tx; + final float tx2 = pTransformation.tx; + + final float ty1 = this.ty; + final float ty2 = pTransformation.ty; + + this.a = a1 * a2 + b1 * c2; + this.b = a1 * b2 + b1 * d2; + this.c = c1 * a2 + d1 * c2; + this.d = c1 * b2 + d1 * d2; + this.tx = tx1 * a2 + ty1 * c2 + tx2; + this.ty = tx1 * b2 + ty1 * d2 + ty2; + } + + public void preConcat(final Transformation pTransformation) { + final float a1 = pTransformation.a; + final float a2 = this.a; + + final float b1 = pTransformation.b; + final float b2 = this.b; + + final float c1 = pTransformation.c; + final float c2 = this.c; + + final float d1 = pTransformation.d; + final float d2 = this.d; + + final float tx1 = pTransformation.tx; + final float tx2 = this.tx; + + final float ty1 = pTransformation.ty; + final float ty2 = this.ty; + + this.a = a1 * a2 + b1 * c2; + this.b = a1 * b2 + b1 * d2; + this.c = c1 * a2 + d1 * c2; + this.d = c1 * b2 + d1 * d2; + this.tx = tx1 * a2 + ty1 * c2 + tx2; + this.ty = tx1 * b2 + ty1 * d2 + ty2; + } + + public void transform(final float[] pVertices) { + int count = pVertices.length / 2; + int i = 0; + int j = 0; + while(--count >= 0) { + final float x = pVertices[i++]; + final float y = pVertices[i++]; + pVertices[j++] = x * this.a + y * this.c + this.tx; + pVertices[j++] = x * this.b + y * this.d + this.ty; + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/TransformationPool.java b/AndEngine/src/org/anddev/andengine/util/TransformationPool.java new file mode 100644 index 0000000..f8390b5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/TransformationPool.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.util; + +import org.anddev.andengine.util.pool.GenericPool; + +/** + * @author Nicolas Gramlich + * @since 23:07:53 - 23.02.2011 + */ +public class TransformationPool { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static final GenericPool POOL = new GenericPool() { + @Override + protected Transformation onAllocatePoolItem() { + return new Transformation(); + } + }; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public static Transformation obtain() { + return POOL.obtainPoolItem(); + } + + public static void recycle(final Transformation pTransformation) { + pTransformation.setToIdentity(); + POOL.recyclePoolItem(pTransformation); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/VerticalAlign.java b/AndEngine/src/org/anddev/andengine/util/VerticalAlign.java new file mode 100644 index 0000000..936c1e6 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/VerticalAlign.java @@ -0,0 +1,43 @@ +package org.anddev.andengine.util; + +/** + * @author Nicolas Gramlich + * @since 15:15:23 - 24.07.2010 + */ +public enum VerticalAlign { + // =========================================================== + // Elements + // =========================================================== + + TOP, + CENTER, + BOTTOM; + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/ViewUtils.java b/AndEngine/src/org/anddev/andengine/util/ViewUtils.java new file mode 100644 index 0000000..2004439 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/ViewUtils.java @@ -0,0 +1,48 @@ +package org.anddev.andengine.util; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * @author Nicolas Gramlich + * @since 20:55:35 - 08.09.2009 + */ +public class ViewUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static View inflate(final Context pContext, final int pLayoutID){ + return LayoutInflater.from(pContext).inflate(pLayoutID, null); + } + + public static View inflate(final Context pContext, final int pLayoutID, final ViewGroup pViewGroup){ + return LayoutInflater.from(pContext).inflate(pLayoutID, pViewGroup, true); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/cache/RectangleVertexBufferCache.java b/AndEngine/src/org/anddev/andengine/util/cache/RectangleVertexBufferCache.java new file mode 100644 index 0000000..cb3fdb4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/cache/RectangleVertexBufferCache.java @@ -0,0 +1,70 @@ +package org.anddev.andengine.util.cache; + +import javax.microedition.khronos.opengles.GL11; + +import org.anddev.andengine.opengl.buffer.BufferObjectManager; +import org.anddev.andengine.opengl.vertex.RectangleVertexBuffer; +import org.anddev.andengine.util.MultiKey; +import org.anddev.andengine.util.MultiKeyHashMap; + +/** + * @author Nicolas Gramlich + * @since 21:10:05 - 09.01.2011 + */ +public class RectangleVertexBufferCache { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mDrawType; + + private final MultiKeyHashMap mRectangleVertexBufferCache = new MultiKeyHashMap(); + + // =========================================================== + // Constructors + // =========================================================== + + public RectangleVertexBufferCache() { + this(GL11.GL_STATIC_DRAW); + } + + public RectangleVertexBufferCache(final int pDrawType) { + this.mDrawType = pDrawType; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public RectangleVertexBuffer get(final int pWidth, final int pHeight) { + final RectangleVertexBuffer cachedRectangleVertexBuffer = this.mRectangleVertexBufferCache.get(pWidth, pHeight); + if(cachedRectangleVertexBuffer != null) { + return cachedRectangleVertexBuffer; + } else { + return this.put(pWidth, pHeight, new RectangleVertexBuffer(this.mDrawType)); + } + } + + public RectangleVertexBuffer put(final int pWidth, final int pHeight, final RectangleVertexBuffer pRectangleVertexBuffer) { + pRectangleVertexBuffer.update(pWidth, pHeight); + BufferObjectManager.getActiveInstance().loadBufferObject(pRectangleVertexBuffer); + this.mRectangleVertexBufferCache.put(new MultiKey(pWidth, pHeight), pRectangleVertexBuffer); + return pRectangleVertexBuffer; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/constants/ColorConstants.java b/AndEngine/src/org/anddev/andengine/util/constants/ColorConstants.java new file mode 100644 index 0000000..7976359 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/constants/ColorConstants.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.util.constants; + +/** + * @author Nicolas Gramlich + * @since 10:21:46 - 19.07.2010 + */ +public interface ColorConstants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final float COLOR_FACTOR_INT_TO_FLOAT = 255.0f; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/constants/Constants.java b/AndEngine/src/org/anddev/andengine/util/constants/Constants.java new file mode 100644 index 0000000..c783d5c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/constants/Constants.java @@ -0,0 +1,20 @@ +package org.anddev.andengine.util.constants; + +/** + * @author Nicolas Gramlich + * @since 13:52:21 - 08.03.2010 + */ +public interface Constants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final String DEBUGTAG = "AndEngine"; + + public static final int VERTEX_INDEX_X = 0; + public static final int VERTEX_INDEX_Y = 1; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/constants/MIMETypes.java b/AndEngine/src/org/anddev/andengine/util/constants/MIMETypes.java new file mode 100644 index 0000000..9659806 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/constants/MIMETypes.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.util.constants; + +/** + * @author Nicolas Gramlich + * @since 14:58:20 - 10.01.2011 + */ +public interface MIMETypes { + // =========================================================== + // Final Fields + // =========================================================== + + public static final String JPEG = "image/jpeg"; + public static final String GIF = "image/gif"; + public static final String PNG = "image/png"; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/constants/MathConstants.java b/AndEngine/src/org/anddev/andengine/util/constants/MathConstants.java new file mode 100644 index 0000000..6c478a4 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/constants/MathConstants.java @@ -0,0 +1,23 @@ +package org.anddev.andengine.util.constants; + +/** + * @author Nicolas Gramlich + * @since 16:49:25 - 26.07.2010 + */ +public interface MathConstants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final float PI = (float) Math.PI; + + public static float PI_TWICE = PI * 2.0f; + public static float PI_HALF = PI * 0.5f; + + public static final float DEG_TO_RAD = PI / 180.0f; + public static final float RAD_TO_DEG = 180.0f / PI; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/constants/TimeConstants.java b/AndEngine/src/org/anddev/andengine/util/constants/TimeConstants.java new file mode 100644 index 0000000..f56dd8f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/constants/TimeConstants.java @@ -0,0 +1,37 @@ +package org.anddev.andengine.util.constants; + +/** + * @author Nicolas Gramlich + * @since 16:49:25 - 26.07.2010 + */ +public interface TimeConstants { + // =========================================================== + // Final Fields + // =========================================================== + + public static final int MONTHSPERYEAR = 12; + + public static final int DAYSPERWEEK = 7; + + public static final int DAYSPERMONTH = 30; + + public static final int HOURSPERDAY = 24; + + public static final int MINUTESPERHOUR = 60; + + public static final int SECONDSPERMINUTE = 60; + public static final int SECONDSPERHOUR = SECONDSPERMINUTE * MINUTESPERHOUR; + public static final int SECONDSPERDAY = SECONDSPERHOUR * HOURSPERDAY; + public static final int SECONDSPERWEEK = SECONDSPERDAY * DAYSPERWEEK; + public static final int SECONDSPERMONTH = SECONDSPERDAY * DAYSPERMONTH; + public static final int SECONDSPERYEAR = SECONDSPERMONTH * MONTHSPERYEAR; + + public static final int MILLISECONDSPERSECOND = 1000; + + public static final long NANOSECONDSPERSECOND = 1000000000; + public static final long NANOSECONDSPERMILLISECOND = NANOSECONDSPERSECOND / MILLISECONDSPERSECOND; + + // =========================================================== + // Methods + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/levelstats/LevelStatsDBConnector.java b/AndEngine/src/org/anddev/andengine/util/levelstats/LevelStatsDBConnector.java new file mode 100644 index 0000000..19ecc53 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/levelstats/LevelStatsDBConnector.java @@ -0,0 +1,131 @@ +package org.anddev.andengine.util.levelstats; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.anddev.andengine.util.Callback; +import org.anddev.andengine.util.Debug; +import org.anddev.andengine.util.MathUtils; +import org.anddev.andengine.util.SimplePreferences; +import org.anddev.andengine.util.StreamUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; + +import android.content.Context; +import android.content.SharedPreferences; + +/** + * @author Nicolas Gramlich + * @since 21:13:55 - 18.10.2010 + */ +public class LevelStatsDBConnector { + // =========================================================== + // Constants + // =========================================================== + + private static final String PREFERENCES_LEVELSTATSDBCONNECTOR_PLAYERID_ID = "preferences.levelstatsdbconnector.playerid"; + + // =========================================================== + // Fields + // =========================================================== + + private final String mSecret; + private final String mSubmitURL; + private final int mPlayerID; + + // =========================================================== + // Constructors + // =========================================================== + + public LevelStatsDBConnector(final Context pContext, final String pSecret, final String pSubmitURL) { + this.mSecret = pSecret; + this.mSubmitURL = pSubmitURL; + + final SharedPreferences simplePreferences = SimplePreferences.getInstance(pContext); + final int playerID = simplePreferences.getInt(PREFERENCES_LEVELSTATSDBCONNECTOR_PLAYERID_ID, -1); + if(playerID != -1) { + this.mPlayerID = playerID; + } else { + this.mPlayerID = MathUtils.random(1000000000, Integer.MAX_VALUE); + SimplePreferences.getEditorInstance(pContext).putInt(PREFERENCES_LEVELSTATSDBCONNECTOR_PLAYERID_ID, this.mPlayerID).commit(); + } + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public void submitAsync(final int pLevelID, final boolean pSolved, final int pSecondsElapsed) { + this.submitAsync(pLevelID, pSolved, pSecondsElapsed, null); + } + + public void submitAsync(final int pLevelID, final boolean pSolved, final int pSecondsElapsed, final Callback pCallback) { + new Thread(new Runnable() { + @Override + public void run() { + try{ + /* Create a new HttpClient and Post Header. */ + final HttpClient httpClient = new DefaultHttpClient(); + final HttpPost httpPost = new HttpPost(LevelStatsDBConnector.this.mSubmitURL); + + /* Append POST data. */ + final List nameValuePairs = new ArrayList(4); + + nameValuePairs.add(new BasicNameValuePair("level_id", String.valueOf(pLevelID))); + nameValuePairs.add(new BasicNameValuePair("solved", (pSolved) ? "1" : "0")); + nameValuePairs.add(new BasicNameValuePair("secondsplayed", String.valueOf(pSecondsElapsed))); + nameValuePairs.add(new BasicNameValuePair("player_id", String.valueOf(LevelStatsDBConnector.this.mPlayerID))); + nameValuePairs.add(new BasicNameValuePair("secret", String.valueOf(LevelStatsDBConnector.this.mSecret))); + + httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); + + /* Execute HTTP Post Request. */ + final HttpResponse httpResponse = httpClient.execute(httpPost); + + final int statusCode = httpResponse.getStatusLine().getStatusCode(); + if(statusCode == HttpStatus.SC_OK) { + final String response = StreamUtils.readFully(httpResponse.getEntity().getContent()); + + if(response.equals("")) { + if(pCallback != null) { + pCallback.onCallback(true); + } + } else { + if(pCallback != null) { + pCallback.onCallback(false); + } + } + } else { + if(pCallback != null) { + pCallback.onCallback(false); + } + } + }catch(final IOException e) { + Debug.e(e); + if(pCallback != null) { + pCallback.onCallback(false); + } + } + } + }).start(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/BaseDoubleValueSpanModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/BaseDoubleValueSpanModifier.java new file mode 100644 index 0000000..d59a9c3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/BaseDoubleValueSpanModifier.java @@ -0,0 +1,78 @@ +package org.anddev.andengine.util.modifier; + +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 10:51:46 - 03.09.2010 + * @param + */ +public abstract class BaseDoubleValueSpanModifier extends BaseSingleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mFromValueB; + private final float mValueSpanB; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseDoubleValueSpanModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB) { + this(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, null, IEaseFunction.DEFAULT); + } + + public BaseDoubleValueSpanModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final IEaseFunction pEaseFunction) { + this(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, null, pEaseFunction); + } + + public BaseDoubleValueSpanModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final IModifierListener pModifierListener) { + this(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pModifierListener, IEaseFunction.DEFAULT); + } + + public BaseDoubleValueSpanModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final IModifierListener pModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValueA, pToValueA, pModifierListener, pEaseFunction); + this.mFromValueB = pFromValueB; + this.mValueSpanB = pToValueB - pFromValueB; + } + + protected BaseDoubleValueSpanModifier(final BaseDoubleValueSpanModifier pBaseDoubleValueSpanModifier) { + super(pBaseDoubleValueSpanModifier); + this.mFromValueB = pBaseDoubleValueSpanModifier.mFromValueB; + this.mValueSpanB = pBaseDoubleValueSpanModifier.mValueSpanB; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onSetInitialValues(final T pItem, final float pValueA, final float pValueB); + protected abstract void onSetValues(final T pItem, final float pPercentageDone, final float pValueA, final float pValueB); + + @Override + protected void onSetInitialValue(final T pItem, final float pValueA) { + this.onSetInitialValues(pItem, pValueA, this.mFromValueB); + } + + @Override + protected void onSetValue(final T pItem, final float pPercentageDone, final float pValueA) { + this.onSetValues(pItem, pPercentageDone, pValueA, this.mFromValueB + pPercentageDone * this.mValueSpanB); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/BaseDurationModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/BaseDurationModifier.java new file mode 100644 index 0000000..d8e4df3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/BaseDurationModifier.java @@ -0,0 +1,103 @@ +package org.anddev.andengine.util.modifier; + + +/** + * @author Nicolas Gramlich + * @since 10:48:13 - 03.09.2010 + * @param + */ +public abstract class BaseDurationModifier extends BaseModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private float mTotalSecondsElapsed; + protected final float mDuration; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseDurationModifier() { + this(-1, null); + } + + public BaseDurationModifier(final float pDuration) { + this(pDuration, null); + } + + public BaseDurationModifier(final float pDuration, final IModifierListener pModifierListener) { + super(pModifierListener); + this.mDuration = pDuration; + } + + protected BaseDurationModifier(final BaseDurationModifier pBaseModifier) { + this(pBaseModifier.mDuration, pBaseModifier.mModifierListener); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + protected float getTotalSecondsElapsed() { + return this.mTotalSecondsElapsed; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getDuration() { + return this.mDuration; + } + + protected abstract void onManagedUpdate(final float pSecondsElapsed, final T pItem); + + protected abstract void onManagedInitialize(final T pItem); + + @Override + public final void onUpdate(final float pSecondsElapsed, final T pItem) { + if(!this.mFinished){ + if(this.mTotalSecondsElapsed == 0) { + this.onManagedInitialize(pItem); + } + + final float secondsToElapse; + if(this.mTotalSecondsElapsed + pSecondsElapsed < this.mDuration) { + secondsToElapse = pSecondsElapsed; + } else { + secondsToElapse = this.mDuration - this.mTotalSecondsElapsed; + } + + this.mTotalSecondsElapsed += secondsToElapse; + this.onManagedUpdate(secondsToElapse, pItem); + + if(this.mDuration != -1 && this.mTotalSecondsElapsed >= this.mDuration) { + this.mTotalSecondsElapsed = this.mDuration; + this.mFinished = true; + if(this.mModifierListener != null) { + this.mModifierListener.onModifierFinished(this, pItem); + } + } + } + } + + @Override + public void reset() { + this.mFinished = false; + this.mTotalSecondsElapsed = 0; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/BaseModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/BaseModifier.java new file mode 100644 index 0000000..9c909a3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/BaseModifier.java @@ -0,0 +1,81 @@ +package org.anddev.andengine.util.modifier; + + +/** + * @author Nicolas Gramlich + * @since 10:47:23 - 03.09.2010 + * @param + */ +public abstract class BaseModifier implements IModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected boolean mFinished; + private boolean mRemoveWhenFinished = true; + protected IModifierListener mModifierListener; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseModifier() { + this((IModifierListener)null); + } + + public BaseModifier(final IModifierListener pModifierListener) { + this.mModifierListener = pModifierListener; + } + + protected BaseModifier(final BaseModifier pBaseModifier) { + this(pBaseModifier.mModifierListener); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public boolean isFinished() { + return this.mFinished; + } + + @Override + public final boolean isRemoveWhenFinished() { + return this.mRemoveWhenFinished; + } + + @Override + public final void setRemoveWhenFinished(final boolean pRemoveWhenFinished) { + this.mRemoveWhenFinished = pRemoveWhenFinished; + } + + @Override + public IModifierListener getModifierListener() { + return this.mModifierListener; + } + + @Override + public void setModifierListener(final IModifierListener pModifierListener) { + this.mModifierListener = pModifierListener; + } + + @Override + public abstract IModifier clone(); + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/BaseSingleValueChangeModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/BaseSingleValueChangeModifier.java new file mode 100644 index 0000000..a5f41cc --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/BaseSingleValueChangeModifier.java @@ -0,0 +1,65 @@ +package org.anddev.andengine.util.modifier; + + +/** + * @author Nicolas Gramlich + * @since 10:49:51 - 03.09.2010 + * @param + */ +public abstract class BaseSingleValueChangeModifier extends BaseDurationModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mValueChangePerSecond; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseSingleValueChangeModifier(final float pDuration, final float pValueChange) { + this(pDuration, pValueChange, null); + } + + public BaseSingleValueChangeModifier(final float pDuration, final float pValueChange, final IModifierListener pModifierListener) { + super(pDuration, pModifierListener); + this.mValueChangePerSecond = pValueChange / pDuration; + } + + protected BaseSingleValueChangeModifier(final BaseSingleValueChangeModifier pBaseSingleValueChangeModifier) { + super(pBaseSingleValueChangeModifier); + this.mValueChangePerSecond = pBaseSingleValueChangeModifier.mValueChangePerSecond; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onChangeValue(final T pItem, final float pValue); + + @Override + protected void onManagedInitialize(final T pItem) { + + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed, final T pItem) { + this.onChangeValue(pItem, this.mValueChangePerSecond * pSecondsElapsed); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/BaseSingleValueSpanModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/BaseSingleValueSpanModifier.java new file mode 100644 index 0000000..952214e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/BaseSingleValueSpanModifier.java @@ -0,0 +1,83 @@ +package org.anddev.andengine.util.modifier; + +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 23:29:22 - 19.03.2010 + */ +public abstract class BaseSingleValueSpanModifier extends BaseDurationModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mFromValue; + private final float mValueSpan; + + protected final IEaseFunction mEaseFunction; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseSingleValueSpanModifier(final float pDuration, final float pFromValue, final float pToValue) { + this(pDuration, pFromValue, pToValue, null, IEaseFunction.DEFAULT); + } + + public BaseSingleValueSpanModifier(final float pDuration, final float pFromValue, final float pToValue, final IEaseFunction pEaseFunction) { + this(pDuration, pFromValue, pToValue, null, pEaseFunction); + } + + public BaseSingleValueSpanModifier(final float pDuration, final float pFromValue, final float pToValue, final IModifierListener pModifierListener) { + this(pDuration, pFromValue, pToValue, IEaseFunction.DEFAULT); + } + + public BaseSingleValueSpanModifier(final float pDuration, final float pFromValue, final float pToValue, final IModifierListener pModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pModifierListener); + this.mFromValue = pFromValue; + this.mValueSpan = pToValue - pFromValue; + this.mEaseFunction = pEaseFunction; + } + + protected BaseSingleValueSpanModifier(final BaseSingleValueSpanModifier pBaseSingleValueSpanModifier) { + super(pBaseSingleValueSpanModifier); + this.mFromValue = pBaseSingleValueSpanModifier.mFromValue; + this.mValueSpan = pBaseSingleValueSpanModifier.mValueSpan; + this.mEaseFunction = pBaseSingleValueSpanModifier.mEaseFunction; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onSetInitialValue(final T pItem, final float pValue); + protected abstract void onSetValue(final T pItem, final float pPercentageDone, final float pValue); + + @Override + protected void onManagedInitialize(final T pItem) { + this.onSetInitialValue(pItem, this.mFromValue); + } + + @Override + protected void onManagedUpdate(final float pSecondsElapsed, final T pItem) { + final float percentageDone = this.mEaseFunction.getPercentageDone(this.getTotalSecondsElapsed(), this.mDuration, 0, 1); + + this.onSetValue(pItem, percentageDone, this.mFromValue + percentageDone * this.mValueSpan); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/BaseTripleValueSpanModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/BaseTripleValueSpanModifier.java new file mode 100644 index 0000000..006fd4d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/BaseTripleValueSpanModifier.java @@ -0,0 +1,70 @@ +package org.anddev.andengine.util.modifier; + +import org.anddev.andengine.util.modifier.ease.IEaseFunction; + +/** + * @author Nicolas Gramlich + * @since 10:52:31 - 03.09.2010 + * @param + */ +public abstract class BaseTripleValueSpanModifier extends BaseDoubleValueSpanModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final float mFromValueC; + private final float mValueSpanC; + + // =========================================================== + // Constructors + // =========================================================== + + public BaseTripleValueSpanModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final float pFromValueC, final float pToValueC, final IEaseFunction pEaseFunction) { + this(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pFromValueC, pToValueC, null, pEaseFunction); + } + + public BaseTripleValueSpanModifier(final float pDuration, final float pFromValueA, final float pToValueA, final float pFromValueB, final float pToValueB, final float pFromValueC, final float pToValueC, final IModifierListener pModifierListener, final IEaseFunction pEaseFunction) { + super(pDuration, pFromValueA, pToValueA, pFromValueB, pToValueB, pModifierListener, pEaseFunction); + this.mFromValueC = pFromValueC; + this.mValueSpanC = pToValueC - pFromValueC; + } + + protected BaseTripleValueSpanModifier(final BaseTripleValueSpanModifier pBaseTripleValueSpanModifier) { + super(pBaseTripleValueSpanModifier); + this.mFromValueC = pBaseTripleValueSpanModifier.mFromValueC; + this.mValueSpanC = pBaseTripleValueSpanModifier.mValueSpanC; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract void onSetInitialValues(final T pItem, final float pValueA, final float pValueB, final float pValueC); + protected abstract void onSetValues(final T pItem, final float pPerctentageDone, final float pValueA, final float pValueB, final float pValueC); + + @Override + protected void onSetInitialValues(final T pItem, final float pValueA, final float pValueB) { + this.onSetInitialValues(pItem, pValueA, pValueB, this.mFromValueC); + } + + @Override + protected void onSetValues(final T pItem, final float pPercentageDone, final float pValueA, final float pValueB) { + this.onSetValues(pItem, pPercentageDone, pValueA, pValueB, this.mFromValueC + pPercentageDone * this.mValueSpanC); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/IModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/IModifier.java new file mode 100644 index 0000000..1c827d3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/IModifier.java @@ -0,0 +1,47 @@ +package org.anddev.andengine.util.modifier; + + +/** + * @author Nicolas Gramlich + * @since 11:17:50 - 19.03.2010 + */ +public interface IModifier extends Cloneable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void reset(); + + public boolean isFinished(); + public boolean isRemoveWhenFinished(); + public void setRemoveWhenFinished(final boolean pRemoveWhenFinished); + + public IModifier clone(); + + public float getDuration(); + + public void onUpdate(final float pSecondsElapsed, final T pItem); + + public IModifierListener getModifierListener(); + public void setModifierListener(final IModifierListener pModifierListener); + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public static interface IModifierListener { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void onModifierFinished(final IModifier pModifier, final T pItem); + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/LoopModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/LoopModifier.java new file mode 100644 index 0000000..f545904 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/LoopModifier.java @@ -0,0 +1,138 @@ +package org.anddev.andengine.util.modifier; + + +/** + * @author Nicolas Gramlich + * @since 11:18:37 - 03.09.2010 + * @param + */ +public class LoopModifier extends BaseModifier { + // =========================================================== + // Constants + // =========================================================== + + public static final int LOOP_CONTINUOUS = -1; + + // =========================================================== + // Fields + // =========================================================== + + private final float mDuration; + + private final IModifier mModifier; + + private ILoopModifierListener mLoopModifierListener; + + private final int mInitialLoopCount; + private int mLoopCount; + + // =========================================================== + // Constructors + // =========================================================== + + public LoopModifier(final IModifier pModifier) { + this(null, LOOP_CONTINUOUS, pModifier); + } + + public LoopModifier(final int pLoopCount, final IModifier pModifier) { + this(null, pLoopCount, pModifier); + } + + public LoopModifier(final IModifierListener pModifierListener, final int pLoopCount, final IModifier pModifier) { + this(pModifierListener, pLoopCount, null, pModifier); + } + + public LoopModifier(final IModifierListener pModifierListener, final int pLoopCount, final ILoopModifierListener pLoopModifierListener, final IModifier pModifier) { + super(pModifierListener); + this.mLoopModifierListener = pLoopModifierListener; + this.mModifier = pModifier; + this.mInitialLoopCount = pLoopCount; + this.mLoopCount = pLoopCount; + this.mDuration = pLoopCount == LOOP_CONTINUOUS ? Float.POSITIVE_INFINITY : pModifier.getDuration() * pLoopCount; // TODO Check if POSITIVE_INFINITY works correct with i.e. SequenceModifier + + pModifier.setModifierListener(new InternalModifierListener()); + } + + protected LoopModifier(final LoopModifier pLoopModifier) { + this(pLoopModifier.mModifierListener, pLoopModifier.mInitialLoopCount, pLoopModifier.mModifier.clone()); + } + + @Override + public LoopModifier clone(){ + return new LoopModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public ILoopModifierListener getLoopModifierListener() { + return this.mLoopModifierListener; + } + + public void setLoopModifierListener(final ILoopModifierListener pLoopModifierListener) { + this.mLoopModifierListener = pLoopModifierListener; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getDuration() { + return this.mDuration; + } + + @Override + public void onUpdate(final float pSecondsElapsed, final T pItem) { + if(!this.mFinished) { + this.mModifier.onUpdate(pSecondsElapsed, pItem); + } + } + + @Override + public void reset() { + this.mLoopCount = this.mInitialLoopCount; + + this.mModifier.reset(); + } + + // =========================================================== + // Methods + // =========================================================== + + public void onHandleLoopFinished(final T pItem) { + if(this.mLoopModifierListener != null) { + this.mLoopModifierListener.onLoopFinished(this, this.mLoopCount); + } + + if(this.mInitialLoopCount == LOOP_CONTINUOUS) { + this.mModifier.reset(); + } else { + this.mLoopCount--; + if(this.mLoopCount < 0) { + this.mFinished = true; + if(this.mModifierListener != null) { + this.mModifierListener.onModifierFinished(this, pItem); + } + } else { + this.mModifier.reset(); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ILoopModifierListener { + public void onLoopFinished(final LoopModifier pLoopModifier, final int pLoopsRemaining); + } + + private class InternalModifierListener implements IModifierListener { + @Override + public void onModifierFinished(final IModifier pModifier, final T pItem) { + LoopModifier.this.onHandleLoopFinished(pItem); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ModifierList.java b/AndEngine/src/org/anddev/andengine/util/modifier/ModifierList.java new file mode 100644 index 0000000..36d75ed --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ModifierList.java @@ -0,0 +1,80 @@ +package org.anddev.andengine.util.modifier; + +import java.util.ArrayList; + +import org.anddev.andengine.engine.handler.IUpdateHandler; +import org.anddev.andengine.util.SmartList; + +/** + * @author Nicolas Gramlich + * @since 14:34:57 - 03.09.2010 + */ +public class ModifierList extends SmartList> implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + private static final long serialVersionUID = 1610345592534873475L; + + // =========================================================== + // Fields + // =========================================================== + + private final T mTarget; + + // =========================================================== + // Constructors + // =========================================================== + + public ModifierList(final T pTarget) { + this.mTarget = pTarget; + } + + public ModifierList(final T pTarget, final int pCapacity){ + super(pCapacity); + this.mTarget = pTarget; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public T getTarget() { + return this.mTarget; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void onUpdate(final float pSecondsElapsed) { + final ArrayList> modifiers = this; + final int modifierCount = this.size(); + if(modifierCount > 0) { + for(int i = modifierCount - 1; i >= 0; i--) { + final IModifier modifier = modifiers.get(i); + modifier.onUpdate(pSecondsElapsed, this.mTarget); + if(modifier.isFinished() && modifier.isRemoveWhenFinished()) { + modifiers.remove(i); + } + } + } + } + + @Override + public void reset() { + final ArrayList> modifiers = this; + for(int i = modifiers.size() - 1; i >= 0; i--) { + modifiers.get(i).reset(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ParallelModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/ParallelModifier.java new file mode 100644 index 0000000..54b5d15 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ParallelModifier.java @@ -0,0 +1,125 @@ +package org.anddev.andengine.util.modifier; + +import org.anddev.andengine.util.modifier.util.ModifierUtils; + +/** + * @author Nicolas Gramlich + * @since 11:21:22 - 03.09.2010 + * @param + */ +public class ParallelModifier extends BaseModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final IModifier[] mModifiers; + + private final float mDuration; + + private boolean mFinishedCached; + + // =========================================================== + // Constructors + // =========================================================== + + public ParallelModifier(final IModifier ... pModifiers) throws IllegalArgumentException { + this(null, pModifiers); + } + + public ParallelModifier(final IModifierListener pModifierListener, final IModifier ... pModifiers) throws IllegalArgumentException { + super(pModifierListener); + if(pModifiers.length == 0) { + throw new IllegalArgumentException("pModifiers must not be empty!"); + } + + this.mModifiers = pModifiers; + + final IModifier shapeModifierWithLongestDuration = ModifierUtils.getModifierWithLongestDuration(pModifiers); + this.mDuration = shapeModifierWithLongestDuration.getDuration(); + shapeModifierWithLongestDuration.setModifierListener(new InternalModifierListener()); + } + + @SuppressWarnings("unchecked") + protected ParallelModifier(final ParallelModifier pParallelModifier) { + super(pParallelModifier.mModifierListener); + + final IModifier[] otherModifiers = pParallelModifier.mModifiers; + this.mModifiers = new IModifier[otherModifiers.length]; + + final IModifier[] shapeModifiers = this.mModifiers; + for(int i = shapeModifiers.length - 1; i >= 0; i--) { + shapeModifiers[i] = otherModifiers[i].clone(); + } + + final IModifier shapeModifierWithLongestDuration = ModifierUtils.getModifierWithLongestDuration(shapeModifiers); + this.mDuration = shapeModifierWithLongestDuration.getDuration(); + shapeModifierWithLongestDuration.setModifierListener(new InternalModifierListener()); + } + + @Override + public ParallelModifier clone(){ + return new ParallelModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getDuration() { + return this.mDuration; + } + + @Override + public void onUpdate(final float pSecondsElapsed, final T pItem) { + this.mFinishedCached = false; + + final IModifier[] shapeModifiers = this.mModifiers; + for(int i = shapeModifiers.length - 1; i >= 0; i--) { + shapeModifiers[i].onUpdate(pSecondsElapsed, pItem); + + if(this.mFinishedCached) { + return; + } + } + + this.mFinishedCached = false; + } + + @Override + public void reset() { + this.mFinished = false; + + final IModifier[] shapeModifiers = this.mModifiers; + for(int i = shapeModifiers.length - 1; i >= 0; i--) { + shapeModifiers[i].reset(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private class InternalModifierListener implements IModifierListener { + @Override + public void onModifierFinished(final IModifier pModifier, final T pItem) { + ParallelModifier.this.mFinished = true; + ParallelModifier.this.mFinishedCached = true; + if(ParallelModifier.this.mModifierListener != null) { + ParallelModifier.this.mModifierListener.onModifierFinished(ParallelModifier.this, pItem); + } + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/SequenceModifier.java b/AndEngine/src/org/anddev/andengine/util/modifier/SequenceModifier.java new file mode 100644 index 0000000..ae3fac0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/SequenceModifier.java @@ -0,0 +1,151 @@ +package org.anddev.andengine.util.modifier; + +import org.anddev.andengine.util.modifier.util.ModifierUtils; + + +/** + * @author Nicolas Gramlich + * @since 19:39:25 - 19.03.2010 + */ +public class SequenceModifier extends BaseModifier { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private ISubSequenceModifierListener mSubSequenceModifierListener; + + private final IModifier[] mSubSequenceModifiers; + private int mCurrentSubSequenceModifier; + + private final float mDuration; + + // =========================================================== + // Constructors + // =========================================================== + + public SequenceModifier(final IModifier ... pModifiers) throws IllegalArgumentException { + this(null, pModifiers); + } + + public SequenceModifier(final IModifierListener pModifierListener, final IModifier ... pModifiers) throws IllegalArgumentException { + this(pModifierListener, null, pModifiers); + } + + public SequenceModifier(final IModifierListener pModifierListener, final ISubSequenceModifierListener pSubSequenceModifierListener, final IModifier ... pModifiers) throws IllegalArgumentException { + super(pModifierListener); + if (pModifiers.length == 0) { + throw new IllegalArgumentException("pModifiers must not be empty!"); + } + + this.mSubSequenceModifierListener = pSubSequenceModifierListener; + this.mSubSequenceModifiers = pModifiers; + + this.mDuration = ModifierUtils.getSequenceDurationOfModifier(pModifiers); + + pModifiers[0].setModifierListener(new InternalModifierListener()); + } + + @SuppressWarnings("unchecked") + protected SequenceModifier(final SequenceModifier pSequenceModifier) { + super(pSequenceModifier.mModifierListener); + this.mSubSequenceModifierListener = pSequenceModifier.mSubSequenceModifierListener; + + this.mDuration = pSequenceModifier.mDuration; + + final IModifier[] otherModifiers = pSequenceModifier.mSubSequenceModifiers; + this.mSubSequenceModifiers = new IModifier[otherModifiers.length]; + + final IModifier[] shapeModifiers = this.mSubSequenceModifiers; + for(int i = shapeModifiers.length - 1; i >= 0; i--) { + shapeModifiers[i] = otherModifiers[i].clone(); + } + + shapeModifiers[0].setModifierListener(new InternalModifierListener()); + } + + @Override + public SequenceModifier clone(){ + return new SequenceModifier(this); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public ISubSequenceModifierListener getSubSequenceModifierListener() { + return this.mSubSequenceModifierListener; + } + + public void setSubSequenceModifierListener(final ISubSequenceModifierListener pSubSequenceModifierListener) { + this.mSubSequenceModifierListener = pSubSequenceModifierListener; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getDuration() { + return this.mDuration; + } + + @Override + public void onUpdate(final float pSecondsElapsed, final T pItem) { + if(!this.mFinished) { + this.mSubSequenceModifiers[this.mCurrentSubSequenceModifier].onUpdate(pSecondsElapsed, pItem); + } + } + + @Override + public void reset() { + this.mCurrentSubSequenceModifier = 0; + this.mFinished = false; + + final IModifier[] shapeModifiers = this.mSubSequenceModifiers; + for(int i = shapeModifiers.length - 1; i >= 0; i--) { + shapeModifiers[i].reset(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + private void onHandleModifierFinished(final InternalModifierListener pInternalModifierListener, final IModifier pModifier, final T pItem) { + this.mCurrentSubSequenceModifier++; + + if(this.mCurrentSubSequenceModifier < this.mSubSequenceModifiers.length) { + final IModifier nextSubSequenceModifier = this.mSubSequenceModifiers[this.mCurrentSubSequenceModifier]; + nextSubSequenceModifier.setModifierListener(pInternalModifierListener); + + if(this.mSubSequenceModifierListener != null) { + this.mSubSequenceModifierListener.onSubSequenceFinished(pModifier, pItem, this.mCurrentSubSequenceModifier); + } + } else { + this.mFinished = true; + + if(this.mModifierListener != null) { + this.mModifierListener.onModifierFinished(this, pItem); + } + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public interface ISubSequenceModifierListener { + public void onSubSequenceFinished(final IModifier pModifier, final T pItem, final int pIndex); + } + + private class InternalModifierListener implements IModifierListener { + @Override + public void onModifierFinished(final IModifier pModifier, final T pItem) { + SequenceModifier.this.onHandleModifierFinished(this, pModifier, pItem); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackIn.java new file mode 100644 index 0000000..2086f8c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackIn.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseBackIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseBackIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseBackIn() { + + } + + public static EaseBackIn getInstance() { + if(null == INSTANCE) { + INSTANCE = new EaseBackIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * (pSecondsElapsed /= pDuration) * pSecondsElapsed * ((1.70158f + 1) * pSecondsElapsed - 1.70158f) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackInOut.java new file mode 100644 index 0000000..838fa4f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackInOut.java @@ -0,0 +1,58 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseBackInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseBackInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseBackInOut() { + + } + + public static EaseBackInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseBackInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + float s = 1.70158f; + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return pMaxValue * 0.5f * (pSecondsElapsed * pSecondsElapsed * (((s *= (1.525f)) + 1) * pSecondsElapsed - s)) + pMinValue; + } + + return pMaxValue / 2 * ((pSecondsElapsed -= 2) * pSecondsElapsed * (((s *= (1.525f)) + 1) * pSecondsElapsed + s) + 2) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackOut.java new file mode 100644 index 0000000..f2254d2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBackOut.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseBackOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseBackOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseBackOut() { + + } + + public static EaseBackOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseBackOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * ((pSecondsElapsed = pSecondsElapsed / pDuration - 1) * pSecondsElapsed * ((1.70158f + 1) * pSecondsElapsed + 1.70158f) + 1) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceIn.java new file mode 100644 index 0000000..1bddb98 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceIn.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseBounceIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseBounceIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseBounceIn() { + + } + + public static EaseBounceIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseBounceIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue - EaseBounceOut.getInstance().getPercentageDone(pDuration - pSecondsElapsed, pDuration, 0, pMaxValue) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceInOut.java new file mode 100644 index 0000000..3d7075d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceInOut.java @@ -0,0 +1,57 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseBounceInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseBounceInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseBounceInOut() { + + } + + public static EaseBounceInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseBounceInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if(pSecondsElapsed < pDuration * 0.5) { + return EaseBounceIn.getInstance().getPercentageDone(pSecondsElapsed * 2, pDuration, 0, pMaxValue) * 0.5f + pMinValue; + } else { + return EaseBounceOut.getInstance().getPercentageDone(pSecondsElapsed * 2 - pDuration, pDuration, 0, pMaxValue) * 0.5f + pMaxValue * 0.5f + pMinValue; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceOut.java new file mode 100644 index 0000000..8bf486e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseBounceOut.java @@ -0,0 +1,61 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseBounceOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseBounceOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseBounceOut() { + + } + + public static EaseBounceOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseBounceOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration) < (1 / 2.75)) { + return pMaxValue * (7.5625f * pSecondsElapsed * pSecondsElapsed) + pMinValue; + } else if(pSecondsElapsed < (2 / 2.75)) { + return pMaxValue * (7.5625f * (pSecondsElapsed -= (1.5f / 2.75f)) * pSecondsElapsed + 0.75f) + pMinValue; + } else if(pSecondsElapsed < (2.5 / 2.75)) { + return pMaxValue * (7.5625f * (pSecondsElapsed -= (2.25f / 2.75f)) * pSecondsElapsed + 0.9375f) + pMinValue; + } else { + return pMaxValue * (7.5625f * (pSecondsElapsed -= (2.625f / 2.75f)) * pSecondsElapsed + 0.984375f) + pMinValue; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularIn.java new file mode 100644 index 0000000..67603ec --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularIn.java @@ -0,0 +1,54 @@ +package org.anddev.andengine.util.modifier.ease; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseCircularIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseCircularIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseCircularIn() { + } + + public static EaseCircularIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseCircularIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (-pMaxValue * (FloatMath.sqrt(1 - (pSecondsElapsed /= pDuration) * pSecondsElapsed) - 1.0f) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularInOut.java new file mode 100644 index 0000000..93aaa50 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularInOut.java @@ -0,0 +1,58 @@ +package org.anddev.andengine.util.modifier.ease; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseCircularInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseCircularInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseCircularInOut() { + } + + public static EaseCircularInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseCircularInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration * 0.5) < 1) { + return (float) (-pMaxValue * 0.5 * (FloatMath.sqrt(1 - pSecondsElapsed * pSecondsElapsed) - 1) + pMinValue); + } + + return (float) (pMaxValue * 0.5 * (FloatMath.sqrt(1 - (pSecondsElapsed -= 2) * pSecondsElapsed) + 1) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularOut.java new file mode 100644 index 0000000..6d09faa --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCircularOut.java @@ -0,0 +1,54 @@ +package org.anddev.andengine.util.modifier.ease; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseCircularOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseCircularOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseCircularOut() { + } + + public static EaseCircularOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseCircularOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (pMaxValue * FloatMath.sqrt(1 - (pSecondsElapsed = pSecondsElapsed / pDuration - 1) * pSecondsElapsed) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicIn.java new file mode 100644 index 0000000..74e093d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicIn.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseCubicIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseCubicIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseCubicIn() { + } + + public static EaseCubicIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseCubicIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * (pSecondsElapsed /= pDuration) * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicInOut.java new file mode 100644 index 0000000..afdb373 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicInOut.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseCubicInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseCubicInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseCubicInOut() { + } + + public static EaseCubicInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseCubicInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return pMaxValue * 0.5f * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + return pMaxValue * 0.5f * ((pSecondsElapsed -= 2) * pSecondsElapsed * pSecondsElapsed + 2) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicOut.java new file mode 100644 index 0000000..d4928cf --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseCubicOut.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseCubicOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseCubicOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseCubicOut() { + } + + public static EaseCubicOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseCubicOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * ((pSecondsElapsed = pSecondsElapsed / pDuration - 1) * pSecondsElapsed * pSecondsElapsed + 1) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticIn.java new file mode 100644 index 0000000..3878b70 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticIn.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.util.modifier.ease; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseElasticIn implements IEaseFunction, MathConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseElasticIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseElasticIn() { + } + + public static EaseElasticIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseElasticIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + float s; + float p = 0.0f; + float a = 0.0f; + if(pSecondsElapsed == 0) { + return pMinValue; + } + if((pSecondsElapsed /= pDuration) == 1) { + return pMinValue + pMaxValue; + } + if(p == 0) { + p = pDuration * 0.3f; + } + if(a == 0 || (pMaxValue > 0 && a < pMaxValue) || (pMaxValue < 0 && a < -pMaxValue)) { + a = pMaxValue; + s = p / 4; + } else { + s = (float) (p / PI_TWICE * Math.asin(pMaxValue / a)); + } + return (float) (-(a * Math.pow(2, 10 * (pSecondsElapsed -= 1)) * FloatMath.sin((pSecondsElapsed * pDuration - s) * PI_TWICE / p)) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticInOut.java new file mode 100644 index 0000000..7e26d9c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticInOut.java @@ -0,0 +1,77 @@ +package org.anddev.andengine.util.modifier.ease; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseElasticInOut implements IEaseFunction, MathConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseElasticInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseElasticInOut() { + } + + public static EaseElasticInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseElasticInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + float s; + float p = 0.0f; + float a = 0.0f; + if(pSecondsElapsed == 0) { + return pMinValue; + } + if((pSecondsElapsed /= pDuration * 0.5) == 2) { + return pMinValue + pMaxValue; + } + if(p == 0) { + p = pDuration * (0.3f * 1.5f); + } + if(a == 0 || (pMaxValue > 0 && a < pMaxValue) || (pMaxValue < 0 && a < -pMaxValue)) { + a = pMaxValue; + s = p / 4; + } else { + s = (float) (p / PI_TWICE * Math.asin(pMaxValue / a)); + } + if(pSecondsElapsed < 1) { + return (float) (-0.5 * (a * Math.pow(2, 10 * (pSecondsElapsed -= 1)) * FloatMath.sin((pSecondsElapsed * pDuration - s) * PI_TWICE / p)) + pMinValue); + } + return (float) (a * Math.pow(2, -10 * (pSecondsElapsed -= 1)) * FloatMath.sin((pSecondsElapsed * pDuration - s) * PI_TWICE / p) * .5 + pMaxValue + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticOut.java new file mode 100644 index 0000000..be5b830 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseElasticOut.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.util.modifier.ease; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseElasticOut implements IEaseFunction, MathConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseElasticOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseElasticOut() { + } + + public static EaseElasticOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseElasticOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + float s; + float p = 0.0f; + float a = 0.0f; + if(pSecondsElapsed == 0) { + return pMinValue; + } + if((pSecondsElapsed /= pDuration) == 1) { + return pMinValue + pMaxValue; + } + if(p == 0) { + p = pDuration * 0.3f; + } + if(a == 0 || (pMaxValue > 0 && a < pMaxValue) || (pMaxValue < 0 && a < -pMaxValue)) { + a = pMaxValue; + s = p / 4; + } else { + s = (float) (p / PI_TWICE * Math.asin(pMaxValue / a)); + } + return (float) (a * Math.pow(2, -10 * pSecondsElapsed) * FloatMath.sin((pSecondsElapsed * pDuration - s) * PI_TWICE / p) + pMaxValue + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialIn.java new file mode 100644 index 0000000..025aec3 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialIn.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseExponentialIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseExponentialIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseExponentialIn() { + } + + public static EaseExponentialIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseExponentialIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (float) ((pSecondsElapsed == 0) ? pMinValue : pMaxValue * Math.pow(2, 10 * (pSecondsElapsed / pDuration - 1)) + pMinValue - pMaxValue * 0.001f); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialInOut.java new file mode 100644 index 0000000..1495602 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialInOut.java @@ -0,0 +1,61 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseExponentialInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseExponentialInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseExponentialInOut() { + } + + public static EaseExponentialInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseExponentialInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if(pSecondsElapsed == 0) { + return pMinValue; + } + if(pSecondsElapsed == pDuration) { + return pMinValue + pMaxValue; + } + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return (float) (pMaxValue * 0.5f * Math.pow(2, 10 * (pSecondsElapsed - 1)) + pMinValue); + } + return (float) (pMaxValue * 0.5f * (-Math.pow(2, -10 * --pSecondsElapsed) + 2) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialOut.java new file mode 100644 index 0000000..b88220a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseExponentialOut.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseExponentialOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseExponentialOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseExponentialOut() { + } + + public static EaseExponentialOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseExponentialOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (float) ((pSecondsElapsed == pDuration) ? pMinValue + pMaxValue : pMaxValue * (-Math.pow(2, -10 * pSecondsElapsed / pDuration) + 1) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseLinear.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseLinear.java new file mode 100644 index 0000000..020b6a2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseLinear.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:50:40 - 26.07.2010 + */ +public class EaseLinear implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseLinear INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseLinear() { + } + + public static EaseLinear getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseLinear(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * pSecondsElapsed / pDuration + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadIn.java new file mode 100644 index 0000000..43ac06f --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadIn.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuadIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuadIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuadIn() { + } + + public static EaseQuadIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuadIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * (pSecondsElapsed /= pDuration) * pSecondsElapsed + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadInOut.java new file mode 100644 index 0000000..db08618 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadInOut.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuadInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuadInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuadInOut() { + } + + public static EaseQuadInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuadInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return pMaxValue * 0.5f * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + return -pMaxValue * 0.5f * ((--pSecondsElapsed) * (pSecondsElapsed - 2) - 1) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadOut.java new file mode 100644 index 0000000..9a9d283 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuadOut.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuadOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuadOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuadOut() { + } + + public static EaseQuadOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuadOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return -pMaxValue * (pSecondsElapsed /= pDuration) * (pSecondsElapsed - 2) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartIn.java new file mode 100644 index 0000000..828330e --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartIn.java @@ -0,0 +1,53 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuartIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuartIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuartIn() { + + } + + public static EaseQuartIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuartIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * (pSecondsElapsed /= pDuration) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartInOut.java new file mode 100644 index 0000000..121fc10 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartInOut.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuartInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuartInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuartInOut() { + } + + public static EaseQuartInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuartInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return pMaxValue * 0.5f * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + return -pMaxValue * 0.5f * ((pSecondsElapsed -= 2) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed - 2) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartOut.java new file mode 100644 index 0000000..84dbd5a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuartOut.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuartOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuartOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuartOut() { + } + + public static EaseQuartOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuartOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return -pMaxValue * ((pSecondsElapsed = pSecondsElapsed / pDuration - 1) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed - 1) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintIn.java new file mode 100644 index 0000000..9ac61c0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintIn.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuintIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuintIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuintIn() { + } + + public static EaseQuintIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuintIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * (pSecondsElapsed /= pDuration) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintInOut.java new file mode 100644 index 0000000..05b90b7 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintInOut.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuintInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuintInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuintInOut() { + } + + public static EaseQuintInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuintInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return pMaxValue * 0.5f * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + return pMaxValue * 0.5f * ((pSecondsElapsed -= 2) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + 2) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintOut.java new file mode 100644 index 0000000..f8ecd45 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseQuintOut.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseQuintOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseQuintOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseQuintOut() { + } + + public static EaseQuintOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseQuintOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * ((pSecondsElapsed = pSecondsElapsed / pDuration - 1) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + 1) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineIn.java new file mode 100644 index 0000000..7cc8dc8 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineIn.java @@ -0,0 +1,56 @@ +package org.anddev.andengine.util.modifier.ease; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseSineIn implements IEaseFunction, MathConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseSineIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseSineIn() { + } + + public static EaseSineIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseSineIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (-pMaxValue * FloatMath.cos(pSecondsElapsed / pDuration * PI_HALF) + pMaxValue + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineInOut.java new file mode 100644 index 0000000..7adb16a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineInOut.java @@ -0,0 +1,56 @@ +package org.anddev.andengine.util.modifier.ease; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseSineInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseSineInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseSineInOut() { + } + + public static EaseSineInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseSineInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (-pMaxValue * 0.5f * (FloatMath.cos(MathConstants.PI * pSecondsElapsed / pDuration) - 1) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineOut.java new file mode 100644 index 0000000..7d56592 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseSineOut.java @@ -0,0 +1,56 @@ +package org.anddev.andengine.util.modifier.ease; + +import org.anddev.andengine.util.constants.MathConstants; + +import android.util.FloatMath; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseSineOut implements IEaseFunction, MathConstants { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseSineOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseSineOut() { + } + + public static EaseSineOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseSineOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return (pMaxValue * FloatMath.sin(pSecondsElapsed / pDuration * PI_HALF) + pMinValue); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongIn.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongIn.java new file mode 100644 index 0000000..5c8d900 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongIn.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseStrongIn implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseStrongIn INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseStrongIn() { + } + + public static EaseStrongIn getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseStrongIn(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * (pSecondsElapsed /= pDuration) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongInOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongInOut.java new file mode 100644 index 0000000..70883e0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongInOut.java @@ -0,0 +1,55 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseStrongInOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseStrongInOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseStrongInOut() { + } + + public static EaseStrongInOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseStrongInOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + if((pSecondsElapsed /= pDuration * 0.5f) < 1) { + return pMaxValue * 0.5f * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + pMinValue; + } + return pMaxValue * 0.5f * ((pSecondsElapsed -= 2) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + 2) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongOut.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongOut.java new file mode 100644 index 0000000..8ffc229 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/EaseStrongOut.java @@ -0,0 +1,52 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 16:52:11 - 26.07.2010 + */ +public class EaseStrongOut implements IEaseFunction { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private static EaseStrongOut INSTANCE; + + // =========================================================== + // Constructors + // =========================================================== + + private EaseStrongOut() { + } + + public static EaseStrongOut getInstance() { + if(INSTANCE == null) { + INSTANCE = new EaseStrongOut(); + } + return INSTANCE; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getPercentageDone(float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue) { + return pMaxValue * ((pSecondsElapsed = pSecondsElapsed / pDuration - 1) * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed * pSecondsElapsed + 1) + pMinValue; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/ease/IEaseFunction.java b/AndEngine/src/org/anddev/andengine/util/modifier/ease/IEaseFunction.java new file mode 100644 index 0000000..4bea2bd --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/ease/IEaseFunction.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.util.modifier.ease; + +/** + * @author Gil, Nicolas Gramlich + * @since 17:13:17 - 26.07.2010 + */ +public interface IEaseFunction { + // =========================================================== + // Final Fields + // =========================================================== + + public static final IEaseFunction DEFAULT = EaseLinear.getInstance(); + + // =========================================================== + // Methods + // =========================================================== + + public abstract float getPercentageDone(final float pSecondsElapsed, final float pDuration, final float pMinValue, final float pMaxValue); +} diff --git a/AndEngine/src/org/anddev/andengine/util/modifier/util/ModifierUtils.java b/AndEngine/src/org/anddev/andengine/util/modifier/util/ModifierUtils.java new file mode 100644 index 0000000..2ccf115 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/modifier/util/ModifierUtils.java @@ -0,0 +1,62 @@ +package org.anddev.andengine.util.modifier.util; + +import org.anddev.andengine.util.modifier.IModifier; + +/** + * @author Nicolas Gramlich + * @since 11:16:36 - 03.09.2010 + */ +public class ModifierUtils { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public static IModifier getModifierWithLongestDuration(final IModifier[] pModifiers){ + IModifier out = null; + float longestDuration = Float.MIN_VALUE; + + for(int i = pModifiers.length - 1; i >= 0; i--) { + final float duration = pModifiers[i].getDuration(); + if(duration > longestDuration) { + longestDuration = duration; + out = pModifiers[i]; + } + } + + return out; + } + + public static float getSequenceDurationOfModifier(final IModifier[] pModifiers){ + float duration = Float.MIN_VALUE; + + for(int i = pModifiers.length - 1; i >= 0; i--) { + duration += pModifiers[i].getDuration(); + } + + return duration; + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/Direction.java b/AndEngine/src/org/anddev/andengine/util/path/Direction.java new file mode 100644 index 0000000..284127a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/Direction.java @@ -0,0 +1,74 @@ +package org.anddev.andengine.util.path; + +/** + * @author Nicolas Gramlich + * @since 15:19:11 - 17.08.2010 + */ +public enum Direction { + // =========================================================== + // Elements + // =========================================================== + + UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0); + + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mDeltaX; + private final int mDeltaY; + + // =========================================================== + // Constructors + // =========================================================== + + private Direction(final int pDeltaX, final int pDeltaY) { + this.mDeltaX = pDeltaX; + this.mDeltaY = pDeltaY; + } + + public static Direction fromDelta(final int pDeltaX, final int pDeltaY) { + if(pDeltaX == 0) { + if(pDeltaY == 1) { + return DOWN; + } else if(pDeltaY == -1) { + return UP; + } + } else if (pDeltaY == 0) { + if(pDeltaX == 1) { + return RIGHT; + } else if(pDeltaX == -1) { + return LEFT; + } + } + throw new IllegalArgumentException(); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getDeltaX() { + return this.mDeltaX; + } + + public int getDeltaY() { + return this.mDeltaY; + } + + // =========================================================== + // Methods from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/IPathFinder.java b/AndEngine/src/org/anddev/andengine/util/path/IPathFinder.java new file mode 100644 index 0000000..f582752 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/IPathFinder.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.util.path; + +/** + * @author Nicolas Gramlich + * @since 22:57:13 - 16.08.2010 + */ +public interface IPathFinder { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public Path findPath(final T pEntity, final int pMaxCost, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow); +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/ITiledMap.java b/AndEngine/src/org/anddev/andengine/util/path/ITiledMap.java new file mode 100644 index 0000000..120a8c2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/ITiledMap.java @@ -0,0 +1,24 @@ +package org.anddev.andengine.util.path; + +/** + * @author Nicolas Gramlich + * @since 23:00:24 - 16.08.2010 + */ +public interface ITiledMap { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public int getTileColumns(); + public int getTileRows(); + + public void onTileVisitedByPathFinder(final int pTileColumn, int pTileRow); + + public boolean isTileBlocked(final T pEntity, final int pTileColumn, final int pTileRow); + + public float getStepCost(final T pEntity, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow); +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/Path.java b/AndEngine/src/org/anddev/andengine/util/path/Path.java new file mode 100644 index 0000000..85b3b79 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/Path.java @@ -0,0 +1,187 @@ +package org.anddev.andengine.util.path; + +import java.util.ArrayList; + +public class Path { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mSteps = new ArrayList(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getLength() { + return this.mSteps.size(); + } + + public Step getStep(final int pIndex) { + return this.mSteps.get(pIndex); + } + + public Direction getDirectionToPreviousStep(final int pIndex) { + if(pIndex == 0) { + return null; + } else { + final int dX = this.getTileColumn(pIndex - 1) - this.getTileColumn(pIndex); + final int dY = this.getTileRow(pIndex - 1) - this.getTileRow(pIndex); + return Direction.fromDelta(dX, dY); + } + } + + public Direction getDirectionToNextStep(final int pIndex) { + if(pIndex == this.getLength() - 1) { + return null; + } else { + final int dX = this.getTileColumn(pIndex + 1) - this.getTileColumn(pIndex); + final int dY = this.getTileRow(pIndex + 1) - this.getTileRow(pIndex); + return Direction.fromDelta(dX, dY); + } + } + + public int getTileColumn(final int pIndex) { + return this.getStep(pIndex).getTileColumn(); + } + + public int getTileRow(final int pIndex) { + return this.getStep(pIndex).getTileRow(); + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void append(final int pTileColumn, final int pTileRow) { + this.append(new Step(pTileColumn, pTileRow)); + } + + public void append(final Step pStep) { + this.mSteps.add(pStep); + } + + public void prepend(final int pTileColumn, final int pTileRow) { + this.prepend(new Step(pTileColumn, pTileRow)); + } + + public void prepend(final Step pStep) { + this.mSteps.add(0, pStep); + } + + public boolean contains(final int pTileColumn, final int pTileRow) { + final ArrayList steps = this.mSteps; + for(int i = steps.size() - 1; i >= 0; i--) { + final Step step = steps.get(i); + if(step.getTileColumn() == pTileColumn && step.getTileRow() == pTileRow) { + return true; + } + } + return false; + } + + public int getFromTileRow() { + return this.getTileRow(0); + } + + public int getFromTileColumn() { + return this.getTileColumn(0); + } + + public int getToTileRow() { + return this.getTileRow(this.mSteps.size() - 1); + } + + public int getToTileColumn() { + return this.getTileColumn(this.mSteps.size() - 1); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + public class Step { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final int mTileColumn; + private final int mTileRow; + + // =========================================================== + // Constructors + // =========================================================== + + public Step(final int pTileColumn, final int pTileRow) { + this.mTileColumn = pTileColumn; + this.mTileRow = pTileRow; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int getTileColumn() { + return this.mTileColumn; + } + + public int getTileRow() { + return this.mTileRow; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int hashCode() { + return this.mTileColumn << 16 + this.mTileRow; + } + + @Override + public boolean equals(final Object pOther) { + if(this == pOther) { + return true; + } + if(pOther == null) { + return false; + } + if(this.getClass() != pOther.getClass()) { + return false; + } + final Step other = (Step) pOther; + if(this.mTileColumn != other.mTileColumn) { + return false; + } + if(this.mTileRow != other.mTileRow) { + return false; + } + return true; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } + +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/astar/AStarPathFinder.java b/AndEngine/src/org/anddev/andengine/util/path/astar/AStarPathFinder.java new file mode 100644 index 0000000..5e4d8eb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/astar/AStarPathFinder.java @@ -0,0 +1,252 @@ +package org.anddev.andengine.util.path.astar; + +import java.util.ArrayList; +import java.util.Collections; + +import org.anddev.andengine.util.path.IPathFinder; +import org.anddev.andengine.util.path.ITiledMap; +import org.anddev.andengine.util.path.Path; + +/** + * @author Nicolas Gramlich + * @since 23:16:17 - 16.08.2010 + */ +public class AStarPathFinder implements IPathFinder { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ArrayList mVisitedNodes = new ArrayList(); + private final ArrayList mOpenNodes = new ArrayList(); + + private final ITiledMap mTiledMap; + private final int mMaxSearchDepth; + + private final Node[][] mNodes; + private final boolean mAllowDiagonalMovement; + + private final IAStarHeuristic mAStarHeuristic; + + // =========================================================== + // Constructors + // =========================================================== + + public AStarPathFinder(final ITiledMap pTiledMap, final int pMaxSearchDepth, final boolean pAllowDiagonalMovement) { + this(pTiledMap, pMaxSearchDepth, pAllowDiagonalMovement, new EuclideanHeuristic()); + } + + public AStarPathFinder(final ITiledMap pTiledMap, final int pMaxSearchDepth, final boolean pAllowDiagonalMovement, final IAStarHeuristic pAStarHeuristic) { + this.mAStarHeuristic = pAStarHeuristic; + this.mTiledMap = pTiledMap; + this.mMaxSearchDepth = pMaxSearchDepth; + this.mAllowDiagonalMovement = pAllowDiagonalMovement; + + this.mNodes = new Node[pTiledMap.getTileRows()][pTiledMap.getTileColumns()]; + final Node[][] nodes = this.mNodes; + for(int x = pTiledMap.getTileColumns() - 1; x >= 0; x--) { + for(int y = pTiledMap.getTileRows() - 1; y >= 0; y--) { + nodes[y][x] = new Node(x, y); + } + } + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public Path findPath(final T pEntity, final int pMaxCost, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow) { + final ITiledMap tiledMap = this.mTiledMap; + if(tiledMap.isTileBlocked(pEntity, pToTileColumn, pToTileRow)) { + return null; + } + + /* Drag some fields to local variables. */ + final ArrayList openNodes = this.mOpenNodes; + final ArrayList visitedNodes = this.mVisitedNodes; + + final Node[][] nodes = this.mNodes; + final Node fromNode = nodes[pFromTileRow][pFromTileColumn]; + final Node toNode = nodes[pToTileRow][pToTileColumn]; + + final IAStarHeuristic aStarHeuristic = this.mAStarHeuristic; + final boolean allowDiagonalMovement = this.mAllowDiagonalMovement; + final int maxSearchDepth = this.mMaxSearchDepth; + + /* Initialize algorithm. */ + fromNode.mCost = 0; + fromNode.mDepth = 0; + toNode.mParent = null; + + visitedNodes.clear(); + + openNodes.clear(); + openNodes.add(fromNode); + + int currentDepth = 0; + while(currentDepth < maxSearchDepth && !openNodes.isEmpty()) { + /* The first Node in the open list is the one with the lowest cost. */ + final Node current = openNodes.remove(0); + if(current == toNode) { + break; + } + + visitedNodes.add(current); + + /* Loop over all neighbors of this tile. */ + for(int dX = -1; dX <= 1; dX++) { + for(int dY = -1; dY <= 1; dY++) { + if((dX == 0) && (dY == 0)) { + continue; + } + + if(!allowDiagonalMovement) { + if((dX != 0) && (dY != 0)) { + continue; + } + } + + final int neighborTileColumn = dX + current.mTileColumn; + final int neighborTileRow = dY + current.mTileRow; + + if(!this.isTileBlocked(pEntity, pFromTileColumn, pFromTileRow, neighborTileColumn, neighborTileRow)) { + final float neighborCost = current.mCost + tiledMap.getStepCost(pEntity, current.mTileColumn, current.mTileRow, neighborTileColumn, neighborTileRow); + final Node neighbor = nodes[neighborTileRow][neighborTileColumn]; + tiledMap.onTileVisitedByPathFinder(neighborTileColumn, neighborTileRow); + + /* Re-evaluate if there is a better path. */ + if(neighborCost < neighbor.mCost) { + // TODO Is this ever possible with AStar ?? + if(openNodes.contains(neighbor)) { + openNodes.remove(neighbor); + } + if(visitedNodes.contains(neighbor)) { + visitedNodes.remove(neighbor); + } + } + + if(!openNodes.contains(neighbor) && !(visitedNodes.contains(neighbor))) { + neighbor.mCost = neighborCost; + if(neighbor.mCost <= pMaxCost) { + neighbor.mExpectedRestCost = aStarHeuristic.getExpectedRestCost(tiledMap, pEntity, neighborTileColumn, neighborTileRow, pToTileColumn, pToTileRow); + currentDepth = Math.max(currentDepth, neighbor.setParent(current)); + openNodes.add(neighbor); + + /* Ensure always the node with the lowest cost+heuristic + * will be used next, simply by sorting. */ + Collections.sort(openNodes); + } + } + } + } + } + } + + /* Check if a path was found. */ + if(toNode.mParent == null) { + return null; + } + + /* Traceback path. */ + final Path path = new Path(); + Node tmp = nodes[pToTileRow][pToTileColumn]; + while(tmp != fromNode) { + path.prepend(tmp.mTileColumn, tmp.mTileRow); + tmp = tmp.mParent; + } + path.prepend(pFromTileColumn, pFromTileRow); + + return path; + } + + // =========================================================== + // Methods + // =========================================================== + + protected boolean isTileBlocked(final T pEntity, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow) { + if((pToTileColumn < 0) || (pToTileRow < 0) || (pToTileColumn >= this.mTiledMap.getTileColumns()) || (pToTileRow >= this.mTiledMap.getTileRows())) { + return true; + } else if((pFromTileColumn == pToTileColumn) && (pFromTileRow == pToTileRow)) { + return true; + } + + return this.mTiledMap.isTileBlocked(pEntity, pToTileColumn, pToTileRow); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + + private static class Node implements Comparable { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + Node mParent; + int mDepth; + + final int mTileColumn; + final int mTileRow; + + float mCost; + float mExpectedRestCost; + + // =========================================================== + // Constructors + // =========================================================== + + public Node(final int pTileColumn, final int pTileRow) { + this.mTileColumn = pTileColumn; + this.mTileRow = pTileRow; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public int setParent(final Node parent) { + this.mDepth = parent.mDepth + 1; + this.mParent = parent; + + return this.mDepth; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public int compareTo(final Node pOther) { + final float totalCost = this.mExpectedRestCost + this.mCost; + final float totalCostOther = pOther.mExpectedRestCost + pOther.mCost; + + if (totalCost < totalCostOther) { + return -1; + } else if (totalCost > totalCostOther) { + return 1; + } else { + return 0; + } + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/astar/EuclideanHeuristic.java b/AndEngine/src/org/anddev/andengine/util/path/astar/EuclideanHeuristic.java new file mode 100644 index 0000000..216818a --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/astar/EuclideanHeuristic.java @@ -0,0 +1,47 @@ +package org.anddev.andengine.util.path.astar; + +import org.anddev.andengine.util.path.ITiledMap; + +import android.util.FloatMath; + +/** + * @author Nicolas Gramlich + * @since 22:58:01 - 16.08.2010 + */ +public class EuclideanHeuristic implements IAStarHeuristic { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getExpectedRestCost(final ITiledMap pTileMap, final T pEntity, final int pTileFromX, final int pTileFromY, final int pTileToX, final int pTileToY) { + final float dX = pTileToX - pTileFromX; + final float dY = pTileToY - pTileFromY; + + return FloatMath.sqrt(dX * dX + dY * dY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/astar/IAStarHeuristic.java b/AndEngine/src/org/anddev/andengine/util/path/astar/IAStarHeuristic.java new file mode 100644 index 0000000..6e48886 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/astar/IAStarHeuristic.java @@ -0,0 +1,19 @@ +package org.anddev.andengine.util.path.astar; + +import org.anddev.andengine.util.path.ITiledMap; + +/** + * @author Nicolas Gramlich + * @since 22:59:20 - 16.08.2010 + */ +public interface IAStarHeuristic { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + public float getExpectedRestCost(final ITiledMap pTiledMap, final T pEntity, final int pFromTileColumn, final int pFromTileRow, final int pToTileColumn, final int pToTileRow); +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/astar/ManhattanHeuristic.java b/AndEngine/src/org/anddev/andengine/util/path/astar/ManhattanHeuristic.java new file mode 100644 index 0000000..6fff053 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/astar/ManhattanHeuristic.java @@ -0,0 +1,42 @@ +package org.anddev.andengine.util.path.astar; + +import org.anddev.andengine.util.path.ITiledMap; + +/** + * @author Nicolas Gramlich + * @since 22:58:01 - 16.08.2010 + */ +public class ManhattanHeuristic implements IAStarHeuristic { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getExpectedRestCost(final ITiledMap pTiledMap, final T pEntity, final int pTileFromX, final int pTileFromY, final int pTileToX, final int pTileToY) { + return Math.abs(pTileFromX - pTileToX) + Math.abs(pTileToX - pTileToY); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/path/astar/NullHeuristic.java b/AndEngine/src/org/anddev/andengine/util/path/astar/NullHeuristic.java new file mode 100644 index 0000000..7aef043 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/path/astar/NullHeuristic.java @@ -0,0 +1,42 @@ +package org.anddev.andengine.util.path.astar; + +import org.anddev.andengine.util.path.ITiledMap; + +/** + * @author Nicolas Gramlich + * @since 22:58:01 - 16.08.2010 + */ +public class NullHeuristic implements IAStarHeuristic { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public float getExpectedRestCost(final ITiledMap pTiledMap, final T pEntity, final int pTileFromX, final int pTileFromY, final int pTileToX, final int pTileToY) { + return 0; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolItem.java b/AndEngine/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolItem.java new file mode 100644 index 0000000..81fd1cf --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolItem.java @@ -0,0 +1,48 @@ +package org.anddev.andengine.util.pool; + +import org.anddev.andengine.entity.IEntity; + +/** + * @author Nicolas Gramlich + * @since 00:53:22 - 28.08.2010 + */ +public class EntityDetachRunnablePoolItem extends RunnablePoolItem { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + protected IEntity mEntity; + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + public void setEntity(final IEntity pEntity) { + this.mEntity = pEntity; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void run() { + this.mEntity.detachSelf(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolUpdateHandler.java b/AndEngine/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolUpdateHandler.java new file mode 100644 index 0000000..b4658a1 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/EntityDetachRunnablePoolUpdateHandler.java @@ -0,0 +1,40 @@ +package org.anddev.andengine.util.pool; + +/** + * @author Nicolas Gramlich + * @since 23:16:25 - 31.08.2010 + */ +public class EntityDetachRunnablePoolUpdateHandler extends RunnablePoolUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected EntityDetachRunnablePoolItem onAllocatePoolItem() { + return new EntityDetachRunnablePoolItem(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/pool/GenericPool.java b/AndEngine/src/org/anddev/andengine/util/pool/GenericPool.java new file mode 100644 index 0000000..59b5531 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/GenericPool.java @@ -0,0 +1,132 @@ +package org.anddev.andengine.util.pool; + +import java.util.Collections; +import java.util.Stack; + +import org.anddev.andengine.util.Debug; + +/** + * @author Valentin Milea + * @author Nicolas Gramlich + * + * @since 22:19:55 - 31.08.2010 + * @param + */ +public abstract class GenericPool { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Stack mAvailableItems = new Stack(); + private int mUnrecycledCount; + private final int mGrowth; + + // =========================================================== + // Constructors + // =========================================================== + + public GenericPool() { + this(0); + } + + public GenericPool(final int pInitialSize) { + this(pInitialSize, 1); + } + + public GenericPool(final int pInitialSize, final int pGrowth) { + if(pGrowth < 0) { + throw new IllegalArgumentException("pGrowth must be at least 0!"); + } + + this.mGrowth = pGrowth; + + if(pInitialSize > 0) { + this.batchAllocatePoolItems(pInitialSize); + } + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public synchronized int getUnrecycledCount() { + return this.mUnrecycledCount; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract T onAllocatePoolItem(); + + // =========================================================== + // Methods + // =========================================================== + + protected void onHandleRecycleItem(final T pItem) { + + } + + protected T onHandleAllocatePoolItem() { + return this.onAllocatePoolItem(); + } + + protected void onHandleObtainItem(final T pItem) { + + } + + public synchronized void batchAllocatePoolItems(final int pCount) { + final Stack availableItems = this.mAvailableItems; + for(int i = pCount - 1; i >= 0; i--) { + availableItems.push(this.onHandleAllocatePoolItem()); + } + } + + public synchronized T obtainPoolItem() { + final T item; + + if(this.mAvailableItems.size() > 0) { + item = this.mAvailableItems.pop(); + } else { + if(this.mGrowth == 1) { + item = this.onHandleAllocatePoolItem(); + } else { + this.batchAllocatePoolItems(this.mGrowth); + item = this.mAvailableItems.pop(); + } + Debug.i(this.getClass().getName() + "<" + item.getClass().getSimpleName() +"> was exhausted, with " + this.mUnrecycledCount + " item not yet recycled. Allocated " + this.mGrowth + " more."); + } + this.onHandleObtainItem(item); + + this.mUnrecycledCount++; + return item; + } + + public synchronized void recyclePoolItem(final T pItem) { + if(pItem == null) { + throw new IllegalArgumentException("Cannot recycle null item!"); + } + + this.onHandleRecycleItem(pItem); + + this.mAvailableItems.push(pItem); + + this.mUnrecycledCount--; + + if(this.mUnrecycledCount < 0) { + Debug.e("More items recycled than obtained!"); + } + } + + public synchronized void shufflePoolItems() { + Collections.shuffle(this.mAvailableItems); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/pool/MultiPool.java b/AndEngine/src/org/anddev/andengine/util/pool/MultiPool.java new file mode 100644 index 0000000..ab27c8c --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/MultiPool.java @@ -0,0 +1,59 @@ +package org.anddev.andengine.util.pool; + +import android.util.SparseArray; + +/** + * @author Nicolas Gramlich + * @since 10:13:26 - 02.03.2011 + */ +public class MultiPool { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final SparseArray> mPools = new SparseArray>(); + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + public void registerPool(final int pID, final GenericPool pPool) { + this.mPools.put(pID, pPool); + } + + public T obtainPoolItem(final int pID) { + final GenericPool pool = this.mPools.get(pID); + if(pool == null) { + return null; + } else { + return pool.obtainPoolItem(); + } + } + + public void recyclePoolItem(final int pID, final T pItem) { + final GenericPool pool = this.mPools.get(pID); + if(pool != null) { + pool.recyclePoolItem(pItem); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/pool/Pool.java b/AndEngine/src/org/anddev/andengine/util/pool/Pool.java new file mode 100644 index 0000000..8cae4b2 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/Pool.java @@ -0,0 +1,92 @@ +package org.anddev.andengine.util.pool; + + +/** + * @author Valentin Milea + * @author Nicolas Gramlich + * + * @since 23:00:21 - 21.08.2010 + * @param + */ +public abstract class Pool extends GenericPool{ + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public Pool() { + super(); + } + + public Pool(final int pInitialSize) { + super(pInitialSize); + } + + public Pool(final int pInitialSize, final int pGrowth) { + super(pInitialSize, pGrowth); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected T onHandleAllocatePoolItem() { + final T poolItem = super.onHandleAllocatePoolItem(); + poolItem.mParent = this; + return poolItem; + } + + @Override + protected void onHandleObtainItem(final T pPoolItem) { + pPoolItem.mRecycled = false; + pPoolItem.onObtain(); + } + + @Override + protected void onHandleRecycleItem(final T pPoolItem) { + pPoolItem.onRecycle(); + pPoolItem.mRecycled = true; + } + + @Override + public synchronized void recyclePoolItem(final T pPoolItem) { + if(pPoolItem.mParent == null) { + throw new IllegalArgumentException("PoolItem not assigned to a pool!"); + } else if(!pPoolItem.isFromPool(this)) { + throw new IllegalArgumentException("PoolItem from another pool!"); + } else if(pPoolItem.isRecycled()) { + throw new IllegalArgumentException("PoolItem already recycled!"); + } + + super.recyclePoolItem(pPoolItem); + } + + // =========================================================== + // Methods + // =========================================================== + + public synchronized boolean ownsPoolItem(final T pPoolItem) { + return pPoolItem.mParent == this; + } + + @SuppressWarnings("unchecked") + void recycle(final PoolItem pPoolItem) { + this.recyclePoolItem((T) pPoolItem); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/pool/PoolItem.java b/AndEngine/src/org/anddev/andengine/util/pool/PoolItem.java new file mode 100644 index 0000000..77e336d --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/PoolItem.java @@ -0,0 +1,68 @@ +package org.anddev.andengine.util.pool; + +/** + * @author Valentin Milea + * @author Nicolas Gramlich + * + * @since 23:02:47 - 21.08.2010 + */ +public abstract class PoolItem { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + Pool mParent; + boolean mRecycled = true; + + // =========================================================== + // Constructors + // =========================================================== + + public Pool getParent() { + return this.mParent; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public boolean isRecycled() { + return this.mRecycled; + } + + public boolean isFromPool(final Pool pPool) { + return pPool == this.mParent; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + protected void onRecycle() { + + } + + protected void onObtain() { + + } + + public void recycle() { + if(this.mParent == null) { + throw new IllegalStateException("Item already recycled!"); + } + + this.mParent.recycle(this); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/pool/PoolUpdateHandler.java b/AndEngine/src/org/anddev/andengine/util/pool/PoolUpdateHandler.java new file mode 100644 index 0000000..a9a1d26 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/PoolUpdateHandler.java @@ -0,0 +1,129 @@ +package org.anddev.andengine.util.pool; + +import java.util.ArrayList; + +import org.anddev.andengine.engine.handler.IUpdateHandler; + +/** + * @author Valentin Milea + * @author Nicolas Gramlich + * + * @since 23:02:58 - 21.08.2010 + * @param + */ +public abstract class PoolUpdateHandler implements IUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final Pool mPool; + private final ArrayList mScheduledPoolItems = new ArrayList(); + + // =========================================================== + // Constructors + // =========================================================== + + public PoolUpdateHandler() { + this.mPool = new Pool() { + @Override + protected T onAllocatePoolItem() { + return PoolUpdateHandler.this.onAllocatePoolItem(); + } + }; + } + + public PoolUpdateHandler(final int pInitialPoolSize) { + this.mPool = new Pool(pInitialPoolSize) { + @Override + protected T onAllocatePoolItem() { + return PoolUpdateHandler.this.onAllocatePoolItem(); + } + }; + } + + public PoolUpdateHandler(final int pInitialPoolSize, final int pGrowth) { + this.mPool = new Pool(pInitialPoolSize, pGrowth) { + @Override + protected T onAllocatePoolItem() { + return PoolUpdateHandler.this.onAllocatePoolItem(); + } + }; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + protected abstract T onAllocatePoolItem(); + + protected abstract void onHandlePoolItem(final T pPoolItem); + + @Override + public void onUpdate(final float pSecondsElapsed) { + final ArrayList scheduledPoolItems = this.mScheduledPoolItems; + + synchronized (scheduledPoolItems) { + final int count = scheduledPoolItems.size(); + + if(count > 0) { + final Pool pool = this.mPool; + T item; + + for(int i = 0; i < count; i++) { + item = scheduledPoolItems.get(i); + this.onHandlePoolItem(item); + pool.recyclePoolItem(item); + } + + scheduledPoolItems.clear(); + } + } + } + + @Override + public void reset() { + final ArrayList scheduledPoolItems = this.mScheduledPoolItems; + synchronized (scheduledPoolItems) { + final int count = scheduledPoolItems.size(); + + final Pool pool = this.mPool; + for(int i = count - 1; i >= 0; i--) { + pool.recyclePoolItem(scheduledPoolItems.get(i)); + } + + scheduledPoolItems.clear(); + } + } + + // =========================================================== + // Methods + // =========================================================== + + public T obtainPoolItem() { + return this.mPool.obtainPoolItem(); + } + + public void postPoolItem(final T pPoolItem) { + synchronized (this.mScheduledPoolItems) { + if(pPoolItem == null) { + throw new IllegalArgumentException("PoolItem already recycled!"); + } else if(!this.mPool.ownsPoolItem(pPoolItem)) { + throw new IllegalArgumentException("PoolItem from another pool!"); + } + + this.mScheduledPoolItems.add(pPoolItem); + } + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/pool/RunnablePoolItem.java b/AndEngine/src/org/anddev/andengine/util/pool/RunnablePoolItem.java new file mode 100644 index 0000000..1550fe5 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/RunnablePoolItem.java @@ -0,0 +1,35 @@ +package org.anddev.andengine.util.pool; + +/** + * @author Nicolas Gramlich + * @since 23:46:50 - 27.08.2010 + */ +public abstract class RunnablePoolItem extends PoolItem implements Runnable { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/pool/RunnablePoolUpdateHandler.java b/AndEngine/src/org/anddev/andengine/util/pool/RunnablePoolUpdateHandler.java new file mode 100644 index 0000000..266c972 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/pool/RunnablePoolUpdateHandler.java @@ -0,0 +1,54 @@ +package org.anddev.andengine.util.pool; + +/** + * @author Valentin Milea + * @author Nicolas Gramlich + * + * @since 23:03:58 - 21.08.2010 + * @param + */ +public abstract class RunnablePoolUpdateHandler extends PoolUpdateHandler { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + public RunnablePoolUpdateHandler() { + + } + + public RunnablePoolUpdateHandler(final int pInitialPoolSize) { + super(pInitialPoolSize); + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + protected abstract T onAllocatePoolItem(); + + @Override + protected void onHandlePoolItem(final T pRunnablePoolItem) { + pRunnablePoolItem.run(); + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/src/org/anddev/andengine/util/progress/IProgressListener.java b/AndEngine/src/org/anddev/andengine/util/progress/IProgressListener.java new file mode 100644 index 0000000..60debcf --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/progress/IProgressListener.java @@ -0,0 +1,17 @@ +package org.anddev.andengine.util.progress; + + +public interface IProgressListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * @param pProgress between 0 and 100. + */ + public void onProgressChanged(final int pProgress); +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/progress/ProgressCallable.java b/AndEngine/src/org/anddev/andengine/util/progress/ProgressCallable.java new file mode 100644 index 0000000..21599d0 --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/progress/ProgressCallable.java @@ -0,0 +1,24 @@ +package org.anddev.andengine.util.progress; + + +/** + * @author Nicolas Gramlich + * @since 20:52:44 - 03.01.2010 + */ +public interface ProgressCallable { + // =========================================================== + // Final Fields + // =========================================================== + + // =========================================================== + // Methods + // =========================================================== + + /** + * Computes a result, or throws an exception if unable to do so. + * @param pProgressListener + * @return computed result + * @throws Exception if unable to compute a result + */ + public T call(final IProgressListener pProgressListener) throws Exception; +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/progress/ProgressMonitor.java b/AndEngine/src/org/anddev/andengine/util/progress/ProgressMonitor.java new file mode 100644 index 0000000..bfd10ea --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/progress/ProgressMonitor.java @@ -0,0 +1,82 @@ +package org.anddev.andengine.util.progress; + +/** + * @author Nicolas Gramlich + * @since 18:07:35 - 09.07.2009 + */ +public class ProgressMonitor implements IProgressListener { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + private final ProgressMonitor mParentProgressMonitor; + private final IProgressListener mListener; + + private int mSubMonitorRangeFrom = 0; + private int mSubMonitorRangeTo = 100; + + private int mProgress = 0; + + // =========================================================== + // Constructors + // =========================================================== + + public ProgressMonitor(final IProgressListener pListener) { + this.mListener = pListener; + this.mParentProgressMonitor = null; + } + + public ProgressMonitor(final ProgressMonitor pParent){ + this.mListener = null; + this.mParentProgressMonitor = pParent; + } + + // =========================================================== + // Getter & Setter + // =========================================================== + + public ProgressMonitor getParentProgressMonitor() { + return this.mParentProgressMonitor; + } + + public int getProgress() { + return this.mProgress; + } + + public void setSubMonitorRange(final int pSubMonitorRangeFrom, final int pSubMonitorRangeTo) { + this.mSubMonitorRangeFrom = pSubMonitorRangeFrom; + this.mSubMonitorRangeTo = pSubMonitorRangeTo; + } + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + /** + * @param pProgress between 0 and 100. + */ + @Override + public void onProgressChanged(final int pProgress){ + this.mProgress = pProgress; + if(this.mParentProgressMonitor != null) { + this.mParentProgressMonitor.onSubProgressChanged(pProgress); + } else { + this.mListener.onProgressChanged(pProgress); + } + } + + private void onSubProgressChanged(final int pSubProgress){ + final int subRange = this.mSubMonitorRangeTo- this.mSubMonitorRangeFrom; + final int subProgressInRange = this.mSubMonitorRangeFrom + (int)(subRange * pSubProgress / 100f); + + if(this.mParentProgressMonitor != null) { + this.mParentProgressMonitor.onSubProgressChanged(subProgressInRange); + }else{ + this.mListener.onProgressChanged(subProgressInRange); + } + } +} diff --git a/AndEngine/src/org/anddev/andengine/util/sort/InsertionSorter.java b/AndEngine/src/org/anddev/andengine/util/sort/InsertionSorter.java new file mode 100644 index 0000000..8a93eeb --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/sort/InsertionSorter.java @@ -0,0 +1,71 @@ +package org.anddev.andengine.util.sort; + +import java.util.Comparator; +import java.util.List; + +/** + * @author Nicolas Gramlich + * @since 14:14:31 - 06.08.2010 + * @param + */ +public class InsertionSorter extends Sorter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + @Override + public void sort(final T[] pArray, final int pStart, final int pEnd, final Comparator pComparator) { + for(int i = pStart + 1; i < pEnd; i++) { + final T current = pArray[i]; + T prev = pArray[i - 1]; + if(pComparator.compare(current, prev) < 0) { + int j = i; + do { + pArray[j--] = prev; + } while(j > pStart && pComparator.compare(current, prev = pArray[j - 1]) < 0); + pArray[j] = current; + } + } + return; + } + + @Override + public void sort(final List pList, final int pStart, final int pEnd, final Comparator pComparator) { + for(int i = pStart + 1; i < pEnd; i++) { + final T current = pList.get(i); + T prev = pList.get(i - 1); + if(pComparator.compare(current, prev) < 0) { + int j = i; + do { + pList.set(j--, prev); + } while(j > pStart && pComparator.compare(current, prev = pList.get(j - 1)) < 0); + pList.set(j, current); + } + } + return; + } + + // =========================================================== + // Methods + // =========================================================== + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} \ No newline at end of file diff --git a/AndEngine/src/org/anddev/andengine/util/sort/Sorter.java b/AndEngine/src/org/anddev/andengine/util/sort/Sorter.java new file mode 100644 index 0000000..25a21bc --- /dev/null +++ b/AndEngine/src/org/anddev/andengine/util/sort/Sorter.java @@ -0,0 +1,51 @@ +package org.anddev.andengine.util.sort; + +import java.util.Comparator; +import java.util.List; + +/** + * @author Nicolas Gramlich + * @since 14:14:39 - 06.08.2010 + * @param + */ +public abstract class Sorter { + // =========================================================== + // Constants + // =========================================================== + + // =========================================================== + // Fields + // =========================================================== + + // =========================================================== + // Constructors + // =========================================================== + + // =========================================================== + // Getter & Setter + // =========================================================== + + // =========================================================== + // Methods for/from SuperClass/Interfaces + // =========================================================== + + public abstract void sort(final T[] pArray, final int pStart, final int pEnd, final Comparator pComparator); + + public abstract void sort(final List pList, final int pStart, final int pEnd, final Comparator pComparator); + + // =========================================================== + // Methods + // =========================================================== + + public final void sort(final T[] pArray, final Comparator pComparator){ + this.sort(pArray, 0, pArray.length, pComparator); + } + + public final void sort(final List pList, final Comparator pComparator){ + this.sort(pList, 0, pList.size(), pComparator); + } + + // =========================================================== + // Inner and Anonymous Classes + // =========================================================== +} diff --git a/AndEngine/uml/andengine_classdiagram.png b/AndEngine/uml/andengine_classdiagram.png new file mode 100644 index 0000000..7c9690a Binary files /dev/null and b/AndEngine/uml/andengine_classdiagram.png differ diff --git a/AndEngine/uml/andengine_classdiagram.ucls b/AndEngine/uml/andengine_classdiagram.ucls new file mode 100644 index 0000000..1b8bb9e --- /dev/null +++ b/AndEngine/uml/andengine_classdiagram.ucls @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file