* Formatting for many android classes which needed it desperately

* Moved JmeSystem.Platform to its own class in core. Desktop's and Android's JmeSystem now both use it
 * Moved proper usage of efficient data from AndroidSkyFactory to SkyFactory, deprecated AndroidSkyFactory

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8236 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..rd 13 years ago
parent 45d1a0e772
commit 5ac90f46fa
  1. 228
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 41
      engine/src/android/com/jme3/asset/AndroidAssetManager.java
  3. 159
      engine/src/android/com/jme3/system/JmeSystem.java
  4. 32
      engine/src/android/com/jme3/texture/plugins/AndroidImageLoader.java
  5. 56
      engine/src/android/com/jme3/util/RingBuffer.java
  6. 141
      engine/src/android/com/jme3/util/android/AndroidSkyFactory.java
  7. 55
      engine/src/android/jme3test/android/AboutActivity.java
  8. 203
      engine/src/android/jme3test/android/AndroidActivity.java
  9. 156
      engine/src/android/jme3test/android/SimpleTexturedTest.java
  10. 9
      engine/src/android/jme3test/android/Test.java
  11. 18
      engine/src/android/jme3test/android/TestSceneLoading.java
  12. 252
      engine/src/android/jme3test/android/TestsActivity.java
  13. 751
      engine/src/android/jme3tools/android/Fixed.java
  14. 8
      engine/src/android/res/layout/about.xml
  15. 9
      engine/src/android/res/layout/tests.xml
  16. 14
      engine/src/android/res/menu/options.xml
  17. 6
      engine/src/android/res/values/strings.xml
  18. 1
      engine/src/core/com/jme3/system/JmeContext.java
  19. 65
      engine/src/core/com/jme3/system/Platform.java
  20. 139
      engine/src/core/com/jme3/util/SkyFactory.java
  21. 35
      engine/src/desktop/com/jme3/system/JmeSystem.java

@ -1,6 +1,7 @@
package com.jme3.app; package com.jme3.app;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.logging.SimpleFormatter; import java.util.logging.SimpleFormatter;
import com.jme3.util.JmeFormatter; import com.jme3.util.JmeFormatter;
@ -28,41 +29,35 @@ import com.jme3.system.JmeSystem;
import com.jme3.system.android.OGLESContext; import com.jme3.system.android.OGLESContext;
import com.jme3.system.android.AndroidConfigChooser.ConfigType; import com.jme3.system.android.AndroidConfigChooser.ConfigType;
/** /**
* <code>AndroidHarness</code> wraps a jme application object and runs it on Android * <code>AndroidHarness</code> wraps a jme application object and runs it on Android
* @author Kirill * @author Kirill
* @author larynx * @author larynx
*/ */
public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener {
{
protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName()); protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());
/** /**
* The application class to start * The application class to start
*/ */
protected String appClass = "jme3test.android.Test"; protected String appClass = "jme3test.android.Test";
/** /**
* The jme3 application object * The jme3 application object
*/ */
protected Application app = null; protected Application app = null;
/** /**
* ConfigType.FASTEST is RGB565, GLSurfaceView default * ConfigType.FASTEST is RGB565, GLSurfaceView default
* ConfigType.BEST is RGBA8888 or better if supported by the hardware * ConfigType.BEST is RGBA8888 or better if supported by the hardware
*/ */
protected ConfigType eglConfigType = ConfigType.FASTEST; protected ConfigType eglConfigType = ConfigType.FASTEST;
/** /**
* If true all valid and not valid egl configs are logged * If true all valid and not valid egl configs are logged
*/ */
protected boolean eglConfigVerboseLogging = false; protected boolean eglConfigVerboseLogging = false;
/** /**
* If true MouseEvents are generated from TouchEvents * If true MouseEvents are generated from TouchEvents
*/ */
protected boolean mouseEventsEnabled = true; protected boolean mouseEventsEnabled = true;
/** /**
* Flip X axis * Flip X axis
*/ */
@ -71,7 +66,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
* Flip Y axis * Flip Y axis
*/ */
protected boolean mouseEventsInvertY = true; protected boolean mouseEventsInvertY = true;
/** /**
* Title of the exit dialog, default is "Do you want to exit?" * Title of the exit dialog, default is "Do you want to exit?"
*/ */
@ -80,7 +74,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
* Message of the exit dialog, default is "Use your home key to bring this app into the background or exit to terminate it." * Message of the exit dialog, default is "Use your home key to bring this app into the background or exit to terminate it."
*/ */
protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it."; protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it.";
/** /**
* Set the screen orientation, default is SENSOR * Set the screen orientation, default is SENSOR
* ActivityInfo.SCREEN_ORIENTATION_* constants * ActivityInfo.SCREEN_ORIENTATION_* constants
@ -95,31 +88,27 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
* SCREEN_ORIENTATION_NOSENSOR * SCREEN_ORIENTATION_NOSENSOR
*/ */
protected int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR; protected int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
protected OGLESContext ctx; protected OGLESContext ctx;
protected GLSurfaceView view = null; protected GLSurfaceView view = null;
protected boolean isGLThreadPaused = true; protected boolean isGLThreadPaused = true;
final private String ESCAPE_EVENT = "TouchEscape"; final private String ESCAPE_EVENT = "TouchEscape";
@Override @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState) {
{
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Logger log = logger; Logger log = logger;
boolean bIsLogFormatSet = false; boolean bIsLogFormatSet = false;
do do {
{ if (log.getHandlers().length == 0) {
if (log.getHandlers().length == 0)
{
log = logger.getParent(); log = logger.getParent();
if (log != null) if (log != null) {
for (Handler h : log.getHandlers()) for (Handler h : log.getHandlers()) {
{
//h.setFormatter(new SimpleFormatter()); //h.setFormatter(new SimpleFormatter());
h.setFormatter(new JmeFormatter()); h.setFormatter(new JmeFormatter());
bIsLogFormatSet = true; bIsLogFormatSet = true;
} }
}
} }
} while (log != null && !bIsLogFormatSet); } while (log != null && !bIsLogFormatSet);
@ -128,201 +117,172 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(screenOrientation); setRequestedOrientation(screenOrientation);
// Create Settings // Create Settings
AppSettings settings = new AppSettings(true); AppSettings settings = new AppSettings(true);
// Create the input class // Create the input class
AndroidInput input = new AndroidInput(this); AndroidInput input = new AndroidInput(this);
input.setMouseEventsInvertX(mouseEventsInvertX); input.setMouseEventsInvertX(mouseEventsInvertX);
input.setMouseEventsInvertY(mouseEventsInvertY); input.setMouseEventsInvertY(mouseEventsInvertY);
input.setMouseEventsEnabled(mouseEventsEnabled); input.setMouseEventsEnabled(mouseEventsEnabled);
// Create application instance // Create application instance
try try {
{ if (app == null) {
if (app == null)
{
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass); Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(appClass);
app = clazz.newInstance(); app = clazz.newInstance();
} }
app.setSettings(settings); app.setSettings(settings);
app.start(); app.start();
ctx = (OGLESContext) app.getContext(); ctx = (OGLESContext) app.getContext();
view = ctx.createView(input, eglConfigType, eglConfigVerboseLogging); view = ctx.createView(input, eglConfigType, eglConfigVerboseLogging);
setContentView(view); setContentView(view);
// Set the screen reolution // Set the screen reolution
WindowManager wind = this.getWindowManager(); WindowManager wind = this.getWindowManager();
Display disp = wind.getDefaultDisplay(); Display disp = wind.getDefaultDisplay();
ctx.getSettings().setResolution(disp.getWidth(), disp.getHeight()); ctx.getSettings().setResolution(disp.getWidth(), disp.getHeight());
AppSettings s = ctx.getSettings(); AppSettings s = ctx.getSettings();
logger.info("Settings: Width " + s.getWidth() + " Height " + s.getHeight()); logger.log(Level.INFO, "Settings: Width {0} Height {1}", new Object[]{s.getWidth(), s.getHeight()});
} catch (Exception ex) {
}
catch (Exception ex)
{
handleError("Class " + appClass + " init failed", ex); handleError("Class " + appClass + " init failed", ex);
setContentView(new TextView(this)); setContentView(new TextView(this));
} }
} }
@Override @Override
protected void onRestart() protected void onRestart() {
{ super.onRestart();
super.onRestart(); if (app != null) {
if (app != null)
app.restart(); app.restart();
}
logger.info("onRestart"); logger.info("onRestart");
} }
@Override @Override
protected void onStart() protected void onStart() {
{
super.onStart(); super.onStart();
logger.info("onStart"); logger.info("onStart");
} }
@Override @Override
protected void onResume() protected void onResume() {
{
super.onResume(); super.onResume();
if (view != null) if (view != null) {
view.onResume(); view.onResume();
}
isGLThreadPaused = false; isGLThreadPaused = false;
logger.info("onResume"); logger.info("onResume");
} }
@Override @Override
protected void onPause() protected void onPause() {
{
super.onPause(); super.onPause();
if (view != null) if (view != null) {
view.onPause(); view.onPause();
}
isGLThreadPaused = true; isGLThreadPaused = true;
logger.info("onPause"); logger.info("onPause");
} }
@Override @Override
protected void onStop() protected void onStop() {
{
super.onStop(); super.onStop();
logger.info("onStop"); logger.info("onStop");
} }
@Override @Override
protected void onDestroy() protected void onDestroy() {
{ if (app != null) {
if (app != null) app.stop(!isGLThreadPaused);
app.stop(! isGLThreadPaused); }
super.onDestroy(); super.onDestroy();
logger.info("onDestroy"); logger.info("onDestroy");
} }
public Application getJmeApplication() public Application getJmeApplication() {
{
return app; return app;
} }
/** /**
* Called when an error has occured. This is typically * Called when an error has occured. This is typically
* invoked when an uncought exception is thrown in the render thread. * invoked when an uncaught exception is thrown in the render thread.
* @param errorMsg The error message, if any, or null. * @param errorMsg The error message, if any, or null.
* @param t Throwable object, or null. * @param t Throwable object, or null.
*/ */
public void handleError(final String errorMsg, final Throwable t) public void handleError(final String errorMsg, final Throwable t) {
{ String sTrace = "";
if (t != null && t.getStackTrace() != null) {
String s = ""; for (StackTraceElement ste : t.getStackTrace()) {
if (t != null && t.getStackTrace() != null) sTrace += "\tat " + ste.getClassName() + "." + ste.getMethodName() + "(";
{ if (ste.isNativeMethod()){
for (StackTraceElement ste: t.getStackTrace()) sTrace += "Native";
{ }else{
s += ste.getClassName() + "." + ste.getMethodName() + "(" + + ste.getLineNumber() + ") "; sTrace += ste.getLineNumber();
}
sTrace += ")\n";
} }
} }
final String sTrace = s; final String stackTrace = sTrace;
logger.severe(t != null ? t.toString() : "OpenGL Exception"); logger.log(Level.SEVERE, t != null ? t.toString() : "OpenGL Exception");
logger.severe((errorMsg != null ? errorMsg + ": " : "") + sTrace); logger.log(Level.SEVERE, "{0}{1}", new Object[]{errorMsg != null ? errorMsg + ": " : "", stackTrace});
this.runOnUiThread(new Runnable() { this.runOnUiThread(new Runnable() {
@Override @Override
public void run() public void run() {
{ AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) // .setIcon(R.drawable.alert_dialog_icon)
AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) .setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "OpenGL Exception").setPositiveButton("Kill", AndroidHarness.this).setMessage((errorMsg != null ? errorMsg + ": " : "") + stackTrace).create();
// .setIcon(R.drawable.alert_dialog_icon) dialog.show();
.setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "OpenGL Exception")
.setPositiveButton("Kill", AndroidHarness.this)
.setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
.create();
dialog.show();
} }
}); });
} }
/** /**
* Called by the android alert dialog, terminate the activity and OpenGL rendering * Called by the android alert dialog, terminate the activity and OpenGL rendering
* @param dialog * @param dialog
* @param whichButton * @param whichButton
*/ */
public void onClick(DialogInterface dialog, int whichButton) public void onClick(DialogInterface dialog, int whichButton) {
{ if (whichButton != -2) {
if (whichButton != -2) if (app != null) {
{
if (app != null)
app.stop(true); app.stop(true);
}
this.finish(); this.finish();
} }
} }
/** /**
* Gets called by the InputManager on all touch/drag/scale events * Gets called by the InputManager on all touch/drag/scale events
*/ */
@Override @Override
public void onTouch(String name, TouchEvent evt, float tpf) public void onTouch(String name, TouchEvent evt, float tpf) {
{ if (name.equals(ESCAPE_EVENT)) {
if (name.equals(ESCAPE_EVENT)) switch (evt.getType()) {
{
switch(evt.getType())
{
case KEY_UP: case KEY_UP:
this.runOnUiThread(new Runnable() this.runOnUiThread(new Runnable() {
{
@Override @Override
public void run() public void run() {
{ AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) // .setIcon(R.drawable.alert_dialog_icon)
AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this) .setTitle(exitDialogTitle).setPositiveButton("Yes", AndroidHarness.this).setNegativeButton("No", AndroidHarness.this).setMessage(exitDialogMessage).create();
// .setIcon(R.drawable.alert_dialog_icon) dialog.show();
.setTitle(exitDialogTitle)
.setPositiveButton("Yes", AndroidHarness.this)
.setNegativeButton("No", AndroidHarness.this)
.setMessage(exitDialogMessage)
.create();
dialog.show();
} }
}); });
break;
default:
break; break;
default:
break;
} }
} }
} }
} }

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.asset; package com.jme3.asset;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
@ -50,14 +49,14 @@ public class AndroidAssetManager extends DesktopAssetManager {
private static final Logger logger = Logger.getLogger(AndroidAssetManager.class.getName()); private static final Logger logger = Logger.getLogger(AndroidAssetManager.class.getName());
public AndroidAssetManager(){ public AndroidAssetManager() {
this(null); this(null);
} }
@Deprecated @Deprecated
public AndroidAssetManager(boolean loadDefaults){ public AndroidAssetManager(boolean loadDefaults) {
//this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Android.cfg")); //this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Android.cfg"));
this(null); this(null);
} }
/** /**
@ -65,14 +64,13 @@ public class AndroidAssetManager extends DesktopAssetManager {
* If URL == null then a default list of locators and loaders for android is set * If URL == null then a default list of locators and loaders for android is set
* @param configFile * @param configFile
*/ */
public AndroidAssetManager(URL configFile) public AndroidAssetManager(URL configFile) {
{
System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver");
System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
// Set Default Android config
// Set Default Android config this.registerLocator("", AndroidLocator.class);
this.registerLocator("", AndroidLocator.class);
this.registerLocator("", ClasspathLocator.class); this.registerLocator("", ClasspathLocator.class);
this.registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg"); this.registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg");
this.registerLoader(AndroidAudioLoader.class, "ogg", "mp3"); this.registerLoader(AndroidAudioLoader.class, "ogg", "mp3");
@ -91,8 +89,8 @@ public class AndroidAssetManager extends DesktopAssetManager {
this.registerLoader(com.jme3.scene.plugins.ogre.MaterialLoader.class, "material"); this.registerLoader(com.jme3.scene.plugins.ogre.MaterialLoader.class, "material");
this.registerLoader(com.jme3.scene.plugins.ogre.SceneLoader.class, "scene"); this.registerLoader(com.jme3.scene.plugins.ogre.SceneLoader.class, "scene");
this.registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib"); this.registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib");
logger.info("AndroidAssetManager created."); logger.info("AndroidAssetManager created.");
} }
@ -102,18 +100,17 @@ public class AndroidAssetManager extends DesktopAssetManager {
* @return * @return
*/ */
@Override @Override
public Texture loadTexture(TextureKey key){ public Texture loadTexture(TextureKey key) {
Texture tex = (Texture) loadAsset(key); Texture tex = (Texture) loadAsset(key);
// Needed for Android // Needed for Android
tex.setMagFilter(Texture.MagFilter.Nearest); tex.setMagFilter(Texture.MagFilter.Nearest);
tex.setAnisotropicFilter(0); tex.setAnisotropicFilter(0);
if (tex.getMinFilter().usesMipMapLevels()){ if (tex.getMinFilter().usesMipMapLevels()) {
tex.setMinFilter(Texture.MinFilter.NearestNearestMipMap); tex.setMinFilter(Texture.MinFilter.NearestNearestMipMap);
}else{ } else {
tex.setMinFilter(Texture.MinFilter.NearestNoMipMaps); tex.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
} }
return tex; return tex;
} }
} }

@ -1,6 +1,5 @@
package com.jme3.system; package com.jme3.system;
import android.app.Activity; import android.app.Activity;
import android.content.res.Resources; import android.content.res.Resources;
import com.jme3.util.AndroidLogHandler; import com.jme3.util.AndroidLogHandler;
@ -24,172 +23,96 @@ import java.util.logging.Logger;
import java.net.URL; import java.net.URL;
public class JmeSystem {
public class JmeSystem
{
public static enum Platform {
/**
* Microsoft Windows 32 bit
*/
Windows32,
/**
* Microsoft Windows 64 bit
*/
Windows64,
/**
* Linux 32 bit
*/
Linux32,
/**
* Linux 64 bit
*/
Linux64,
/**
* Apple Mac OS X 32 bit
*/
MacOSX32,
/**
* Apple Mac OS X 64 bit
*/
MacOSX64,
/**
* Apple Mac OS X 32 bit PowerPC
*/
MacOSX_PPC32,
/**
* Apple Mac OS X 64 bit PowerPC
*/
MacOSX_PPC64,
/**
* Android 2.2
*/
Android_Froyo,
/**
* Android 2.3
*/
Android_Gingerbread,
/**
* Android 3.0
*/
Android_Honeycomb,
}
private static final Logger logger = Logger.getLogger(JmeSystem.class.getName()); private static final Logger logger = Logger.getLogger(JmeSystem.class.getName());
private static boolean initialized = false; private static boolean initialized = false;
private static boolean lowPermissions = false; private static boolean lowPermissions = false;
private static Resources res; private static Resources res;
private static Activity activity; private static Activity activity;
public static void initialize(AppSettings settings) public static void initialize(AppSettings settings) {
{ if (initialized) {
if (initialized)
return; return;
}
initialized = true; initialized = true;
try try {
{
JmeFormatter formatter = new JmeFormatter(); JmeFormatter formatter = new JmeFormatter();
Handler consoleHandler = new AndroidLogHandler(); Handler consoleHandler = new AndroidLogHandler();
consoleHandler.setFormatter(formatter); consoleHandler.setFormatter(formatter);
} } catch (SecurityException ex) {
catch (SecurityException ex)
{
logger.log(Level.SEVERE, "Security error in creating log file", ex); logger.log(Level.SEVERE, "Security error in creating log file", ex);
} }
logger.info("Running on "+getFullName()); logger.log(Level.INFO, "Running on {0}", getFullName());
} }
public static String getFullName() public static String getFullName() {
{ return "jMonkeyEngine 3.0.0 Beta (Android)";
return "jMonkey Engine 3 ALPHA 0.7 Android";
} }
public static void setLowPermissions(boolean lowPerm) public static void setLowPermissions(boolean lowPerm) {
{
lowPermissions = lowPerm; lowPermissions = lowPerm;
} }
public static boolean isLowPermissions() public static boolean isLowPermissions() {
{
return lowPermissions; return lowPermissions;
} }
public static JmeContext newContext(AppSettings settings, Type contextType) public static JmeContext newContext(AppSettings settings, Type contextType) {
{
initialize(settings); initialize(settings);
return new OGLESContext(); return new OGLESContext();
} }
public static AudioRenderer newAudioRenderer(AppSettings settings) public static AudioRenderer newAudioRenderer(AppSettings settings) {
{ return new AndroidAudioRenderer(activity);
return new AndroidAudioRenderer(activity);
} }
public static void setResources(Resources res) public static void setResources(Resources res) {
{
JmeSystem.res = res; JmeSystem.res = res;
} }
public static Resources getResources() public static Resources getResources() {
{
return res; return res;
} }
public static void setActivity(Activity activity) public static void setActivity(Activity activity) {
{
JmeSystem.activity = activity; JmeSystem.activity = activity;
} }
public static Activity getActivity() public static Activity getActivity() {
{
return activity; return activity;
} }
public static AssetManager newAssetManager() public static AssetManager newAssetManager() {
{ logger.log(Level.INFO, "newAssetManager()");
logger.info("newAssetManager()");
return new AndroidAssetManager(null); return new AndroidAssetManager(null);
} }
public static AssetManager newAssetManager(URL url) public static AssetManager newAssetManager(URL url) {
{ logger.log(Level.INFO, "newAssetManager({0})", url);
logger.info("newAssetManager(" + url + ")");
return new AndroidAssetManager(url); return new AndroidAssetManager(url);
} }
public static boolean showSettingsDialog(AppSettings settings, boolean loadSettings) public static boolean showSettingsDialog(AppSettings settings, boolean loadSettings) {
{
return true; return true;
} }
public static Platform getPlatform()
{
String os = System.getProperty("os.name").toLowerCase();
String arch = System.getProperty("os.arch").toLowerCase();
return Platform.Android_Froyo; public static Platform getPlatform() {
// throw new UnsupportedOperationException("The specified platform: "+os+" is not supported."); String arch = System.getProperty("os.arch").toLowerCase();
if (arch.contains("arm")){
if (arch.contains("v5")){
return Platform.Android_ARM5;
}else if (arch.contains("v6")){
return Platform.Android_ARM6;
}else if (arch.contains("v7")){
return Platform.Android_ARM7;
}else{
return Platform.Android_ARM5; // unknown ARM
}
}else{
throw new UnsupportedOperationException("Unsupported Android Platform");
}
} }
} }

@ -14,37 +14,35 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class AndroidImageLoader implements AssetLoader public class AndroidImageLoader implements AssetLoader {
{
public Object load2(AssetInfo info) throws IOException public Object load2(AssetInfo info) throws IOException {
{
ByteBuffer bb = BufferUtils.createByteBuffer(1 * 1 * 2); ByteBuffer bb = BufferUtils.createByteBuffer(1 * 1 * 2);
bb.put( (byte) 0xff ).put( (byte) 0xff ); bb.put((byte) 0xff).put((byte) 0xff);
bb.clear(); bb.clear();
return new Image(Format.RGB5A1, 1, 1, bb); return new Image(Format.RGB5A1, 1, 1, bb);
} }
public Object load(AssetInfo info) throws IOException public Object load(AssetInfo info) throws IOException {
{
InputStream in = null; InputStream in = null;
Bitmap bitmap = null; Bitmap bitmap = null;
try { try {
in = info.openStream(); in = info.openStream();
bitmap = BitmapFactory.decodeStream(in); bitmap = BitmapFactory.decodeStream(in);
if (bitmap == null){ if (bitmap == null) {
throw new IOException("Failed to load image: "+info.getKey().getName()); throw new IOException("Failed to load image: " + info.getKey().getName());
} }
} finally { } finally {
if (in != null) if (in != null) {
in.close(); in.close();
}
} }
int width = bitmap.getWidth(); int width = bitmap.getWidth();
int height = bitmap.getHeight(); int height = bitmap.getHeight();
Format fmt; Format fmt;
switch (bitmap.getConfig()){ switch (bitmap.getConfig()) {
case ALPHA_8: case ALPHA_8:
fmt = Format.Alpha8; fmt = Format.Alpha8;
break; break;
@ -54,15 +52,14 @@ public class AndroidImageLoader implements AssetLoader
case ARGB_8888: case ARGB_8888:
fmt = Format.RGBA8; fmt = Format.RGBA8;
break; break;
case RGB_565: case RGB_565:
fmt = Format.RGB565; fmt = Format.RGB565;
break; break;
default: default:
return null; return null;
} }
if ( ((TextureKey)info.getKey()).isFlipY() ) if (((TextureKey) info.getKey()).isFlipY()) {
{
Bitmap newBitmap = null; Bitmap newBitmap = null;
Matrix flipMat = new Matrix(); Matrix flipMat = new Matrix();
flipMat.preScale(1.0f, -1.0f); flipMat.preScale(1.0f, -1.0f);
@ -70,14 +67,13 @@ public class AndroidImageLoader implements AssetLoader
bitmap.recycle(); bitmap.recycle();
bitmap = newBitmap; bitmap = newBitmap;
if (bitmap == null){ if (bitmap == null) {
throw new IOException("Failed to flip image: "+info.getKey().getName()); throw new IOException("Failed to flip image: " + info.getKey().getName());
} }
} }
Image image = new Image(fmt, width, height, null); Image image = new Image(fmt, width, height, null);
image.setEfficentData(bitmap); image.setEfficentData(bitmap);
return image; return image;
} }
} }

@ -8,33 +8,39 @@ import java.util.NoSuchElementException;
*/ */
// suppress unchecked warnings in Java 1.5.0_6 and later // suppress unchecked warnings in Java 1.5.0_6 and later
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class RingBuffer<Item> implements Iterable<Item> public class RingBuffer<Item> implements Iterable<Item> {
{
private Item[] buffer; // queue elements private Item[] buffer; // queue elements
private int count = 0; // number of elements on queue private int count = 0; // number of elements on queue
private int indexOut = 0; // index of first element of queue private int indexOut = 0; // index of first element of queue
private int indexIn = 0; // index of next available slot private int indexIn = 0; // index of next available slot
// cast needed since no generic array creation in Java // cast needed since no generic array creation in Java
public RingBuffer(int capacity) public RingBuffer(int capacity) {
{
buffer = (Item[]) new Object[capacity]; buffer = (Item[]) new Object[capacity];
} }
public boolean isEmpty() { return count == 0; } public boolean isEmpty() {
public int size() { return count; } return count == 0;
}
public void push(Item item) public int size() {
{ return count;
if (count == buffer.length) { throw new RuntimeException("Ring buffer overflow"); } }
public void push(Item item) {
if (count == buffer.length) {
throw new RuntimeException("Ring buffer overflow");
}
buffer[indexIn] = item; buffer[indexIn] = item;
indexIn = (indexIn + 1) % buffer.length; // wrap-around indexIn = (indexIn + 1) % buffer.length; // wrap-around
count++; count++;
} }
public Item pop() public Item pop() {
{ if (isEmpty()) {
if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); } throw new RuntimeException("Ring buffer underflow");
}
Item item = buffer[indexOut]; Item item = buffer[indexOut];
buffer[indexOut] = null; // to help with garbage collection buffer[indexOut] = null; // to help with garbage collection
count--; count--;
@ -42,22 +48,28 @@ public class RingBuffer<Item> implements Iterable<Item>
return item; return item;
} }
public Iterator<Item> iterator() { return new RingBufferIterator(); } public Iterator<Item> iterator() {
return new RingBufferIterator();
}
// an iterator, doesn't implement remove() since it's optional // an iterator, doesn't implement remove() since it's optional
private class RingBufferIterator implements Iterator<Item> { private class RingBufferIterator implements Iterator<Item> {
private int i = 0; private int i = 0;
public boolean hasNext() { return i < count; }
public void remove() { throw new UnsupportedOperationException(); } public boolean hasNext() {
return i < count;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() { public Item next() {
if (!hasNext()) throw new NoSuchElementException(); if (!hasNext()) {
throw new NoSuchElementException();
}
return buffer[i++]; return buffer[i++];
} }
} }
} }

@ -1,148 +1,39 @@
package com.jme3.util.android; package com.jme3.util.android;
import java.util.ArrayList;
import android.graphics.Bitmap;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.asset.TextureKey;
import com.jme3.material.Material;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Sphere;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.texture.TextureCubeMap; import com.jme3.util.SkyFactory;
/** /**
* <code>AndroidSkyFactory</code> creates a sky box spatial * <code>AndroidSkyFactory</code> creates a sky box spatial
* @author larynx, derived from SkyFactory and adapted for android * @author larynx, derived from SkyFactory and adapted for android
* * @deprecated Use {@link SkyFactory} instead
*/ */
public class AndroidSkyFactory @Deprecated
{ public class AndroidSkyFactory {
private static final Sphere sphereMesh = new Sphere(10, 10, 101f, false, true);
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap)
{
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setVector3("NormalScale", normalScale);
if (sphereMap)
{
skyMat.setBoolean("SphereMap", sphereMap);
}
else if (!(texture instanceof TextureCubeMap))
{
// make sure its a cubemap
Image img = texture.getImage();
texture = new TextureCubeMap();
texture.setImage(img);
}
skyMat.setTexture("Texture", texture);
sky.setMaterial(skyMat);
return sky;
}
private static void checkImage(Image image)
{
if (image.getWidth() != image.getHeight())
throw new IllegalArgumentException("Image width and height must be the same");
if (image.getMultiSamples() != 1)
throw new IllegalArgumentException("Multisample textures not allowed");
}
private static void checkImagesForCubeMap(Image ... images)
{
if (images.length == 1) return;
Format fmt = images[0].getFormat();
int width = images[0].getWidth();
int height = images[0].getHeight();
checkImage(images[0]); public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap) {
return SkyFactory.createSky(assetManager, texture, normalScale, sphereMap);
for (int i = 1; i < images.length; i++)
{
Image image = images[i];
checkImage(images[i]);
if (image.getFormat() != fmt) throw new IllegalArgumentException("Images must have same format");
if (image.getWidth() != width) throw new IllegalArgumentException("Images must have same width");
if (image.getHeight() != height) throw new IllegalArgumentException("Images must have same height");
}
} }
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south,
Texture up, Texture down, Vector3f normalScale) Texture up, Texture down, Vector3f normalScale) {
{ return SkyFactory.createSky(assetManager, west, east, north, south, up, down, normalScale);
Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never);
Image westImg = west.getImage();
Image eastImg = east.getImage();
Image northImg = north.getImage();
Image southImg = south.getImage();
Image upImg = up.getImage();
Image downImg = down.getImage();
checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);
Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);
ArrayList<Bitmap> arrayList = new ArrayList<Bitmap>(6);
arrayList.add((Bitmap)westImg.getEfficentData());
arrayList.add((Bitmap)eastImg.getEfficentData());
arrayList.add((Bitmap)downImg.getEfficentData());
arrayList.add((Bitmap)upImg.getEfficentData());
arrayList.add((Bitmap)southImg.getEfficentData());
arrayList.add((Bitmap)northImg.getEfficentData());
cubeImage.setEfficentData(arrayList);
TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
cubeMap.setAnisotropicFilter(0);
cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
cubeMap.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setTexture("Texture", cubeMap);
skyMat.setVector3("NormalScale", normalScale);
sky.setMaterial(skyMat);
return sky;
} }
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south,
Texture up, Texture down) Texture up, Texture down) {
{ return SkyFactory.createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
} }
public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap) public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap) {
{ return SkyFactory.createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
} }
public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap) public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap) {
{ return SkyFactory.createSky(assetManager, textureName, sphereMap);
TextureKey key = new TextureKey(textureName, true);
key.setGenerateMips(true);
key.setAsCube(!sphereMap);
Texture tex = assetManager.loadTexture(key);
return createSky(assetManager, tex, sphereMap);
} }
} }

@ -1,6 +1,5 @@
package jme3test.android; package jme3test.android;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -30,43 +29,37 @@ import jme3test.android.AndroidActivity;
import java.net.URI; import java.net.URI;
public class AboutActivity extends Activity { public class AboutActivity extends Activity {
private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(AboutActivity.class.getName()); private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(AboutActivity.class.getName());
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
logger.info("onCreate(" + savedInstanceState + ")"); logger.info("onCreate(" + savedInstanceState + ")");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
//setContentView(R.layout.about); //setContentView(R.layout.about);
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
logger.info("onDestroy()"); logger.info("onDestroy()");
super.onDestroy(); super.onDestroy();
} }
@Override
protected void onResume() {
super.onResume();
}
@Override @Override
protected void onResume() { protected void onStart() {
super.onResume(); super.onStart();
} }
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onStop() {
super.onStop();
}
} }

@ -6,7 +6,6 @@
* *
* created: Mon Nov 8 00:08:07 EST 2010 * created: Mon Nov 8 00:08:07 EST 2010
*/ */
package jme3test.android; package jme3test.android;
import android.app.Activity; import android.app.Activity;
@ -23,136 +22,128 @@ import com.jme3.system.android.OGLESContext;
import com.jme3.app.Application; import com.jme3.app.Application;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
public class AndroidActivity extends Activity { public class AndroidActivity extends Activity {
private final static java.util.logging.Logger logger = java.util.logging.Logger.getLogger(AndroidActivity.class.getName()); private final static java.util.logging.Logger logger = java.util.logging.Logger.getLogger(AndroidActivity.class.getName());
private OGLESContext ctx;
private GLSurfaceView view;
private boolean useVA = false;
private boolean verboseLogging = false;
@Override
public void onCreate(Bundle savedInstanceState) {
private OGLESContext ctx; super.onCreate(savedInstanceState);
private GLSurfaceView view;
private boolean useVA = false; JmeSystem.setResources(getResources());
private boolean verboseLogging = false;
@Override requestWindowFeature(Window.FEATURE_NO_TITLE);
public void onCreate(Bundle savedInstanceState) { getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState); AppSettings settings = new AppSettings(true);
JmeSystem.setResources(getResources()); String testClassName = getIntent().getStringExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME");
requestWindowFeature(Window.FEATURE_NO_TITLE); logger.info("test class name: [" + testClassName + "]");
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
AppSettings settings = new AppSettings(true); String appClass = (testClassName != null ? testClassName : "jme3test.android.SimpleTexturedTest");
String testClassName = getIntent().getStringExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME"); useVA = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".USE_VA", false);
logger.info("test class name: [" + testClassName + "]"); logger.info("USE_VA -> [" + useVA + "]");
String appClass = (testClassName != null? testClassName: "jme3test.android.SimpleTexturedTest"); settings.putBoolean("USE_VA", useVA);
useVA = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".USE_VA", false); verboseLogging = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".VERBOSE_LOGGING", false);
logger.info("USE_VA -> [" + useVA + "]"); settings.putBoolean("VERBOSE_LOGGING", verboseLogging);
settings.putBoolean("USE_VA", useVA); Application app = null;
verboseLogging = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".VERBOSE_LOGGING", false); try {
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(
appClass);
settings.putBoolean("VERBOSE_LOGGING", verboseLogging); app = clazz.newInstance();
/*
app = (Application) java.lang.reflect.Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class[] {Class.forName(appClass)},
new java.lang.reflect.InvocationHandler() {
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
if (
method.getName().equals("loadFPSText") ||
method.getName().equals("loadStatsView")
) {
logger.info("ignoring method: [" + method + "]");
return null;
}
return method.invoke(proxy, args);
}
}
);
*/
Application app = null;
try { if (app instanceof SimpleApplication) {
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName( ((SimpleApplication) app).setShowSettings(false);
appClass }
);
app = clazz.newInstance(); logger.info("setting settings ...");
/* app.setSettings(settings);
app = (Application) java.lang.reflect.Proxy.newProxyInstance( logger.info("setting settings ... done.");
this.getClass().getClassLoader(),
new Class[] {Class.forName(appClass)}, logger.info("starting app ...");
app.start();
new java.lang.reflect.InvocationHandler() { logger.info("starting app ... done.");
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
if ( if (app instanceof SimpleApplication) {
method.getName().equals("loadFPSText") || ((SimpleApplication) app).getGuiNode().detachAllChildren();
method.getName().equals("loadStatsView") }
) {
logger.info("ignoring method: [" + method + "]"); logger.info("creating context ...");
return null; ctx = (OGLESContext) app.getContext();
} logger.info("creating context ... done.");
return method.invoke(proxy, args); ctx.setSettings(settings);
}
} logger.info("creating view ...");
); view = ctx.createView(this);
*/ logger.info("creating view ... done.");
if (app instanceof SimpleApplication) {
((SimpleApplication) app).setShowSettings(false);
}
logger.info("setting settings ...");
app.setSettings(settings);
logger.info("setting settings ... done.");
logger.info("starting app ...");
app.start();
logger.info("starting app ... done.");
if (app instanceof SimpleApplication)
((SimpleApplication) app).getGuiNode().detachAllChildren();
logger.info("creating context ...");
ctx = (OGLESContext) app.getContext();
logger.info("creating context ... done.");
ctx.setSettings(settings);
logger.info("creating view ...");
view = ctx.createView(this);
logger.info("creating view ... done.");
logger.info("setting content view ...");
setContentView(view);
logger.info("setting content done ...");
} catch (Throwable exception) {
logger.warning("exception: " + exception);
exception.printStackTrace(System.err);
}
}
@Override
protected void onResume() {
logger.info("onResume ...");
super.onResume();
logger.info("view.onResume ...");
view.onResume();
logger.info("view.onResume ... done.");
logger.info("onResume ... done.");
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
}
logger.info("setting content view ...");
setContentView(view);
logger.info("setting content done ...");
} catch (Throwable exception) {
logger.warning("exception: " + exception);
exception.printStackTrace(System.err);
}
}
@Override
protected void onResume() {
logger.info("onResume ...");
super.onResume();
logger.info("view.onResume ...");
view.onResume();
logger.info("view.onResume ... done.");
logger.info("onResume ... done.");
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
}
// @Override // @Override
// protected void onDestroy(){ // protected void onDestroy(){
// super.onDestroy(); // super.onDestroy();
// Debug.stopMethodTracing(); // Debug.stopMethodTracing();
// } // }
} }

@ -4,10 +4,8 @@
* *
* created: Mon Nov 8 00:08:22 EST 2010 * created: Mon Nov 8 00:08:22 EST 2010
*/ */
package jme3test.android; package jme3test.android;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
@ -35,101 +33,95 @@ import com.jme3.util.TangentBinormalGenerator;
import jme3tools.converters.model.ModelConverter; import jme3tools.converters.model.ModelConverter;
public class SimpleTexturedTest extends SimpleApplication { public class SimpleTexturedTest extends SimpleApplication {
private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(SimpleTexturedTest.class.getName()); private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(SimpleTexturedTest.class.getName());
private Node spheresContainer = new Node("spheres-container");
private boolean lightingEnabled = true;
private Node spheresContainer = new Node("spheres-container"); private boolean texturedEnabled = true;
private boolean spheres = true;
private boolean lightingEnabled = true; @Override
private boolean texturedEnabled = true; public void simpleInitApp() {
private boolean spheres = true;
/*
@Override * GUI rendering is broken on Android right now and prevents the main view from rendering.
public void simpleInitApp() { * Detaching all children lets the main view to be rendered.
*/
/*
* GUI rendering is broken on Android right now and prevents the main view from rendering. guiNode.detachAllChildren();
* Detaching all children lets the main view to be rendered.
*/ Mesh shape = null;
guiNode.detachAllChildren(); if (spheres) {
shape = new Sphere(16, 16, .5f);
} else {
shape = new Box(Vector3f.ZERO, 0.3f, 0.3f, 0.3f);
}
// ModelConverter.optimize(geom);
Texture texture = assetManager.loadTexture(new TextureKey("icons/textured.png"));
Material material = null;
if (texturedEnabled) {
if (lightingEnabled) {
material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
material.setBoolean("VertexLighting", true);
material.setFloat("Shininess", 127);
material.setBoolean("LowQuality", true);
material.setTexture("DiffuseMap", texture);
} else {
material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", texture);
}
} else {
material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", ColorRGBA.Red);
}
TangentBinormalGenerator.generate(shape);
for (int y = -1; y < 2; y++) {
for (int x = -1; x < 2; x++) {
// int x = 0;
// int y = 0;
Geometry geomClone = new Geometry("geometry-" + y + "-" + x, shape);
geomClone.setMaterial(material);
geomClone.setLocalTranslation(x, y, 0);
Mesh shape = null;
if (spheres) {
shape = new Sphere(16, 16, .5f);
} else {
shape = new Box(Vector3f.ZERO, 0.3f, 0.3f, 0.3f);
}
// ModelConverter.optimize(geom);
Texture texture = assetManager.loadTexture(new TextureKey("icons/textured.png"));
Material material = null;
if (texturedEnabled) {
if (lightingEnabled) {
material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
material.setBoolean("VertexLighting", true);
material.setFloat("Shininess", 127);
material.setBoolean("LowQuality", true);
material.setTexture("DiffuseMap", texture);
} else {
material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setTexture("ColorMap", texture);
}
} else {
material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", ColorRGBA.Red);
}
TangentBinormalGenerator.generate(shape);
for (int y = -1; y < 2; y++) {
for (int x = -1; x < 2; x++){
// int x = 0;
// int y = 0;
Geometry geomClone = new Geometry("geometry-" + y + "-" + x, shape);
geomClone.setMaterial(material);
geomClone.setLocalTranslation(x, y, 0);
// Transform t = geom.getLocalTransform().clone(); // Transform t = geom.getLocalTransform().clone();
// Transform t2 = geomClone.getLocalTransform().clone(); // Transform t2 = geomClone.getLocalTransform().clone();
// t.combineWithParent(t2); // t.combineWithParent(t2);
// geomClone.setLocalTransform(t); // geomClone.setLocalTransform(t);
spheresContainer.attachChild(geomClone); spheresContainer.attachChild(geomClone);
} }
} }
spheresContainer.setLocalTranslation(new Vector3f(0, 0, -4f)); spheresContainer.setLocalTranslation(new Vector3f(0, 0, -4f));
spheresContainer.setLocalScale(2.0f); spheresContainer.setLocalScale(2.0f);
rootNode.attachChild(spheresContainer); rootNode.attachChild(spheresContainer);
PointLight pointLight = new PointLight(); PointLight pointLight = new PointLight();
pointLight.setColor(new ColorRGBA(0.7f, 0.7f, 1.0f, 1.0f)); pointLight.setColor(new ColorRGBA(0.7f, 0.7f, 1.0f, 1.0f));
pointLight.setPosition(new Vector3f(0f, 0f, 0f)); pointLight.setPosition(new Vector3f(0f, 0f, 0f));
pointLight.setRadius(8); pointLight.setRadius(8);
rootNode.addLight(pointLight); rootNode.addLight(pointLight);
} }
@Override @Override
public void simpleUpdate(float tpf) { public void simpleUpdate(float tpf) {
if (secondCounter == 0) if (secondCounter == 0) {
logger.info("Frames per second: " + timer.getFrameRate()); logger.info("Frames per second: " + timer.getFrameRate());
}
spheresContainer.rotate(0.2f * tpf, 0.4f * tpf, 0.8f * tpf);
}
spheresContainer.rotate(0.2f * tpf, 0.4f * tpf, 0.8f * tpf);
}
} }

@ -15,19 +15,19 @@ public class Test extends SimpleApplication {
public void simpleInitApp() { public void simpleInitApp() {
Sphere s = new Sphere(8, 8, .5f); Sphere s = new Sphere(8, 8, .5f);
Geometry geom = new Geometry("sphere", s); Geometry geom = new Geometry("sphere", s);
// ModelConverter.optimize(geom); // ModelConverter.optimize(geom);
Material mat = new Material(assetManager, "plain_texture.j3md"); Material mat = new Material(assetManager, "plain_texture.j3md");
Texture tex = assetManager.loadTexture(new TextureKey("monkey.j3i")); Texture tex = assetManager.loadTexture(new TextureKey("monkey.j3i"));
mat.setTexture("ColorMap", tex); mat.setTexture("ColorMap", tex);
// geom.setMaterial(mat); // geom.setMaterial(mat);
for (int y = -1; y < 2; y++){ for (int y = -1; y < 2; y++) {
for (int x = -1; x < 2; x++){ for (int x = -1; x < 2; x++) {
Geometry geomClone = new Geometry("geom", s); Geometry geomClone = new Geometry("geom", s);
geomClone.setMaterial(mat); geomClone.setMaterial(mat);
geomClone.setLocalTranslation(x, y, 0); geomClone.setLocalTranslation(x, y, 0);
Transform t = geom.getLocalTransform().clone(); Transform t = geom.getLocalTransform().clone();
Transform t2 = geomClone.getLocalTransform().clone(); Transform t2 = geomClone.getLocalTransform().clone();
t.combineWithParent(t2); t.combineWithParent(t2);
@ -37,5 +37,4 @@ public class Test extends SimpleApplication {
} }
} }
} }
} }

@ -7,14 +7,13 @@ import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.Spatial.CullHint; import com.jme3.scene.Spatial.CullHint;
public class TestSceneLoading extends SimpleApplication { public class TestSceneLoading extends SimpleApplication {
private void setState(Spatial s){ private void setState(Spatial s) {
s.setCullHint(CullHint.Never); s.setCullHint(CullHint.Never);
if (s instanceof Node){ if (s instanceof Node) {
Node n = (Node) s; Node n = (Node) s;
for (int i = 0; i < n.getQuantity(); i++){ for (int i = 0; i < n.getQuantity(); i++) {
Spatial s2 = n.getChild(i); Spatial s2 = n.getChild(i);
setState(s2); setState(s2);
} }
@ -22,16 +21,15 @@ public class TestSceneLoading extends SimpleApplication {
} }
public void simpleInitApp() { public void simpleInitApp() {
/* XXX: does not compile */ /* XXX: does not compile */
/* Spatial scene = inputManager.loadModel("FINAL_LEVEL2.j3o"); /* Spatial scene = inputManager.loadModel("FINAL_LEVEL2.j3o");
// setState(scene); // setState(scene);
rootNode.attachChild(scene); rootNode.attachChild(scene);
cam.setLocation(new Vector3f(-18.059685f, 34.64228f, 4.5048084f)); cam.setLocation(new Vector3f(-18.059685f, 34.64228f, 4.5048084f));
cam.setRotation(new Quaternion(0.22396432f, 0.5235024f, -0.1448922f, 0.8091919f)); cam.setRotation(new Quaternion(0.22396432f, 0.5235024f, -0.1448922f, 0.8091919f));
cam.update(); cam.update();
*/ */
} }
} }

@ -1,6 +1,5 @@
package jme3test.android; package jme3test.android;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -30,152 +29,143 @@ import jme3test.android.AndroidActivity;
import java.net.URI; import java.net.URI;
public class TestsActivity extends Activity { public class TestsActivity extends Activity {
private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(TestsActivity.class.getName()); private static final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(TestsActivity.class.getName());
public static class Test {
private String name = null; public static class Test {
private String className = null;
public Test(String name, String className) { private String name = null;
this.name = name; private String className = null;
this.className = className;
}
public String getName() { public Test(String name, String className) {
return name; this.name = name;
} this.className = className;
}
public String getClassName() { public String getName() {
return className; return name;
} }
}
private final static Test[] tests = { public String getClassName() {
new Test("SimpleTextured", "jme3test.android.SimpleTexturedTest"), return className;
new Test("light.TestLightRadius", "jme3test.light.TestLightRadius"), }
new Test("bullet.TestSimplePhysics", "jme3test.bullet.TestSimplePhysics"), }
new Test("helloworld.HelloJME3", "jme3test.helloworld.HelloJME3"), private final static Test[] tests = {
new Test("helloworld.HelloLoop", "jme3test.helloworld.HelloLoop"), new Test("SimpleTextured", "jme3test.android.SimpleTexturedTest"),
new Test("helloworld.HelloNode", "jme3test.helloworld.HelloNode"), new Test("light.TestLightRadius", "jme3test.light.TestLightRadius"),
new Test("helloworld.HelloEffects", "jme3test.helloworld.HelloEffects"), new Test("bullet.TestSimplePhysics", "jme3test.bullet.TestSimplePhysics"),
new Test("helloworld.HelloTerrain", "jme3test.helloworld.HelloTerrain") new Test("helloworld.HelloJME3", "jme3test.helloworld.HelloJME3"),
}; new Test("helloworld.HelloLoop", "jme3test.helloworld.HelloLoop"),
new Test("helloworld.HelloNode", "jme3test.helloworld.HelloNode"),
new Test("helloworld.HelloEffects", "jme3test.helloworld.HelloEffects"),
new Test("helloworld.HelloTerrain", "jme3test.helloworld.HelloTerrain")
};
private boolean useVA;
private boolean useVA; @Override
public void onCreate(Bundle savedInstanceState) {
logger.info("onCreate(" + savedInstanceState + ")");
@Override super.onCreate(savedInstanceState);
public void onCreate(Bundle savedInstanceState) {
logger.info("onCreate(" + savedInstanceState + ")");
super.onCreate(savedInstanceState); //setContentView(R.layout.tests);
//setContentView(R.layout.tests); try {
try { useVA = true;
useVA = true; //LinearLayout buttonsContainer = (LinearLayout) findViewById(R.id.buttonsContainer);
//LinearLayout buttonsContainer = (LinearLayout) findViewById(R.id.buttonsContainer);
for (Test test : tests) {
final Button button = new Button(this);
final String finalName = test.getName();
final String finalClassName = test.getClassName();
for (Test test: tests) { button.setText(test.getName());
final Button button = new Button(this);
final String finalName = test.getName();
final String finalClassName = test.getClassName();
button.setText(test.getName());
// button.setTextSize(10.0f); // button.setTextSize(10.0f);
// button.setTextColor(Color.rgb(100, 200, 200)); // button.setTextColor(Color.rgb(100, 200, 200));
//buttonsContainer.addView(button); //buttonsContainer.addView(button);
button.setOnClickListener( button.setOnClickListener(
new View.OnClickListener() { new View.OnClickListener() {
@Override
public void onClick(View view) { @Override
Intent intent = new Intent(view.getContext(), AndroidActivity.class); public void onClick(View view) {
intent.putExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME", finalClassName); Intent intent = new Intent(view.getContext(), AndroidActivity.class);
intent.putExtra(AndroidActivity.class.getName() + ".USE_VA", useVA); intent.putExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME", finalClassName);
startActivityForResult(intent, 0); intent.putExtra(AndroidActivity.class.getName() + ".USE_VA", useVA);
} startActivityForResult(intent, 0);
} }
); });
} }
} catch (Exception exception) { } catch (Exception exception) {
logger.warning("exception: " + exception); logger.warning("exception: " + exception);
exception.printStackTrace(System.err); exception.printStackTrace(System.err);
} }
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
logger.info("onDestroy()"); logger.info("onDestroy()");
super.onDestroy(); super.onDestroy();
} }
@Override
@Override protected void onResume() {
protected void onResume() { super.onResume();
super.onResume(); }
}
@Override
@Override protected void onStart() {
protected void onStart() { super.onStart();
super.onStart(); }
}
@Override
@Override protected void onStop() {
protected void onStop() { super.onStop();
super.onStop(); }
}
@Override
@Override public boolean onCreateOptionsMenu(Menu menu) {
public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater();
MenuInflater inflater = getMenuInflater(); //inflater.inflate(R.menu.options, menu);
//inflater.inflate(R.menu.options, menu); return true;
return true; }
}
@Override
@Override public boolean onOptionsItemSelected(MenuItem item) {
public boolean onOptionsItemSelected(MenuItem item) { /*
/* switch (item.getItemId()) {
switch (item.getItemId()) { case R.id.about_button:
case R.id.about_button: about();
about(); return true;
return true; case R.id.quit_button:
case R.id.quit_button: quit();
quit(); return true;
return true; default:
default: return super.onOptionsItemSelected(item);
return super.onOptionsItemSelected(item); }
} */
*/ return false;
return false; }
}
private void quit() {
private void quit() { finish();
finish(); }
}
private void about() {
private void about() { // Intent intent = new Intent(getView().getContext(), AboutActivity.class);
// Intent intent = new Intent(getView().getContext(), AboutActivity.class); try {
try { Intent intent = new Intent();
Intent intent = new Intent(); intent.setClassName(
intent.setClassName( "jme3test.android",
"jme3test.android", "jme3test.android.AboutActivity");
"jme3test.android.AboutActivity" startActivity(intent);
); } catch (Exception exception) {
startActivity(intent); logger.warning("exception: " + exception);
} catch (Exception exception) { exception.printStackTrace(System.err);
logger.warning("exception: " + exception); }
exception.printStackTrace(System.err); }
}
}
} }

@ -14,424 +14,413 @@ import java.util.Random;
* @author CW * @author CW
*/ */
public final class Fixed { public final class Fixed {
/**
* Number of bits used for 'fraction'.
*/
public static final int FIXED_POINT = 16;
/** /**
* Decimal one as represented by the Fixed class. * Number of bits used for 'fraction'.
*/ */
public static final int ONE = 1 << FIXED_POINT; public static final int FIXED_POINT = 16;
/**
/** * Decimal one as represented by the Fixed class.
* Half in fixed point. */
*/ public static final int ONE = 1 << FIXED_POINT;
public static final int HALF = ONE >> 1; /**
* Half in fixed point.
/** */
* Quarter circle resolution for trig functions (should be a power of public static final int HALF = ONE >> 1;
* two). This is the number of discrete steps in 90 degrees. /**
*/ * Quarter circle resolution for trig functions (should be a power of
public static final int QUARTER_CIRCLE = 64; * two). This is the number of discrete steps in 90 degrees.
*/
/** public static final int QUARTER_CIRCLE = 64;
* Mask used to limit angles to one revolution. If a quarter circle is 64 /**
* (i.e. 90 degrees is broken into 64 steps) then the mask is 255. * Mask used to limit angles to one revolution. If a quarter circle is 64
*/ * (i.e. 90 degrees is broken into 64 steps) then the mask is 255.
public static final int FULL_CIRCLE_MASK = QUARTER_CIRCLE * 4 - 1; */
public static final int FULL_CIRCLE_MASK = QUARTER_CIRCLE * 4 - 1;
/** /**
* The trig table is generated at a higher precision than the typical * The trig table is generated at a higher precision than the typical
* 16.16 format used for the rest of the fixed point maths. The table * 16.16 format used for the rest of the fixed point maths. The table
* values are then shifted to match the actual fixed point used. * values are then shifted to match the actual fixed point used.
*/ */
private static final int TABLE_SHIFT = 30; private static final int TABLE_SHIFT = 30;
/**
/** * Equivalent to: sin((2 * PI) / (QUARTER_CIRCLE * 4))
* Equivalent to: sin((2 * PI) / (QUARTER_CIRCLE * 4)) * <p>
* <p> * Note: if either QUARTER_CIRCLE or TABLE_SHIFT is changed this value
* Note: if either QUARTER_CIRCLE or TABLE_SHIFT is changed this value * will need recalculating (put the above formular into a calculator set
* will need recalculating (put the above formular into a calculator set * radians, then shift the result by <code>TABLE_SHIFT</code>).
* radians, then shift the result by <code>TABLE_SHIFT</code>). */
*/ private static final int SIN_PRECALC = 26350943;
private static final int SIN_PRECALC = 26350943; /**
* Equivalent to: cos((2 * PI) / (QUARTER_CIRCLE * 4)) * 2
/** *
* Equivalent to: cos((2 * PI) / (QUARTER_CIRCLE * 4)) * 2 * Note: if either QUARTER_CIRCLE or TABLE_SHIFT is changed this value
* * will need recalculating ((put the above formular into a calculator set
* Note: if either QUARTER_CIRCLE or TABLE_SHIFT is changed this value * radians, then shift the result by <code>TABLE_SHIFT</code>).
* will need recalculating ((put the above formular into a calculator set */
* radians, then shift the result by <code>TABLE_SHIFT</code>). private static final int COS_PRECALC = 2146836866;
*/ /**
private static final int COS_PRECALC = 2146836866; * One quarter sine wave as fixed point values.
*/
/** private static final int[] SINE_TABLE = new int[QUARTER_CIRCLE + 1];
* One quarter sine wave as fixed point values. /**
*/ * Scale value for indexing ATAN_TABLE[].
private static final int[] SINE_TABLE = new int[QUARTER_CIRCLE + 1]; */
private static final int ATAN_SHIFT;
/** /**
* Scale value for indexing ATAN_TABLE[]. * Reverse atan lookup table.
*/ */
private static final int ATAN_SHIFT; private static final byte[] ATAN_TABLE;
/**
/** * ATAN_TABLE.length
* Reverse atan lookup table. */
*/ private static final int ATAN_TABLE_LEN;
private static final byte[] ATAN_TABLE;
/**
* ATAN_TABLE.length
*/
private static final int ATAN_TABLE_LEN;
/*
* Generates the tables and fills in any remaining static ints.
*/
static {
// Generate the sine table using recursive synthesis.
SINE_TABLE[0] = 0;
SINE_TABLE[1] = SIN_PRECALC;
for (int n = 2; n < QUARTER_CIRCLE + 1; n++) {
SINE_TABLE[n] = (int) (((long) SINE_TABLE[n - 1] * COS_PRECALC) >> TABLE_SHIFT) - SINE_TABLE[n - 2];
}
// Scale the values to the fixed point format used.
for (int n = 0; n < QUARTER_CIRCLE + 1; n++) {
SINE_TABLE[n] = SINE_TABLE[n] + (1 << (TABLE_SHIFT - FIXED_POINT - 1)) >> TABLE_SHIFT - FIXED_POINT;
}
// Calculate a shift used to scale atan lookups
int rotl = 0;
int tan0 = tan(0);
int tan1 = tan(1);
while (rotl < 32) {
if ((tan1 >>= 1) > (tan0 >>= 1)) {
rotl++;
} else {
break;
}
}
ATAN_SHIFT = rotl;
// Create the a table of tan values
int[] lut = new int[QUARTER_CIRCLE];
for (int n = 0; n < QUARTER_CIRCLE; n++) {
lut[n] = tan(n) >> rotl;
}
ATAN_TABLE_LEN = lut[QUARTER_CIRCLE - 1];
// Then from the tan values create a reverse lookup
ATAN_TABLE = new byte[ATAN_TABLE_LEN];
for (byte n = 0; n < QUARTER_CIRCLE - 1; n++) {
int min = lut[n ];
int max = lut[n + 1];
for (int i = min; i < max; i++) {
ATAN_TABLE[i] = n;
}
}
}
/**
* How many decimal places to use when converting a fixed point value to
* a decimal string.
*
* @see #toString
*/
private static final int STRING_DECIMAL_PLACES = 2;
/**
* Value to add in order to round down a fixed point number when
* converting to a string.
*/
private static final int STRING_DECIMAL_PLACES_ROUND;
static {
int i = 10;
for (int n = 1; n < STRING_DECIMAL_PLACES; n++) {
i *= i;
}
if (STRING_DECIMAL_PLACES == 0) {
STRING_DECIMAL_PLACES_ROUND = ONE / 2;
} else {
STRING_DECIMAL_PLACES_ROUND = ONE / (2 * i);
}
}
/** /*
* Random number generator. The standard <code>java.utll.Random</code> is * Generates the tables and fills in any remaining static ints.
* used since it is available to both J2ME and J2SE. If a guaranteed */
* sequence is required this would not be adequate. static {
*/ // Generate the sine table using recursive synthesis.
private static Random rng = null; SINE_TABLE[0] = 0;
SINE_TABLE[1] = SIN_PRECALC;
for (int n = 2; n < QUARTER_CIRCLE + 1; n++) {
SINE_TABLE[n] = (int) (((long) SINE_TABLE[n - 1] * COS_PRECALC) >> TABLE_SHIFT) - SINE_TABLE[n - 2];
}
// Scale the values to the fixed point format used.
for (int n = 0; n < QUARTER_CIRCLE + 1; n++) {
SINE_TABLE[n] = SINE_TABLE[n] + (1 << (TABLE_SHIFT - FIXED_POINT - 1)) >> TABLE_SHIFT - FIXED_POINT;
}
// Calculate a shift used to scale atan lookups
int rotl = 0;
int tan0 = tan(0);
int tan1 = tan(1);
while (rotl < 32) {
if ((tan1 >>= 1) > (tan0 >>= 1)) {
rotl++;
} else {
break;
}
}
ATAN_SHIFT = rotl;
// Create the a table of tan values
int[] lut = new int[QUARTER_CIRCLE];
for (int n = 0; n < QUARTER_CIRCLE; n++) {
lut[n] = tan(n) >> rotl;
}
ATAN_TABLE_LEN = lut[QUARTER_CIRCLE - 1];
// Then from the tan values create a reverse lookup
ATAN_TABLE = new byte[ATAN_TABLE_LEN];
for (byte n = 0; n < QUARTER_CIRCLE - 1; n++) {
int min = lut[n];
int max = lut[n + 1];
for (int i = min; i < max; i++) {
ATAN_TABLE[i] = n;
}
}
}
/**
* How many decimal places to use when converting a fixed point value to
* a decimal string.
*
* @see #toString
*/
private static final int STRING_DECIMAL_PLACES = 2;
/**
* Value to add in order to round down a fixed point number when
* converting to a string.
*/
private static final int STRING_DECIMAL_PLACES_ROUND;
static {
int i = 10;
for (int n = 1; n < STRING_DECIMAL_PLACES; n++) {
i *= i;
}
if (STRING_DECIMAL_PLACES == 0) {
STRING_DECIMAL_PLACES_ROUND = ONE / 2;
} else {
STRING_DECIMAL_PLACES_ROUND = ONE / (2 * i);
}
}
/**
* Random number generator. The standard <code>java.utll.Random</code> is
* used since it is available to both J2ME and J2SE. If a guaranteed
* sequence is required this would not be adequate.
*/
private static Random rng = null;
/** /**
* Fixed can't be instantiated. * Fixed can't be instantiated.
*/ */
private Fixed() {} private Fixed() {
}
/** /**
* Returns an integer as a fixed point value. * Returns an integer as a fixed point value.
*/ */
public static int intToFixed(int n) { public static int intToFixed(int n) {
return n << FIXED_POINT; return n << FIXED_POINT;
} }
/** /**
* Returns a fixed point value as a float. * Returns a fixed point value as a float.
*/ */
public static float fixedToFloat(int i) { public static float fixedToFloat(int i) {
float fp = i; float fp = i;
fp = fp / ((float)ONE); fp = fp / ((float) ONE);
return fp; return fp;
} }
/** /**
* Returns a float as a fixed point value. * Returns a float as a fixed point value.
*/ */
public static int floatToFixed(float fp){ public static int floatToFixed(float fp) {
return (int) (fp * ((float) ONE)); return (int) (fp * ((float) ONE));
} }
/** /**
* Converts a fixed point value into a decimal string. * Converts a fixed point value into a decimal string.
*/ */
public static String toString(int n) { public static String toString(int n) {
StringBuffer sb = new StringBuffer(16); StringBuffer sb = new StringBuffer(16);
sb.append((n += STRING_DECIMAL_PLACES_ROUND) >> FIXED_POINT); sb.append((n += STRING_DECIMAL_PLACES_ROUND) >> FIXED_POINT);
sb.append('.'); sb.append('.');
n &= ONE - 1; n &= ONE - 1;
for (int i = 0; i < STRING_DECIMAL_PLACES; i++) { for (int i = 0; i < STRING_DECIMAL_PLACES; i++) {
n *= 10; n *= 10;
sb.append((n / ONE) % 10); sb.append((n / ONE) % 10);
} }
return sb.toString(); return sb.toString();
} }
/** /**
* Multiplies two fixed point values and returns the result. * Multiplies two fixed point values and returns the result.
*/ */
public static int mul(int a, int b) { public static int mul(int a, int b) {
return (int) ((long) a * (long) b >> FIXED_POINT); return (int) ((long) a * (long) b >> FIXED_POINT);
} }
/** /**
* Divides two fixed point values and returns the result. * Divides two fixed point values and returns the result.
*/ */
public static int div(int a, int b) { public static int div(int a, int b) {
return (int) (((long) a << FIXED_POINT * 2) / (long) b >> FIXED_POINT); return (int) (((long) a << FIXED_POINT * 2) / (long) b >> FIXED_POINT);
} }
/** /**
* Sine of an angle. * Sine of an angle.
* *
* @see #QUARTER_CIRCLE * @see #QUARTER_CIRCLE
*/ */
public static int sin(int n) { public static int sin(int n) {
n &= FULL_CIRCLE_MASK; n &= FULL_CIRCLE_MASK;
if (n < QUARTER_CIRCLE * 2) { if (n < QUARTER_CIRCLE * 2) {
if (n < QUARTER_CIRCLE) { if (n < QUARTER_CIRCLE) {
return SINE_TABLE[n]; return SINE_TABLE[n];
} else { } else {
return SINE_TABLE[QUARTER_CIRCLE * 2 - n]; return SINE_TABLE[QUARTER_CIRCLE * 2 - n];
} }
} else { } else {
if (n < QUARTER_CIRCLE * 3) { if (n < QUARTER_CIRCLE * 3) {
return -SINE_TABLE[n - QUARTER_CIRCLE * 2]; return -SINE_TABLE[n - QUARTER_CIRCLE * 2];
} else { } else {
return -SINE_TABLE[QUARTER_CIRCLE * 4 - n]; return -SINE_TABLE[QUARTER_CIRCLE * 4 - n];
} }
} }
} }
/** /**
* Cosine of an angle. * Cosine of an angle.
* *
* @see #QUARTER_CIRCLE * @see #QUARTER_CIRCLE
*/ */
public static int cos(int n) { public static int cos(int n) {
n &= FULL_CIRCLE_MASK; n &= FULL_CIRCLE_MASK;
if (n < QUARTER_CIRCLE * 2) { if (n < QUARTER_CIRCLE * 2) {
if (n < QUARTER_CIRCLE) { if (n < QUARTER_CIRCLE) {
return SINE_TABLE[QUARTER_CIRCLE - n]; return SINE_TABLE[QUARTER_CIRCLE - n];
} else { } else {
return -SINE_TABLE[n - QUARTER_CIRCLE]; return -SINE_TABLE[n - QUARTER_CIRCLE];
} }
} else { } else {
if (n < QUARTER_CIRCLE * 3) { if (n < QUARTER_CIRCLE * 3) {
return -SINE_TABLE[QUARTER_CIRCLE * 3 - n]; return -SINE_TABLE[QUARTER_CIRCLE * 3 - n];
} else { } else {
return SINE_TABLE[n - QUARTER_CIRCLE * 3]; return SINE_TABLE[n - QUARTER_CIRCLE * 3];
} }
} }
} }
/** /**
* Tangent of an angle. * Tangent of an angle.
* *
* @see #QUARTER_CIRCLE * @see #QUARTER_CIRCLE
*/ */
public static int tan(int n) { public static int tan(int n) {
return div(sin(n), cos(n)); return div(sin(n), cos(n));
} }
/** /**
* Returns the arc tangent of an angle. * Returns the arc tangent of an angle.
*/ */
public static int atan(int n) { public static int atan(int n) {
n = n + (1 << (ATAN_SHIFT - 1)) >> ATAN_SHIFT; n = n + (1 << (ATAN_SHIFT - 1)) >> ATAN_SHIFT;
if (n < 0) { if (n < 0) {
if (n <= -ATAN_TABLE_LEN) { if (n <= -ATAN_TABLE_LEN) {
return -(QUARTER_CIRCLE - 1); return -(QUARTER_CIRCLE - 1);
} }
return -ATAN_TABLE[-n]; return -ATAN_TABLE[-n];
} else { } else {
if (n >= ATAN_TABLE_LEN) { if (n >= ATAN_TABLE_LEN) {
return QUARTER_CIRCLE - 1; return QUARTER_CIRCLE - 1;
} }
return ATAN_TABLE[n]; return ATAN_TABLE[n];
} }
} }
/** /**
* Returns the polar angle of a rectangular coordinate. * Returns the polar angle of a rectangular coordinate.
*/ */
public static int atan(int x, int y) { public static int atan(int x, int y) {
int n = atan(div(x, abs(y) + 1)); // kludge to prevent ArithmeticException int n = atan(div(x, abs(y) + 1)); // kludge to prevent ArithmeticException
if (y > 0) { if (y > 0) {
return n; return n;
} }
if (y < 0) { if (y < 0) {
if (x < 0) { if (x < 0) {
return -QUARTER_CIRCLE * 2 - n; return -QUARTER_CIRCLE * 2 - n;
} }
if (x > 0) { if (x > 0) {
return QUARTER_CIRCLE * 2 - n; return QUARTER_CIRCLE * 2 - n;
} }
return QUARTER_CIRCLE * 2; return QUARTER_CIRCLE * 2;
} }
if (x > 0) { if (x > 0) {
return QUARTER_CIRCLE; return QUARTER_CIRCLE;
} }
return -QUARTER_CIRCLE; return -QUARTER_CIRCLE;
} }
/** /**
* Rough calculation of the hypotenuse. Whilst not accurate it is very fast. * Rough calculation of the hypotenuse. Whilst not accurate it is very fast.
* <p> * <p>
* Derived from a piece in Graphics Gems. * Derived from a piece in Graphics Gems.
*/ */
public static int hyp(int x1, int y1, int x2, int y2) { public static int hyp(int x1, int y1, int x2, int y2) {
if ((x2 -= x1) < 0) { if ((x2 -= x1) < 0) {
x2 = -x2; x2 = -x2;
} }
if ((y2 -= y1) < 0) { if ((y2 -= y1) < 0) {
y2 = -y2; y2 = -y2;
} }
return x2 + y2 - (((x2 > y2) ? y2 : x2) >> 1); return x2 + y2 - (((x2 > y2) ? y2 : x2) >> 1);
} }
/** /**
* Fixed point square root. * Fixed point square root.
* <p> * <p>
* Derived from a 1993 Usenet algorithm posted by Christophe Meessen. * Derived from a 1993 Usenet algorithm posted by Christophe Meessen.
*/ */
public static int sqrt(int n) { public static int sqrt(int n) {
if (n <= 0) { if (n <= 0) {
return 0; return 0;
} }
long sum = 0; long sum = 0;
int bit = 0x40000000; int bit = 0x40000000;
while (bit >= 0x100) { // lower values give more accurate results while (bit >= 0x100) { // lower values give more accurate results
long tmp = sum | bit; long tmp = sum | bit;
if (n >= tmp) { if (n >= tmp) {
n -= tmp; n -= tmp;
sum = tmp + bit; sum = tmp + bit;
} }
bit >>= 1; bit >>= 1;
n <<= 1; n <<= 1;
} }
return (int) (sum >> 16 - (FIXED_POINT / 2)); return (int) (sum >> 16 - (FIXED_POINT / 2));
} }
/** /**
* Returns the absolute value. * Returns the absolute value.
*/ */
public static int abs(int n) { public static int abs(int n) {
return (n < 0) ? -n : n; return (n < 0) ? -n : n;
} }
/** /**
* Returns the sign of a value, -1 for negative numbers, otherwise 1. * Returns the sign of a value, -1 for negative numbers, otherwise 1.
*/ */
public static int sgn(int n) { public static int sgn(int n) {
return (n < 0) ? -1 : 1; return (n < 0) ? -1 : 1;
} }
/** /**
* Returns the minimum of two values. * Returns the minimum of two values.
*/ */
public static int min(int a, int b) { public static int min(int a, int b) {
return (a < b) ? a : b; return (a < b) ? a : b;
} }
/** /**
* Returns the maximum of two values. * Returns the maximum of two values.
*/ */
public static int max(int a, int b) { public static int max(int a, int b) {
return (a > b) ? a : b; return (a > b) ? a : b;
} }
/** /**
* Clamps the value n between min and max. * Clamps the value n between min and max.
*/ */
public static int clamp(int n, int min, int max) { public static int clamp(int n, int min, int max) {
return (n < min) ? min : (n > max) ? max : n; return (n < min) ? min : (n > max) ? max : n;
} }
/** /**
* Wraps the value n between 0 and the required limit. * Wraps the value n between 0 and the required limit.
*/ */
public static int wrap(int n, int limit) { public static int wrap(int n, int limit) {
return ((n %= limit) < 0) ? limit + n : n; return ((n %= limit) < 0) ? limit + n : n;
} }
/** /**
* Returns the nearest int to a fixed point value. Equivalent to <code> * Returns the nearest int to a fixed point value. Equivalent to <code>
* Math.round()</code> in the standard library. * Math.round()</code> in the standard library.
*/ */
public static int round(int n) { public static int round(int n) {
return n + HALF >> FIXED_POINT; return n + HALF >> FIXED_POINT;
} }
/** /**
* Returns the nearest int rounded down from a fixed point value. * Returns the nearest int rounded down from a fixed point value.
* Equivalent to <code>Math.floor()</code> in the standard library. * Equivalent to <code>Math.floor()</code> in the standard library.
*/ */
public static int floor(int n) { public static int floor(int n) {
return n >> FIXED_POINT; return n >> FIXED_POINT;
} }
/** /**
* Returns the nearest int rounded up from a fixed point value. * Returns the nearest int rounded up from a fixed point value.
* Equivalent to <code>Math.ceil()</code> in the standard library. * Equivalent to <code>Math.ceil()</code> in the standard library.
*/ */
public static int ceil(int n) { public static int ceil(int n) {
return n + (ONE - 1) >> FIXED_POINT; return n + (ONE - 1) >> FIXED_POINT;
} }
/** /**
* Returns a fixed point value greater than or equal to decimal 0.0 and * Returns a fixed point value greater than or equal to decimal 0.0 and
* less than 1.0 (in 16.16 format this would be 0 to 65535 inclusive). * less than 1.0 (in 16.16 format this would be 0 to 65535 inclusive).
*/ */
public static int rand() { public static int rand() {
if (rng == null) { if (rng == null) {
rng = new Random(); rng = new Random();
} }
return rng.nextInt() >>> (32 - FIXED_POINT); return rng.nextInt() >>> (32 - FIXED_POINT);
} }
/** /**
* Returns a random number between 0 and <code>n</code> (exclusive). * Returns a random number between 0 and <code>n</code> (exclusive).
*/ */
public static int rand(int n) { public static int rand(int n) {
return (rand() * n) >> FIXED_POINT; return (rand() * n) >> FIXED_POINT;
} }
} }

@ -7,25 +7,25 @@
android:layout_height="fill_parent" android:layout_height="fill_parent"
> >
<LinearLayout <LinearLayout
android:id="@+id/buttonsContainer" android:id="@+id/buttonsContainer"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
> >
<TextView <TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="copyright (c) 2009-2010 JMonkeyEngine" android:text="copyright (c) 2009-2010 JMonkeyEngine"
/> />
<TextView <TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="http://www.jmonkeyengine.org" android:text="http://www.jmonkeyengine.org"
/> />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

@ -6,14 +6,12 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
> >
<LinearLayout
<LinearLayout
android:id="@+id/buttonsContainer" android:id="@+id/buttonsContainer"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent">
>
<!-- <!--
<Button <Button
android:id="@+id/SimpleTextured" android:id="@+id/SimpleTextured"
@ -23,6 +21,5 @@
android:layout_weight="1" android:layout_weight="1"
/> />
--> -->
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

@ -1,14 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
<item android:id="@+id/about_button"
android:id="@+id/about_button" android:title="@string/about"
android:title="@string/about"
/> />
<item <item
android:id="@+id/quit_button" android:id="@+id/quit_button"
android:title="@string/quit" android:title="@string/quit"
/> />
</menu> </menu>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">JMEAndroidTest</string> <string name="app_name">JMEAndroidTest</string>
<string name="about">About</string> <string name="about">About</string>
<string name="quit">Quit</string> <string name="quit">Quit</string>
</resources> </resources>

@ -37,7 +37,6 @@ import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput; import com.jme3.input.MouseInput;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.renderer.Renderer; import com.jme3.renderer.Renderer;
import com.jme3.system.JmeCanvasContext;
/** /**
* Represents a rendering context within the engine. * Represents a rendering context within the engine.

@ -0,0 +1,65 @@
package com.jme3.system;
public enum Platform {
/**
* Microsoft Windows 32 bit
*/
Windows32,
/**
* Microsoft Windows 64 bit
*/
Windows64,
/**
* Linux 32 bit
*/
Linux32,
/**
* Linux 64 bit
*/
Linux64,
/**
* Apple Mac OS X 32 bit
*/
MacOSX32,
/**
* Apple Mac OS X 64 bit
*/
MacOSX64,
/**
* Apple Mac OS X 32 bit PowerPC
*/
MacOSX_PPC32,
/**
* Apple Mac OS X 64 bit PowerPC
*/
MacOSX_PPC64,
/**
* Android ARM5
*/
Android_ARM5,
/**
* Android ARM6
*/
Android_ARM6,
/**
* Android ARM7
*/
Android_ARM7,
/**
* Android x86
*/
Android_X86;
}

@ -13,29 +13,75 @@ import com.jme3.texture.Image;
import com.jme3.texture.Image.Format; import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.texture.TextureCubeMap; import com.jme3.texture.TextureCubeMap;
import java.util.ArrayList;
/**
* <code>SkyFactory</code> is used to create jME {@link Spatial}s that can
* be attached to the scene to display a sky image in the background.
*
* @author Kirill Vainer
*/
public class SkyFactory { public class SkyFactory {
/**
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap){ * Creates a sky using the given texture (cubemap or spheremap).
return createSky(assetManager, texture, normalScale, sphereMap, 10); *
} * @param assetManager The asset manager to use to load materials
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap, int sphereRadius){ * @param texture Texture to use for the sky
if (texture == null) * @param normalScale The normal scale is multiplied by the 3D normal
* to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
* and transformation to the normal.
* @param sphereMap The way the texture is used
* depends on this value:<br>
* <ul>
* <li>true: Its a Texture2D with the pixels arranged for
* <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
* <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
* then the image is taken from it and is inserted into a TextureCubeMap</li>
* </ul>
* @return A spatial representing the sky
*/
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap) {
return createSky(assetManager, texture, normalScale, sphereMap, 10);
}
/**
* Creates a sky using the given texture (cubemap or spheremap).
*
* @param assetManager The asset manager to use to load materials
* @param texture Texture to use for the sky
* @param normalScale The normal scale is multiplied by the 3D normal
* to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
* and transformation to the normal.
* @param sphereMap The way the texture is used
* depends on this value:<br>
* <ul>
* <li>true: Its a Texture2D with the pixels arranged for
* <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
* <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
* then the image is taken from it and is inserted into a TextureCubeMap</li>
* </ul>
* @param sphereRadius If specified, this will be the sky sphere's radius.
* This should be the camera's near plane for optimal quality.
* @return A spatial representing the sky
*/
public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap, int sphereRadius) {
if (texture == null) {
throw new IllegalArgumentException("texture cannot be null"); throw new IllegalArgumentException("texture cannot be null");
}
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true); final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh); Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky); sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never); sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO)); sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md"); Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");
skyMat.setVector3("NormalScale", normalScale); skyMat.setVector3("NormalScale", normalScale);
if (sphereMap){ if (sphereMap) {
skyMat.setBoolean("SphereMap", sphereMap); skyMat.setBoolean("SphereMap", sphereMap);
}else if (!(texture instanceof TextureCubeMap)){ } else if (!(texture instanceof TextureCubeMap)) {
// make sure its a cubemap // make sure its a cubemap
Image img = texture.getImage(); Image img = texture.getImage();
texture = new TextureCubeMap(); texture = new TextureCubeMap();
@ -43,23 +89,27 @@ public class SkyFactory {
} }
skyMat.setTexture("Texture", texture); skyMat.setTexture("Texture", texture);
sky.setMaterial(skyMat); sky.setMaterial(skyMat);
return sky; return sky;
} }
private static void checkImage(Image image){ private static void checkImage(Image image) {
// if (image.getDepth() != 1) // if (image.getDepth() != 1)
// throw new IllegalArgumentException("3D/Array images not allowed"); // throw new IllegalArgumentException("3D/Array images not allowed");
if (image.getWidth() != image.getHeight()) if (image.getWidth() != image.getHeight()) {
throw new IllegalArgumentException("Image width and height must be the same"); throw new IllegalArgumentException("Image width and height must be the same");
}
if (image.getMultiSamples() != 1) if (image.getMultiSamples() != 1) {
throw new IllegalArgumentException("Multisample textures not allowed"); throw new IllegalArgumentException("Multisample textures not allowed");
}
} }
private static void checkImagesForCubeMap(Image ... images){ private static void checkImagesForCubeMap(Image... images) {
if (images.length == 1) return; if (images.length == 1) {
return;
}
Format fmt = images[0].getFormat(); Format fmt = images[0].getFormat();
int width = images[0].getWidth(); int width = images[0].getWidth();
@ -67,45 +117,63 @@ public class SkyFactory {
checkImage(images[0]); checkImage(images[0]);
for (int i = 1; i < images.length; i++){ for (int i = 1; i < images.length; i++) {
Image image = images[i]; Image image = images[i];
checkImage(images[i]); checkImage(images[i]);
if (image.getFormat() != fmt) throw new IllegalArgumentException("Images must have same format"); if (image.getFormat() != fmt) {
if (image.getWidth() != width) throw new IllegalArgumentException("Images must have same resolution"); throw new IllegalArgumentException("Images must have same format");
if (image.getData(0).capacity() != size) throw new IllegalArgumentException("Images must have same size"); }
if (image.getWidth() != width) {
throw new IllegalArgumentException("Images must have same resolution");
}
if (image.getData(0).capacity() != size) {
throw new IllegalArgumentException("Images must have same size");
}
} }
} }
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale){ public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale) {
return createSky(assetManager, west, east, north, south, up, down, normalScale, 10); return createSky(assetManager, west, east, north, south, up, down, normalScale, 10);
} }
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale, int sphereRadius){ public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down, Vector3f normalScale, int sphereRadius) {
final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true); final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);
Geometry sky = new Geometry("Sky", sphereMesh); Geometry sky = new Geometry("Sky", sphereMesh);
sky.setQueueBucket(Bucket.Sky); sky.setQueueBucket(Bucket.Sky);
sky.setCullHint(Spatial.CullHint.Never); sky.setCullHint(Spatial.CullHint.Never);
sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO)); sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));
Image westImg = west.getImage(); Image westImg = west.getImage();
Image eastImg = east.getImage(); Image eastImg = east.getImage();
Image northImg = north.getImage(); Image northImg = north.getImage();
Image southImg = south.getImage(); Image southImg = south.getImage();
Image upImg = up.getImage(); Image upImg = up.getImage();
Image downImg = down.getImage(); Image downImg = down.getImage();
checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg); checkImagesForCubeMap(westImg, eastImg, northImg, southImg, upImg, downImg);
Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null); Image cubeImage = new Image(westImg.getFormat(), westImg.getWidth(), westImg.getHeight(), null);
cubeImage.addData(westImg.getData(0)); cubeImage.addData(westImg.getData(0));
cubeImage.addData(eastImg.getData(0)); cubeImage.addData(eastImg.getData(0));
cubeImage.addData(downImg.getData(0)); cubeImage.addData(downImg.getData(0));
cubeImage.addData(upImg.getData(0)); cubeImage.addData(upImg.getData(0));
cubeImage.addData(southImg.getData(0)); cubeImage.addData(southImg.getData(0));
cubeImage.addData(northImg.getData(0)); cubeImage.addData(northImg.getData(0));
if (westImg.getEfficentData() != null){
// also consilidate efficient data
ArrayList<Object> efficientData = new ArrayList<Object>(6);
efficientData.add(westImg.getEfficentData());
efficientData.add(eastImg.getEfficentData());
efficientData.add(downImg.getEfficentData());
efficientData.add(upImg.getEfficentData());
efficientData.add(southImg.getEfficentData());
efficientData.add(northImg.getEfficentData());
cubeImage.setEfficentData(efficientData);
}
TextureCubeMap cubeMap = new TextureCubeMap(cubeImage); TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
cubeMap.setAnisotropicFilter(0); cubeMap.setAnisotropicFilter(0);
@ -121,22 +189,19 @@ public class SkyFactory {
return sky; return sky;
} }
public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down){ public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south, Texture up, Texture down) {
return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ); return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
} }
public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap){ public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap) {
return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap); return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
} }
public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap){ public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap) {
TextureKey key = new TextureKey(textureName, true); TextureKey key = new TextureKey(textureName, true);
key.setGenerateMips(true); key.setGenerateMips(true);
key.setAsCube(!sphereMap); key.setAsCube(!sphereMap);
Texture tex = assetManager.loadTexture(key); Texture tex = assetManager.loadTexture(key);
return createSky(assetManager, tex, sphereMap); return createSky(assetManager, tex, sphereMap);
} }
} }

@ -48,41 +48,6 @@ import javax.swing.SwingUtilities;
public class JmeSystem { public class JmeSystem {
public static enum Platform {
/**
* Microsoft Windows 32 bit
*/
Windows32,
/**
* Microsoft Windows 64 bit
*/
Windows64,
/**
* Linux 32 bit
*/
Linux32,
/**
* Linux 64 bit
*/
Linux64,
/**
* Apple Mac OS X 32 bit
*/
MacOSX32,
/**
* Apple Mac OS X 64 bit
*/
MacOSX64,
/**
* Apple Mac OS X 32 bit PowerPC
*/
MacOSX_PPC32,
/**
* Apple Mac OS X 64 bit PowerPC
*/
MacOSX_PPC64,
}
private static final Logger logger = Logger.getLogger(JmeSystem.class.getName()); private static final Logger logger = Logger.getLogger(JmeSystem.class.getName());
private static boolean initialized = false; private static boolean initialized = false;
private static boolean lowPermissions = false; private static boolean lowPermissions = false;

Loading…
Cancel
Save