Nehon 11 years ago
commit 4f6c061d4e
  1. 49
      CONTRIBUTING.md
  2. 2
      gradle.properties
  3. 4
      jme3-examples/src/main/java/jme3test/TestChooser.java
  4. 203
      jme3-ios/src/main/java/com/jme3/input/ios/IosInputHandler.java
  5. 191
      jme3-ios/src/main/java/com/jme3/input/ios/IosTouchHandler.java
  6. 121
      jme3-ios/src/main/java/com/jme3/input/ios/TouchEventPool.java
  7. 13
      jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java
  8. 76
      jme3-ios/src/main/java/com/jme3/util/RingBuffer.java
  9. 9
      jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainLodControl.java

@ -1,32 +1,57 @@
# How to contribute to jMonkeyEngine # How to contribute to jMonkeyEngine
First and foremost, you have to familiarize yourself with Git & GitHub. Dig through First and foremost, you have to familiarize yourself with Git & GitHub. Dig through
[help.github.com](https://help.github.com/) and [try.github.io](http://try.github.io/) if these are new topics for you. [help.github.com](https://help.github.com/) and [try.github.io](http://try.github.io/) if these are new topics for you. If you'd like to contribute with something other than code, just tell us about it and we'll figure something out.
If you'd like to contribute with something other than code, read this (WIP). ## Communication
## Getting Started Communication always comes first. **All** code changes and other contributions should start with the [forum](http://hub.jmonkeyengine.org/forum/). Make a thread to explain your change and show us the important bits of your code. If the code is too long to be posted within the forum’s code tags, please paste your code in a Gist or pastebin and link to the submission in your thread. You are required to register on our website in order to create threads.
Communication always comes first. All code changes should start with the [forum](http://hub.jmonkeyengine.org/forum/). Make a thread to explain your change and show us your code. If the code is too long to be posted within the forum’s code tags, please paste your code in a Gist or pastebin and link to the submission in your thread. You are required to register on our website in order to create threads. ### New Contributors
When you're ready to submit your code, just make a [pull request](https://help.github.com/articles/using-pull-requests). When you're ready to submit your code, just make a [pull request](https://help.github.com/articles/using-pull-requests).
## Core Contributors - Do not commit your code until you have received proper feedback.
- In your commit log message, please refer back to the originating forum thread (example) for a ‘full circle’ reference. Also please [reference related issues](https://help.github.com/articles/closing-issues-via-commit-messages) by typing the issue hashtag.
Developers in the Contributors team can push directly to Main instead of submitting pull requests. However:
- Do not commit your code until you have received proper feedback. In the case of jME3, explicit permission from a core developer is mandatory.
- In your commit log message, please refer back to the originating forum thread (example) for a ‘full circle’ reference.
- When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing. - When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing.
- If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks! - If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks!
**Note to Eclipse users:** The Eclipse [git client does not support https](http://hub.jmonkeyengine.org/forum/topic/problem-cloning-the-new-git-repository/#post-265594). The current workaround is to use the command line to clone the repository and then add local repository in Eclipse.
#### Core Contributors
Developers in the Contributors team can push directly to Main instead of submitting pull requests, however for new features it is often a good idea to do a pull request as a means to get a last code review.
## Building the engine
NEEDS ATTENTION: Gradle and whatnot.
## Best Practices
### Git essentials ### Git essentials
rebase... rebase...
### Code style ### Testing
### Reporting bugs general testing tips?
### Testing ### Code Quality
We generally abide by the standard Java Code Conventions. Besides that, just make an effort to write elegant code:
1. Handles errors gracefully
2. Only reinvents the wheel when there is a measurable benefit in doing so.
3. Has consistent naming conventions.
4. Has comments around ugly code explaining why it is ugly.
5. Compiles (or runs if interpreted) without warnings.
## Reporting bugs
1. Start by searching the forum and issue tracker for duplicates.
2. Create a new issue, explaining the problem in proper detail (templates pending).
## Documentation ## Documentation
- Edit the wiki
- Edit JavaDocs

@ -7,7 +7,7 @@ jmeVersionSuffix = -pre-alpha-svn
# specify if SDK and Native libraries get built # specify if SDK and Native libraries get built
buildSdkProject = true buildSdkProject = true
buildNativeProjects = true buildNativeProjects = false
# Path to android NDK for building native libraries # Path to android NDK for building native libraries
#ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7 #ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7

@ -84,6 +84,10 @@ public class TestChooser extends JDialog {
*/ */
public TestChooser() throws HeadlessException { public TestChooser() throws HeadlessException {
super((JFrame) null, "TestChooser"); super((JFrame) null, "TestChooser");
/** This listener ends application when window is closed (x button on top right corner of test chooser).
* @see issue#85 https://github.com/jMonkeyEngine/jmonkeyengine/issues/85
*/
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
} }
/** /**

@ -0,0 +1,203 @@
package com.jme3.input.ios;
import com.jme3.input.RawInputListener;
import com.jme3.input.TouchInput;
import com.jme3.input.event.InputEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import com.jme3.system.AppSettings;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
public class IosInputHandler implements TouchInput {
private static final Logger logger = Logger.getLogger(IosInputHandler.class.getName());
private final static int MAX_TOUCH_EVENTS = 1024;
// Custom settings
private boolean mouseEventsEnabled = true;
private boolean mouseEventsInvertX = false;
private boolean mouseEventsInvertY = false;
private boolean keyboardEventsEnabled = false;
private boolean dontSendHistory = false;
// Internal
private boolean initialized = false;
private RawInputListener listener = null;
private ConcurrentLinkedQueue<InputEvent> inputEventQueue = new ConcurrentLinkedQueue<InputEvent>();
private final TouchEventPool touchEventPool = new TouchEventPool(MAX_TOUCH_EVENTS);
private IosTouchHandler touchHandler;
private float scaleX = 1f;
private float scaleY = 1f;
private int width = 0;
private int height = 0;
public IosInputHandler() {
touchHandler = new IosTouchHandler(this);
}
@Override
public void initialize() {
touchEventPool.initialize();
if (touchHandler != null) {
touchHandler.initialize();
}
initialized = true;
}
@Override
public void update() {
logger.log(Level.FINE, "InputEvent update : {0}",
new Object[]{listener});
if (listener != null) {
InputEvent inputEvent;
while ((inputEvent = inputEventQueue.poll()) != null) {
if (inputEvent instanceof TouchEvent) {
listener.onTouchEvent((TouchEvent)inputEvent);
} else if (inputEvent instanceof MouseButtonEvent) {
listener.onMouseButtonEvent((MouseButtonEvent)inputEvent);
} else if (inputEvent instanceof MouseMotionEvent) {
listener.onMouseMotionEvent((MouseMotionEvent)inputEvent);
} else if (inputEvent instanceof KeyInputEvent) {
listener.onKeyEvent((KeyInputEvent)inputEvent);
}
}
}
}
@Override
public void destroy() {
initialized = false;
touchEventPool.destroy();
if (touchHandler != null) {
touchHandler.destroy();
}
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void setInputListener(RawInputListener listener) {
this.listener = listener;
}
@Override
public long getInputTimeNanos() {
return System.nanoTime();
}
@Override
public void setSimulateMouse(boolean simulate) {
this.mouseEventsEnabled = simulate;
}
@Override
public boolean getSimulateMouse() {
return mouseEventsEnabled;
}
@Override
public boolean isSimulateMouse() {
return mouseEventsEnabled;
}
@Override
public void setSimulateKeyboard(boolean simulate) {
this.keyboardEventsEnabled = simulate;
}
@Override
public void setOmitHistoricEvents(boolean dontSendHistory) {
this.dontSendHistory = dontSendHistory;
}
@Override
public void showVirtualKeyboard(boolean visible) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
// ----------------
public void loadSettings(AppSettings settings) {
// TODO: add simulate keyboard to settings
// keyboardEventsEnabled = true;
mouseEventsEnabled = true;//settings.isEmulateMouse();
mouseEventsInvertX = settings.isEmulateMouseFlipX();
mouseEventsInvertY = settings.isEmulateMouseFlipY();
// view width and height are 0 until the view is displayed on the screen
//if (view.getWidth() != 0 && view.getHeight() != 0) {
// scaleX = (float)settings.getWidth() / (float)view.getWidth();
// scaleY = (float)settings.getHeight() / (float)view.getHeight();
//}
scaleX = 1.0f;
scaleY = 1.0f;
width = settings.getWidth();
height = settings.getHeight();
logger.log(Level.FINE, "Setting input scaling, scaleX: {0}, scaleY: {1}, width: {2}, height: {3}",
new Object[]{scaleX, scaleY, width, height});
}
public boolean isMouseEventsInvertX() {
return mouseEventsInvertX;
}
public boolean isMouseEventsInvertY() {
return mouseEventsInvertY;
}
public float invertX(float origX) {
return getJmeX(width) - origX;
}
public float invertY(float origY) {
return getJmeY(height) - origY;
}
public float getJmeX(float origX) {
return origX * scaleX;
}
public float getJmeY(float origY) {
return origY * scaleY;
}
public TouchEvent getFreeTouchEvent() {
return touchEventPool.getNextFreeEvent();
}
public void addEvent(InputEvent event) {
inputEventQueue.add(event);
if (event instanceof TouchEvent) {
touchEventPool.storeEvent((TouchEvent)event);
}
}
// ----------------
public void injectTouchDown(int pointerId, long time, float x, float y) {
logger.log(Level.FINE, "Using input scaling, scaleX: {0}, scaleY: {1}, width: {2}, height: {3}",
new Object[]{scaleX, scaleY, width, height});
if (touchHandler != null) {
touchHandler.actionDown(pointerId, time, x, y);
}
}
public void injectTouchUp(int pointerId, long time, float x, float y) {
if (touchHandler != null) {
touchHandler.actionUp(pointerId, time, x, y);
}
}
public void injectTouchMove(int pointerId, long time, float x, float y) {
if (touchHandler != null) {
touchHandler.actionMove(pointerId, time, x, y);
}
}
}

@ -0,0 +1,191 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.input.ios;
import com.jme3.input.event.InputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import static com.jme3.input.event.TouchEvent.Type.DOWN;
import static com.jme3.input.event.TouchEvent.Type.MOVE;
import static com.jme3.input.event.TouchEvent.Type.UP;
import com.jme3.math.Vector2f;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* AndroidTouchHandler is the base class that receives touch inputs from the
* Android system and creates the TouchEvents for jME. This class is designed
* to handle the base touch events for Android rev 9 (Android 2.3). This is
* extended by other classes to add features that were introducted after
* Android rev 9.
*
* @author iwgeric
*/
public class IosTouchHandler {
private static final Logger logger = Logger.getLogger(IosTouchHandler.class.getName());
final private HashMap<Integer, Vector2f> lastPositions = new HashMap<Integer, Vector2f>();
protected int numPointers = 1;
protected IosInputHandler iosInput;
public IosTouchHandler(IosInputHandler iosInput) {
this.iosInput = iosInput;
}
public void initialize() {
}
public void destroy() {
}
public void actionDown(int pointerId, long time, float x, float y) {
logger.log(Level.FINE, "Inject input pointer: {0}, time: {1}, x: {2}, y: {3}",
new Object[]{pointerId, time, x, y});
float jmeX = iosInput.getJmeX(x);
float jmeY = iosInput.invertY(iosInput.getJmeY(y));
TouchEvent touch = iosInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.DOWN, jmeX, jmeY, 0, 0);
touch.setPointerId(pointerId);//TODO: pointer ID
touch.setTime(time);
touch.setPressure(1.0f);
//touch.setPressure(event.getPressure(pointerIndex)); //TODO: preassure
lastPositions.put(pointerId, new Vector2f(jmeX, jmeY));
processEvent(touch);
}
public void actionUp(int pointerId, long time, float x, float y) {
float jmeX = iosInput.getJmeX(x);
float jmeY = iosInput.invertY(iosInput.getJmeY(y));
TouchEvent touch = iosInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.UP, jmeX, jmeY, 0, 0);
touch.setPointerId(pointerId);//TODO: pointer ID
touch.setTime(time);
touch.setPressure(1.0f);
//touch.setPressure(event.getPressure(pointerIndex)); //TODO: preassure
lastPositions.remove(pointerId);
processEvent(touch);
}
public void actionMove(int pointerId, long time, float x, float y) {
float jmeX = iosInput.getJmeX(x);
float jmeY = iosInput.invertY(iosInput.getJmeY(y));
Vector2f lastPos = lastPositions.get(pointerId);
if (lastPos == null) {
lastPos = new Vector2f(jmeX, jmeY);
lastPositions.put(pointerId, lastPos);
}
float dX = jmeX - lastPos.x;
float dY = jmeY - lastPos.y;
if (dX != 0 || dY != 0) {
TouchEvent touch = iosInput.getFreeTouchEvent();
touch.set(TouchEvent.Type.MOVE, jmeX, jmeY, dX, dY);
touch.setPointerId(pointerId);
touch.setTime(time);
touch.setPressure(1.0f);
//touch.setPressure(event.getPressure(p));
lastPos.set(jmeX, jmeY);
processEvent(touch);
}
}
protected void processEvent(TouchEvent event) {
// Add the touch event
iosInput.addEvent(event);
// MouseEvents do not support multi-touch, so only evaluate 1 finger pointer events
if (iosInput.isSimulateMouse() && numPointers == 1) {
InputEvent mouseEvent = generateMouseEvent(event);
if (mouseEvent != null) {
// Add the mouse event
iosInput.addEvent(mouseEvent);
}
}
}
// TODO: Ring Buffer for mouse events?
protected InputEvent generateMouseEvent(TouchEvent event) {
InputEvent inputEvent = null;
int newX;
int newY;
int newDX;
int newDY;
if (iosInput.isMouseEventsInvertX()) {
newX = (int) (iosInput.invertX(event.getX()));
newDX = (int)event.getDeltaX() * -1;
} else {
newX = (int) event.getX();
newDX = (int)event.getDeltaX();
}
if (iosInput.isMouseEventsInvertY()) {
newY = (int) (iosInput.invertY(event.getY()));
newDY = (int)event.getDeltaY() * -1;
} else {
newY = (int) event.getY();
newDY = (int)event.getDeltaY();
}
switch (event.getType()) {
case DOWN:
// Handle mouse down event
inputEvent = new MouseButtonEvent(0, true, newX, newY);
inputEvent.setTime(event.getTime());
break;
case UP:
// Handle mouse up event
inputEvent = new MouseButtonEvent(0, false, newX, newY);
inputEvent.setTime(event.getTime());
break;
case HOVER_MOVE:
case MOVE:
inputEvent = new MouseMotionEvent(newX, newY, newDX, newDY, (int)event.getScaleSpan(), (int)event.getDeltaScaleSpan());
inputEvent.setTime(event.getTime());
break;
}
return inputEvent;
}
}

@ -0,0 +1,121 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.input.ios;
import com.jme3.input.event.TouchEvent;
import com.jme3.util.RingBuffer;
import java.util.logging.Logger;
/**
* TouchEventPool provides a RingBuffer of jME TouchEvents to help with garbage
* collection on Android. Each TouchEvent is stored in the RingBuffer and is
* reused if the TouchEvent has been consumed.
*
* If a TouchEvent has not been consumed, it is placed back into the pool at the
* end for later use. If a TouchEvent has been consumed, it is reused to avoid
* creating lots of little objects.
*
* If the pool is full of unconsumed events, then a new event is created and provided.
*
*
* @author iwgeric
*/
public class TouchEventPool {
private static final Logger logger = Logger.getLogger(TouchEventPool.class.getName());
private final RingBuffer<TouchEvent> eventPool;
private final int maxEvents;
public TouchEventPool (int maxEvents) {
eventPool = new RingBuffer<TouchEvent>(maxEvents);
this.maxEvents = maxEvents;
}
public void initialize() {
TouchEvent newEvent;
while (!eventPool.isEmpty()) {
eventPool.pop();
}
for (int i = 0; i < maxEvents; i++) {
newEvent = new TouchEvent();
newEvent.setConsumed();
eventPool.push(newEvent);
}
}
public void destroy() {
// Clean up queues
while (!eventPool.isEmpty()) {
eventPool.pop();
}
}
/**
* Fetches a touch event from the reuse pool
*
* @return a usable TouchEvent
*/
public TouchEvent getNextFreeEvent() {
TouchEvent evt = null;
int curSize = eventPool.size();
while (curSize > 0) {
evt = (TouchEvent)eventPool.pop();
if (evt.isConsumed()) {
break;
} else {
eventPool.push(evt);
evt = null;
}
curSize--;
}
if (evt == null) {
logger.warning("eventPool full of unconsumed events");
evt = new TouchEvent();
}
return evt;
}
/**
* Stores the TouchEvent back in the pool for later reuse. It is only reused
* if the TouchEvent has been consumed.
*
* @param event TouchEvent to store for later use if consumed.
*/
public void storeEvent(TouchEvent event) {
if (eventPool.size() < maxEvents) {
eventPool.push(event);
} else {
logger.warning("eventPool full");
}
}
}

@ -37,6 +37,7 @@ import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput; import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.ios.IGLESShaderRenderer; import com.jme3.renderer.ios.IGLESShaderRenderer;
import com.jme3.system.*; import com.jme3.system.*;
import com.jme3.input.ios.IosInputHandler;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -56,6 +57,7 @@ public class IGLESContext implements JmeContext {
protected IGLESShaderRenderer renderer; protected IGLESShaderRenderer renderer;
protected Timer timer; protected Timer timer;
protected SystemListener listener; protected SystemListener listener;
protected IosInputHandler input;
protected int minFrameDuration = 0; // No FPS cap protected int minFrameDuration = 0; // No FPS cap
public IGLESContext() { public IGLESContext() {
@ -71,12 +73,9 @@ public class IGLESContext implements JmeContext {
public void setSettings(AppSettings settings) { public void setSettings(AppSettings settings) {
logger.log(Level.FINE, "IGLESContext setSettings"); logger.log(Level.FINE, "IGLESContext setSettings");
this.settings.copyFrom(settings); this.settings.copyFrom(settings);
/* if (input != null) {
if (androidInput != null) { input.loadSettings(settings);
androidInput.loadSettings(settings);
} }
*/
} }
@Override @Override
@ -119,8 +118,7 @@ public class IGLESContext implements JmeContext {
@Override @Override
public TouchInput getTouchInput() { public TouchInput getTouchInput() {
//return androidInput; return input;
return null;// new DummyTouchInput();
} }
@Override @Override
@ -153,6 +151,7 @@ public class IGLESContext implements JmeContext {
public void create(boolean waitFor) { public void create(boolean waitFor) {
logger.log(Level.FINE, "IGLESContext create"); logger.log(Level.FINE, "IGLESContext create");
renderer = new IGLESShaderRenderer(); renderer = new IGLESShaderRenderer();
input = new IosInputHandler();
timer = new NanoTimer(); timer = new NanoTimer();
//synchronized (createdLock){ //synchronized (createdLock){

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

@ -160,11 +160,10 @@ public class TerrainLodControl extends AbstractControl {
} }
if (cameras != null) { if (cameras != null) {
if (cameraLocations.isEmpty() && !cameras.isEmpty()) { cameraLocations.clear();
for (Camera c : cameras) // populate them for (Camera c : cameras) // populate them
{ {
cameraLocations.add(c.getLocation()); cameraLocations.add(c.getLocation());
}
} }
updateLOD(cameraLocations, lodCalculator); updateLOD(cameraLocations, lodCalculator);
} }

Loading…
Cancel
Save