* 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
This commit is contained in:
sha..rd 2011-09-10 21:26:59 +00:00
parent 45d1a0e772
commit 5ac90f46fa
21 changed files with 1092 additions and 1272 deletions

View File

@ -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;
} }
} }
} }
} }

View File

@ -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;
} }
} }

View File

@ -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() public static Platform getPlatform() {
{
String os = System.getProperty("os.name").toLowerCase();
String arch = System.getProperty("os.arch").toLowerCase(); String arch = System.getProperty("os.arch").toLowerCase();
if (arch.contains("arm")){
return Platform.Android_Froyo; if (arch.contains("v5")){
// throw new UnsupportedOperationException("The specified platform: "+os+" is not supported."); 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");
}
} }
} }

View File

@ -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;
} }
} }

View File

@ -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++];
} }
} }
} }

View File

@ -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) public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap) {
{ return SkyFactory.createSky(assetManager, texture, normalScale, 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) public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south,
{ Texture up, Texture down, Vector3f normalScale) {
if (image.getWidth() != image.getHeight()) return SkyFactory.createSky(assetManager, west, east, north, south, up, down, normalScale);
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) public static Spatial createSky(AssetManager assetManager, Texture west, Texture east, Texture north, Texture south,
{ Texture up, Texture down) {
if (images.length == 1) return; return SkyFactory.createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
Format fmt = images[0].getFormat();
int width = images[0].getWidth();
int height = images[0].getHeight();
checkImage(images[0]);
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 texture, boolean sphereMap) {
Texture up, Texture down, Vector3f normalScale) return SkyFactory.createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
{
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, String textureName, boolean sphereMap) {
Texture up, Texture down) return SkyFactory.createSky(assetManager, textureName, sphereMap);
{
return createSky(assetManager, west, east, north, south, up, down, Vector3f.UNIT_XYZ);
}
public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap)
{
return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap);
}
public static Spatial createSky(AssetManager assetManager, String textureName, boolean sphereMap)
{
TextureKey key = new TextureKey(textureName, true);
key.setGenerateMips(true);
key.setAsCube(!sphereMap);
Texture tex = assetManager.loadTexture(key);
return createSky(assetManager, tex, sphereMap);
} }
} }

View File

@ -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
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.about);
}
//setContentView(R.layout.about); @Override
} public void onDestroy() {
logger.info("onDestroy()");
super.onDestroy();
}
@Override @Override
public void onDestroy() { protected void onResume() {
logger.info("onDestroy()"); super.onResume();
super.onDestroy(); }
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
}
} }

View File

@ -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) {
super.onCreate(savedInstanceState);
JmeSystem.setResources(getResources());
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
AppSettings settings = new AppSettings(true);
String testClassName = getIntent().getStringExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME");
logger.info("test class name: [" + testClassName + "]");
String appClass = (testClassName != null ? testClassName : "jme3test.android.SimpleTexturedTest");
useVA = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".USE_VA", false);
logger.info("USE_VA -> [" + useVA + "]");
settings.putBoolean("USE_VA", useVA);
verboseLogging = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".VERBOSE_LOGGING", false);
settings.putBoolean("VERBOSE_LOGGING", verboseLogging);
Application app = null;
try {
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(
appClass);
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);
}
}
);
*/
private OGLESContext ctx; if (app instanceof SimpleApplication) {
private GLSurfaceView view; ((SimpleApplication) app).setShowSettings(false);
}
private boolean useVA = false; logger.info("setting settings ...");
private boolean verboseLogging = false; app.setSettings(settings);
logger.info("setting settings ... done.");
@Override logger.info("starting app ...");
public void onCreate(Bundle savedInstanceState) { app.start();
logger.info("starting app ... done.");
super.onCreate(savedInstanceState); if (app instanceof SimpleApplication) {
((SimpleApplication) app).getGuiNode().detachAllChildren();
}
JmeSystem.setResources(getResources()); logger.info("creating context ...");
ctx = (OGLESContext) app.getContext();
logger.info("creating context ... done.");
requestWindowFeature(Window.FEATURE_NO_TITLE); ctx.setSettings(settings);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
AppSettings settings = new AppSettings(true); logger.info("creating view ...");
view = ctx.createView(this);
logger.info("creating view ... done.");
String testClassName = getIntent().getStringExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME"); logger.info("setting content view ...");
setContentView(view);
logger.info("setting content done ...");
logger.info("test class name: [" + testClassName + "]"); } catch (Throwable exception) {
logger.warning("exception: " + exception);
exception.printStackTrace(System.err);
}
}
String appClass = (testClassName != null? testClassName: "jme3test.android.SimpleTexturedTest"); @Override
protected void onResume() {
logger.info("onResume ...");
super.onResume();
logger.info("view.onResume ...");
useVA = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".USE_VA", false); view.onResume();
logger.info("USE_VA -> [" + useVA + "]"); logger.info("view.onResume ... done.");
logger.info("onResume ... done.");
settings.putBoolean("USE_VA", useVA); }
verboseLogging = getIntent().getBooleanExtra(AndroidActivity.class.getName() + ".VERBOSE_LOGGING", false);
settings.putBoolean("VERBOSE_LOGGING", verboseLogging);
Application app = null;
try {
Class<? extends Application> clazz = (Class<? extends Application>) Class.forName(
appClass
);
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);
}
}
);
*/
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();
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
}
// @Override // @Override
// protected void onDestroy(){ // protected void onDestroy(){
// super.onDestroy(); // super.onDestroy();
// Debug.stopMethodTracing(); // Debug.stopMethodTracing();
// } // }
} }

View File

@ -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 boolean texturedEnabled = true;
private boolean spheres = true;
@Override
public void simpleInitApp() {
private Node spheresContainer = new Node("spheres-container"); /*
* GUI rendering is broken on Android right now and prevents the main view from rendering.
* Detaching all children lets the main view to be rendered.
*/
guiNode.detachAllChildren();
private boolean lightingEnabled = true; Mesh shape = null;
private boolean texturedEnabled = true;
private boolean spheres = true;
@Override if (spheres) {
public void simpleInitApp() { shape = new Sphere(16, 16, .5f);
} else {
shape = new Box(Vector3f.ZERO, 0.3f, 0.3f, 0.3f);
}
/* // ModelConverter.optimize(geom);
* GUI rendering is broken on Android right now and prevents the main view from rendering.
* Detaching all children lets the main view to be rendered.
*/
guiNode.detachAllChildren(); Texture texture = assetManager.loadTexture(new TextureKey("icons/textured.png"));
Mesh shape = null; Material material = null;
if (spheres) { if (texturedEnabled) {
shape = new Sphere(16, 16, .5f); if (lightingEnabled) {
} else { material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
shape = new Box(Vector3f.ZERO, 0.3f, 0.3f, 0.3f); 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);
}
// ModelConverter.optimize(geom); TangentBinormalGenerator.generate(shape);
Texture texture = assetManager.loadTexture(new TextureKey("icons/textured.png")); 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);
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);
}
} }

View File

@ -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 {
} }
} }
} }
} }

View File

@ -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();
*/ */
} }
} }

View File

@ -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;
private String className = null;
public Test(String name, String className) {
this.name = name;
this.className = className;
}
public String getName() {
return name;
}
public String getClassName() {
return className;
}
}
private final static Test[] tests = {
new Test("SimpleTextured", "jme3test.android.SimpleTexturedTest"),
new Test("light.TestLightRadius", "jme3test.light.TestLightRadius"),
new Test("bullet.TestSimplePhysics", "jme3test.bullet.TestSimplePhysics"),
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;
@Override
public void onCreate(Bundle savedInstanceState) {
logger.info("onCreate(" + savedInstanceState + ")");
super.onCreate(savedInstanceState);
//setContentView(R.layout.tests);
try {
useVA = true;
//LinearLayout buttonsContainer = (LinearLayout) findViewById(R.id.buttonsContainer);
public static class Test { for (Test test : tests) {
final Button button = new Button(this);
final String finalName = test.getName();
final String finalClassName = test.getClassName();
private String name = null; button.setText(test.getName());
private String className = null;
public Test(String name, String className) {
this.name = name;
this.className = className;
}
public String getName() {
return name;
}
public String getClassName() {
return className;
}
}
private final static Test[] tests = {
new Test("SimpleTextured", "jme3test.android.SimpleTexturedTest"),
new Test("light.TestLightRadius", "jme3test.light.TestLightRadius"),
new Test("bullet.TestSimplePhysics", "jme3test.bullet.TestSimplePhysics"),
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;
@Override
public void onCreate(Bundle savedInstanceState) {
logger.info("onCreate(" + savedInstanceState + ")");
super.onCreate(savedInstanceState);
//setContentView(R.layout.tests);
try {
useVA = true;
//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();
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) {
Intent intent = new Intent(view.getContext(), AndroidActivity.class);
intent.putExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME", finalClassName);
intent.putExtra(AndroidActivity.class.getName() + ".USE_VA", useVA);
startActivityForResult(intent, 0);
}
}
);
}
} catch (Exception exception) {
logger.warning("exception: " + exception);
exception.printStackTrace(System.err);
}
}
@Override @Override
public void onDestroy() { public void onClick(View view) {
logger.info("onDestroy()"); Intent intent = new Intent(view.getContext(), AndroidActivity.class);
super.onDestroy(); intent.putExtra(AndroidActivity.class.getName() + ".TEST_CLASS_NAME", finalClassName);
} intent.putExtra(AndroidActivity.class.getName() + ".USE_VA", useVA);
startActivityForResult(intent, 0);
}
});
}
} catch (Exception exception) {
logger.warning("exception: " + exception);
exception.printStackTrace(System.err);
}
}
@Override
public void onDestroy() {
logger.info("onDestroy()");
super.onDestroy();
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
} }
@Override
protected void onStart() {
super.onStart();
}
@Override @Override
protected void onStop() { protected void onStart() {
super.onStop(); super.onStart();
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { protected void onStop() {
MenuInflater inflater = getMenuInflater(); super.onStop();
//inflater.inflate(R.menu.options, menu); }
return true;
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onCreateOptionsMenu(Menu menu) {
/* MenuInflater inflater = getMenuInflater();
switch (item.getItemId()) { //inflater.inflate(R.menu.options, menu);
case R.id.about_button: return true;
about(); }
return true;
case R.id.quit_button:
quit();
return true;
default:
return super.onOptionsItemSelected(item);
}
*/
return false;
}
private void quit() { @Override
finish(); public boolean onOptionsItemSelected(MenuItem item) {
} /*
switch (item.getItemId()) {
private void about() { case R.id.about_button:
// Intent intent = new Intent(getView().getContext(), AboutActivity.class); about();
try { return true;
Intent intent = new Intent(); case R.id.quit_button:
intent.setClassName( quit();
"jme3test.android", return true;
"jme3test.android.AboutActivity" default:
); return super.onOptionsItemSelected(item);
startActivity(intent); }
} catch (Exception exception) { */
logger.warning("exception: " + exception); return false;
exception.printStackTrace(System.err); }
}
}
private void quit() {
finish();
}
private void about() {
// Intent intent = new Intent(getView().getContext(), AboutActivity.class);
try {
Intent intent = new Intent();
intent.setClassName(
"jme3test.android",
"jme3test.android.AboutActivity");
startActivity(intent);
} catch (Exception exception) {
logger.warning("exception: " + exception);
exception.printStackTrace(System.err);
}
}
} }

View File

@ -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.
*/
public static final int ONE = 1 << FIXED_POINT;
/**
* Half in fixed point.
*/
public static final int HALF = ONE >> 1;
/**
* Quarter circle resolution for trig functions (should be a power of
* 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.
*/
public static final int FULL_CIRCLE_MASK = QUARTER_CIRCLE * 4 - 1;
/**
* 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
* values are then shifted to match the actual fixed point used.
*/
private static final int TABLE_SHIFT = 30;
/**
* Equivalent to: sin((2 * PI) / (QUARTER_CIRCLE * 4))
* <p>
* Note: if either QUARTER_CIRCLE or TABLE_SHIFT is changed this value
* 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 SIN_PRECALC = 26350943;
/**
* 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
* radians, then shift the result by <code>TABLE_SHIFT</code>).
*/
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];
/**
* Scale value for indexing ATAN_TABLE[].
*/
private static final int ATAN_SHIFT;
/**
* Reverse atan lookup table.
*/
private static final byte[] ATAN_TABLE;
/**
* ATAN_TABLE.length
*/
private static final int ATAN_TABLE_LEN;
/** /*
* Half in fixed point. * Generates the tables and fills in any remaining static ints.
*/ */
public static final int HALF = ONE >> 1; 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
* Quarter circle resolution for trig functions (should be a power of int rotl = 0;
* two). This is the number of discrete steps in 90 degrees. int tan0 = tan(0);
*/ int tan1 = tan(1);
public static final int QUARTER_CIRCLE = 64; 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 {
* Mask used to limit angles to one revolution. If a quarter circle is 64 int i = 10;
* (i.e. 90 degrees is broken into 64 steps) then the mask is 255. for (int n = 1; n < STRING_DECIMAL_PLACES; n++) {
*/ i *= i;
public static final int FULL_CIRCLE_MASK = QUARTER_CIRCLE * 4 - 1; }
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;
/** /**
* The trig table is generated at a higher precision than the typical * Fixed can't be instantiated.
* 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. private Fixed() {
*/ }
private static final int TABLE_SHIFT = 30;
/** /**
* Equivalent to: sin((2 * PI) / (QUARTER_CIRCLE * 4)) * Returns an integer as a fixed point value.
* <p> */
* Note: if either QUARTER_CIRCLE or TABLE_SHIFT is changed this value public static int intToFixed(int n) {
* will need recalculating (put the above formular into a calculator set return n << FIXED_POINT;
* radians, then shift the result by <code>TABLE_SHIFT</code>). }
*/
private static final int SIN_PRECALC = 26350943;
/**
* 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
* radians, then shift the result by <code>TABLE_SHIFT</code>).
*/
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];
/**
* Scale value for indexing ATAN_TABLE[].
*/
private static final int ATAN_SHIFT;
/**
* Reverse atan lookup table.
*/
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
* 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.
*/
private Fixed() {}
/**
* Returns an integer as a fixed point value.
*/
public static int intToFixed(int n) {
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;
} }
} }

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
} }
} }

View File

@ -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;