rename vtm-gdx-*
This commit is contained in:
@@ -0,0 +1,466 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package com.badlogic.gdx.backends.gwt;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.badlogic.gdx.Application;
|
||||
import com.badlogic.gdx.ApplicationListener;
|
||||
import com.badlogic.gdx.Audio;
|
||||
import com.badlogic.gdx.Files;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Graphics;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.LifecycleListener;
|
||||
import com.badlogic.gdx.Net;
|
||||
import com.badlogic.gdx.Preferences;
|
||||
import com.badlogic.gdx.backends.gwt.preloader.Preloader;
|
||||
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
|
||||
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Clipboard;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import com.google.gwt.core.client.EntryPoint;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
|
||||
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.InlineHTML;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
|
||||
/**
|
||||
* Implementation of an {@link Application} based on GWT. Clients have to
|
||||
* override {@link #getConfig()} and {@link #getApplicationListener()}. Clients
|
||||
* can override the default loading screen via {@link #getPreloaderCallback()}
|
||||
* and implement any loading screen drawing via GWT widgets.
|
||||
*
|
||||
* @author mzechner
|
||||
*/
|
||||
public abstract class GwtApplication implements EntryPoint, Application {
|
||||
private final static Logger log = LoggerFactory.getLogger(GwtApplication.class);
|
||||
|
||||
private ApplicationListener listener;
|
||||
private GwtApplicationConfiguration config;
|
||||
private GwtGraphics graphics;
|
||||
private GwtInput input;
|
||||
private GwtNet net;
|
||||
private Panel root = null;
|
||||
private Array<Runnable> runnables = new Array<Runnable>();
|
||||
private Array<Runnable> runnablesHelper = new Array<Runnable>();
|
||||
private Array<LifecycleListener> lifecycleListeners = new Array<LifecycleListener>();
|
||||
private int lastWidth;
|
||||
private int lastHeight;
|
||||
Preloader preloader;
|
||||
private static AgentInfo agentInfo;
|
||||
private ObjectMap<String, Preferences> prefs = new ObjectMap<String, Preferences>();
|
||||
|
||||
/** @return the configuration for the {@link GwtApplication}. */
|
||||
public abstract GwtApplicationConfiguration getConfig();
|
||||
|
||||
public String getPreloaderBaseURL() {
|
||||
return GWT.getHostPageBaseURL() + "assets/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onModuleLoad() {
|
||||
GwtApplication.agentInfo = computeAgentInfo();
|
||||
this.listener = getApplicationListener();
|
||||
this.config = getConfig();
|
||||
|
||||
if (config.rootPanel != null) {
|
||||
this.root = config.rootPanel;
|
||||
} else {
|
||||
Element element = Document.get().getElementById("embed-" + GWT.getModuleName());
|
||||
if (element == null) {
|
||||
VerticalPanel panel = new VerticalPanel();
|
||||
panel.setWidth("" + config.width + "px");
|
||||
panel.setHeight("" + config.height + "px");
|
||||
panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
RootPanel.get().add(panel);
|
||||
RootPanel.get().setWidth("" + config.width + "px");
|
||||
RootPanel.get().setHeight("" + config.height + "px");
|
||||
this.root = panel;
|
||||
} else {
|
||||
VerticalPanel panel = new VerticalPanel();
|
||||
panel.setWidth("" + config.width + "px");
|
||||
panel.setHeight("" + config.height + "px");
|
||||
panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
|
||||
panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
element.appendChild(panel.getElement());
|
||||
root = panel;
|
||||
}
|
||||
}
|
||||
|
||||
final PreloaderCallback callback = getPreloaderCallback();
|
||||
preloader = createPreloader();
|
||||
preloader.preload("assets.txt", new PreloaderCallback() {
|
||||
@Override
|
||||
public void error(String file) {
|
||||
callback.error(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(PreloaderState state) {
|
||||
callback.update(state);
|
||||
if (state.hasEnded()) {
|
||||
getRootPanel().clear();
|
||||
setupLoop();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void setupLoop() {
|
||||
Gdx.app = this;
|
||||
// setup modules
|
||||
try {
|
||||
graphics = new GwtGraphics(root, config);
|
||||
} catch (Throwable e) {
|
||||
root.clear();
|
||||
root.add(new Label("Sorry, your browser doesn't seem to support WebGL"));
|
||||
return;
|
||||
}
|
||||
lastWidth = graphics.getWidth();
|
||||
lastHeight = graphics.getHeight();
|
||||
//Gdx.audio = new GwtAudio();
|
||||
Gdx.graphics = graphics;
|
||||
Gdx.gl20 = graphics.getGL20();
|
||||
Gdx.gl = Gdx.gl20;
|
||||
Gdx.files = new GwtFiles(preloader);
|
||||
this.input = new GwtInput(graphics.canvas);
|
||||
Gdx.input = this.input;
|
||||
this.net = new GwtNet();
|
||||
Gdx.net = this.net;
|
||||
|
||||
// tell listener about app creation
|
||||
try {
|
||||
listener.create();
|
||||
listener.resize(graphics.getWidth(), graphics.getHeight());
|
||||
} catch (Throwable t) {
|
||||
error("GwtApplication", "exception: " + t.getMessage(), t);
|
||||
t.printStackTrace();
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
|
||||
Gdx.gl.glClearColor(1, 1, 1, 1);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
final int frameTime = (int) ((1f / config.fps) * 1000);
|
||||
|
||||
// setup rendering timer
|
||||
new Timer() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
mainLoop(this, frameTime);
|
||||
} catch (Throwable t) {
|
||||
error("GwtApplication", "exception: " + t.getMessage(), t);
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
//}.scheduleRepeating((int) ((1f / config.fps) * 1000));
|
||||
}.schedule(1);
|
||||
}
|
||||
|
||||
void mainLoop(Timer timer, int frameTime) {
|
||||
graphics.update();
|
||||
if (Gdx.graphics.getWidth() != lastWidth || Gdx.graphics.getHeight() != lastHeight) {
|
||||
GwtApplication.this.listener.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
lastWidth = graphics.getWidth();
|
||||
lastHeight = graphics.getHeight();
|
||||
Gdx.gl.glViewport(0, 0, lastWidth, lastHeight);
|
||||
}
|
||||
runnablesHelper.addAll(runnables);
|
||||
runnables.clear();
|
||||
for (int i = 0; i < runnablesHelper.size; i++) {
|
||||
runnablesHelper.get(i).run();
|
||||
}
|
||||
runnablesHelper.clear();
|
||||
listener.render();
|
||||
input.justTouched = false;
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
int diff = (int) (now - graphics.lastTimeStamp);
|
||||
diff = frameTime - diff;
|
||||
timer.schedule(diff > 5 ? diff : 5);
|
||||
}
|
||||
|
||||
public Panel getRootPanel() {
|
||||
return root;
|
||||
}
|
||||
|
||||
long loadStart = TimeUtils.nanoTime();
|
||||
|
||||
public Preloader createPreloader() {
|
||||
return new Preloader(getPreloaderBaseURL());
|
||||
}
|
||||
|
||||
public PreloaderCallback getPreloaderCallback() {
|
||||
final Panel preloaderPanel = new VerticalPanel();
|
||||
preloaderPanel.setStyleName("gdx-preloader");
|
||||
final Image logo = new Image(GWT.getModuleBaseURL() + "logo.png");
|
||||
logo.setStyleName("logo");
|
||||
preloaderPanel.add(logo);
|
||||
final Panel meterPanel = new SimplePanel();
|
||||
meterPanel.setStyleName("gdx-meter");
|
||||
meterPanel.addStyleName("red");
|
||||
final InlineHTML meter = new InlineHTML();
|
||||
final Style meterStyle = meter.getElement().getStyle();
|
||||
meterStyle.setWidth(0, Unit.PCT);
|
||||
meterPanel.add(meter);
|
||||
preloaderPanel.add(meterPanel);
|
||||
getRootPanel().add(preloaderPanel);
|
||||
return new PreloaderCallback() {
|
||||
|
||||
@Override
|
||||
public void error(String file) {
|
||||
System.out.println("error: " + file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(PreloaderState state) {
|
||||
meterStyle.setWidth(100f * state.getProgress(), Unit.PCT);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics getGraphics() {
|
||||
return graphics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Audio getAudio() {
|
||||
return Gdx.audio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Input getInput() {
|
||||
return Gdx.input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Files getFiles() {
|
||||
return Gdx.files;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Net getNet() {
|
||||
return Gdx.net;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String tag, String message) {
|
||||
log.info("{} : {}", tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String tag, String message, Throwable exception) {
|
||||
log.info("{} : {}\n{}", tag, exception, getStackTrace(exception));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String tag, String message) {
|
||||
log.error("{} : {}", tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String tag, String message, Throwable exception) {
|
||||
log.error("{} : {}\n{}", tag, message, getStackTrace(exception));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String tag, String message) {
|
||||
log.debug("{} : {}", tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String tag, String message, Throwable exception) {
|
||||
log.debug("{} : {}\n{}", tag, message, getStackTrace(exception));
|
||||
}
|
||||
|
||||
private String getStackTrace(Throwable e) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (StackTraceElement trace : e.getStackTrace()) {
|
||||
buffer.append(trace.toString() + "\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogLevel(int logLevel) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLogLevel() {
|
||||
return LOG_DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationType getType() {
|
||||
return ApplicationType.WebGL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getJavaHeap() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNativeHeap() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Preferences getPreferences(String name) {
|
||||
Preferences pref = prefs.get(name);
|
||||
if (pref == null) {
|
||||
pref = new GwtPreferences(name);
|
||||
prefs.put(name, pref);
|
||||
}
|
||||
return pref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard getClipboard() {
|
||||
return new Clipboard() {
|
||||
@Override
|
||||
public String getContents() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContents(String content) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postRunnable(Runnable runnable) {
|
||||
runnables.add(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains precomputed information on the user-agent. Useful for dealing
|
||||
* with browser and OS behavioral differences. Kindly
|
||||
* borrowed from PlayN
|
||||
*/
|
||||
public static AgentInfo agentInfo() {
|
||||
return agentInfo;
|
||||
}
|
||||
|
||||
/** kindly borrowed from PlayN **/
|
||||
private static native AgentInfo computeAgentInfo() /*-{
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
return {
|
||||
// browser type flags
|
||||
isFirefox : userAgent.indexOf("firefox") != -1,
|
||||
isChrome : userAgent.indexOf("chrome") != -1,
|
||||
isSafari : userAgent.indexOf("safari") != -1,
|
||||
isOpera : userAgent.indexOf("opera") != -1,
|
||||
isIE : userAgent.indexOf("msie") != -1,
|
||||
// OS type flags
|
||||
isMacOS : userAgent.indexOf("mac") != -1,
|
||||
isLinux : userAgent.indexOf("linux") != -1,
|
||||
isWindows : userAgent.indexOf("win") != -1
|
||||
};
|
||||
}-*/;
|
||||
|
||||
/** Returned by {@link #agentInfo}. Kindly borrowed from PlayN. */
|
||||
public static class AgentInfo extends JavaScriptObject {
|
||||
public final native boolean isFirefox() /*-{
|
||||
return this.isFirefox;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isChrome() /*-{
|
||||
return this.isChrome;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isSafari() /*-{
|
||||
return this.isSafari;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isOpera() /*-{
|
||||
return this.isOpera;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isIE() /*-{
|
||||
return this.isIE;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isMacOS() /*-{
|
||||
return this.isMacOS;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isLinux() /*-{
|
||||
return this.isLinux;
|
||||
}-*/;
|
||||
|
||||
public final native boolean isWindows() /*-{
|
||||
return this.isWindows;
|
||||
}-*/;
|
||||
|
||||
protected AgentInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return preloader.baseUrl;
|
||||
}
|
||||
|
||||
public Preloader getPreloader() {
|
||||
return preloader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLifecycleListener(LifecycleListener listener) {
|
||||
synchronized (lifecycleListeners) {
|
||||
lifecycleListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLifecycleListener(LifecycleListener listener) {
|
||||
synchronized (lifecycleListeners) {
|
||||
lifecycleListeners.removeValue(listener, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package com.badlogic.gdx.backends.gwt;
|
||||
|
||||
import org.oscim.gdx.client.GwtGLAdapter;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Graphics;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.GL30;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.google.gwt.canvas.client.Canvas;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.logical.shared.ResizeEvent;
|
||||
import com.google.gwt.event.logical.shared.ResizeHandler;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.webgl.client.WebGLContextAttributes;
|
||||
import com.google.gwt.webgl.client.WebGLRenderingContext;
|
||||
|
||||
public class GwtGraphics implements Graphics {
|
||||
CanvasElement canvas;
|
||||
WebGLRenderingContext context;
|
||||
GL20 gl;
|
||||
String extensions;
|
||||
float fps = 0;
|
||||
long lastTimeStamp = System.currentTimeMillis();
|
||||
float deltaTime = 0;
|
||||
float time = 0;
|
||||
int frames;
|
||||
GwtApplicationConfiguration config;
|
||||
boolean inFullscreenMode = false;
|
||||
double pixelRatio;
|
||||
|
||||
public GwtGraphics(Panel root, final GwtApplicationConfiguration config) {
|
||||
Canvas canvasWidget = Canvas.createIfSupported();
|
||||
if (canvasWidget == null)
|
||||
throw new GdxRuntimeException("Canvas not supported");
|
||||
canvas = canvasWidget.getCanvasElement();
|
||||
root.add(canvasWidget);
|
||||
|
||||
this.pixelRatio = getDevicePixelRatioJSNI();
|
||||
|
||||
canvas.setWidth((int) (config.width * pixelRatio));
|
||||
canvas.setHeight((int) (config.height * pixelRatio));
|
||||
|
||||
canvas.getStyle().setWidth(config.width, Unit.PX);
|
||||
canvas.getStyle().setHeight(config.height, Unit.PX);
|
||||
this.config = config;
|
||||
|
||||
WebGLContextAttributes attributes = WebGLContextAttributes.create();
|
||||
attributes.setAntialias(config.antialiasing);
|
||||
attributes.setStencil(config.stencil);
|
||||
attributes.setAlpha(false);
|
||||
attributes.setPremultipliedAlpha(false);
|
||||
|
||||
context = WebGLRenderingContext.getContext(canvas, attributes);
|
||||
context.viewport(0, 0, config.width, config.height);
|
||||
|
||||
// this actually *enables* the option to use std derivatives in shader..
|
||||
if (context.getExtension("OES_standard_derivatives") == null) {
|
||||
|
||||
}
|
||||
|
||||
if (context.getExtension("WEBKIT_WEBGL_depth_texture") == null) {
|
||||
|
||||
}
|
||||
|
||||
this.gl = config.useDebugGL ? new GwtGL20Debug(context) : new GwtGLAdapter(context);
|
||||
canvas.setId("gdx-canvas");
|
||||
|
||||
Window.addResizeHandler(new ResizeHandler() {
|
||||
@Override
|
||||
public void onResize(ResizeEvent event) {
|
||||
int w = config.rootPanel.getOffsetWidth();
|
||||
int h = config.rootPanel.getOffsetHeight();
|
||||
|
||||
canvas.getStyle().setWidth(w, Unit.PX);
|
||||
canvas.getStyle().setHeight(h, Unit.PX);
|
||||
|
||||
Gdx.app.log("onResize", w + "/" + h);
|
||||
canvas.setWidth((int) (w * pixelRatio));
|
||||
canvas.setHeight((int) (h * pixelRatio));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static native double getDevicePixelRatioJSNI() /*-{
|
||||
return $wnd.devicePixelRatio || 1.0;
|
||||
}-*/;
|
||||
|
||||
public static native int getWindowWidthJSNI() /*-{
|
||||
return $wnd.innerWidth;
|
||||
}-*/;
|
||||
|
||||
public static native int getWindowHeightJSNI() /*-{
|
||||
return $wnd.innerHeight;
|
||||
}-*/;
|
||||
|
||||
public WebGLRenderingContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GL20 getGL20() {
|
||||
return gl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return canvas.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return canvas.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDeltaTime() {
|
||||
return deltaTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFramesPerSecond() {
|
||||
return (int) fps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsType getType() {
|
||||
return GraphicsType.WebGL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPpiX() {
|
||||
return 96;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPpiY() {
|
||||
return 96;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPpcX() {
|
||||
return 96 / 2.54f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPpcY() {
|
||||
return 96 / 2.54f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDisplayModeChange() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DisplayMode[] getDisplayModes() {
|
||||
return new DisplayMode[] { new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60,
|
||||
8) {
|
||||
} };
|
||||
}
|
||||
|
||||
private native int getScreenWidthJSNI() /*-{
|
||||
return $wnd.screen.width;
|
||||
}-*/;
|
||||
|
||||
private native int getScreenHeightJSNI() /*-{
|
||||
return $wnd.screen.height;
|
||||
}-*/;
|
||||
|
||||
private native boolean isFullscreenJSNI() /*-{
|
||||
if ("webkitIsFullScreen" in $doc) {
|
||||
return $doc.webkitIsFullScreen;
|
||||
}
|
||||
if ("mozFullScreen" in $doc) {
|
||||
return $doc.mozFullScreen;
|
||||
}
|
||||
return false
|
||||
}-*/;
|
||||
|
||||
private void fullscreenChanged() {
|
||||
if (!isFullscreen()) {
|
||||
canvas.setWidth(config.width);
|
||||
canvas.setHeight(config.height);
|
||||
}
|
||||
}
|
||||
|
||||
private native boolean setFullscreenJSNI(GwtGraphics graphics, CanvasElement element) /*-{
|
||||
if (element.webkitRequestFullScreen) {
|
||||
element.width = $wnd.screen.width;
|
||||
element.height = $wnd.screen.height;
|
||||
element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
|
||||
$doc
|
||||
.addEventListener(
|
||||
"webkitfullscreenchange",
|
||||
function() {
|
||||
graphics.@com.badlogic.gdx.backends.gwt.GwtGraphics::fullscreenChanged()();
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
if (element.mozRequestFullScreen) {
|
||||
element.width = $wnd.screen.width;
|
||||
element.height = $wnd.screen.height;
|
||||
element.mozRequestFullScreen();
|
||||
$doc
|
||||
.addEventListener(
|
||||
"mozfullscreenchange",
|
||||
function() {
|
||||
graphics.@com.badlogic.gdx.backends.gwt.GwtGraphics::fullscreenChanged()();
|
||||
}, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
private native void exitFullscreen() /*-{
|
||||
if ($doc.webkitExitFullscreen)
|
||||
$doc.webkitExitFullscreen();
|
||||
if ($doc.mozExitFullscreen)
|
||||
$doc.mozExitFullscreen();
|
||||
}-*/;
|
||||
|
||||
@Override
|
||||
public DisplayMode getDesktopDisplayMode() {
|
||||
return new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDisplayMode(DisplayMode displayMode) {
|
||||
if (displayMode.width != getScreenWidthJSNI()
|
||||
&& displayMode.height != getScreenHeightJSNI())
|
||||
return false;
|
||||
return setFullscreenJSNI(this, canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDisplayMode(int width, int height, boolean fullscreen) {
|
||||
if (fullscreen) {
|
||||
if (width != getScreenWidthJSNI() && height != getScreenHeightJSNI())
|
||||
return false;
|
||||
return setFullscreenJSNI(this, canvas);
|
||||
} else {
|
||||
if (isFullscreenJSNI())
|
||||
exitFullscreen();
|
||||
canvas.setWidth(width);
|
||||
canvas.setHeight(height);
|
||||
canvas.getStyle().setWidth(width, Unit.PX);
|
||||
canvas.getStyle().setHeight(height, Unit.PX);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferFormat getBufferFormat() {
|
||||
return new BufferFormat(8, 8, 8, 0, 16, config.stencil ? 8 : 0, 0, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsExtension(String extension) {
|
||||
if (extensions == null)
|
||||
extensions = Gdx.gl.glGetString(GL20.GL_EXTENSIONS);
|
||||
return extensions.contains(extension);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
long currTimeStamp = System.currentTimeMillis();
|
||||
deltaTime = (currTimeStamp - lastTimeStamp) / 1000.0f;
|
||||
lastTimeStamp = currTimeStamp;
|
||||
time += deltaTime;
|
||||
frames++;
|
||||
if (time > 1) {
|
||||
this.fps = frames;
|
||||
time = 0;
|
||||
frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(String title) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVSync(boolean vsync) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getDensity() {
|
||||
return 96.0f / 160;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousRendering(boolean isContinuous) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinuousRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestRendering() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRawDeltaTime() {
|
||||
return getDeltaTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullscreen() {
|
||||
return isFullscreenJSNI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGL30Available() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GL30 getGL30() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,947 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package com.badlogic.gdx.backends.gwt;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.InputProcessor;
|
||||
import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox;
|
||||
import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox.TextInputDialogListener;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.core.client.JsArray;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.dom.client.Touch;
|
||||
import com.google.gwt.event.dom.client.KeyCodes;
|
||||
|
||||
public class GwtInput implements Input {
|
||||
boolean justTouched = false;
|
||||
private boolean[] touched = new boolean[20];
|
||||
private int[] touchX = new int[20];
|
||||
private int[] touchY = new int[20];
|
||||
private int[] deltaX = new int[20];
|
||||
private int[] deltaY = new int[20];
|
||||
Set<Integer> pressedButtons = new HashSet<Integer>();
|
||||
Set<Integer> pressedKeys = new HashSet<Integer>();
|
||||
InputProcessor processor;
|
||||
char lastKeyCharPressed;
|
||||
float keyRepeatTimer;
|
||||
long currentEventTimeStamp;
|
||||
final CanvasElement canvas;
|
||||
boolean hasFocus = true;
|
||||
|
||||
public GwtInput(CanvasElement canvas) {
|
||||
this.canvas = canvas;
|
||||
hookEvents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAccelerometerX() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAccelerometerY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAccelerometerZ() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return touchX[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX(int pointer) {
|
||||
return touchX[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaX() {
|
||||
return deltaX[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaX(int pointer) {
|
||||
return deltaX[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return touchY[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY(int pointer) {
|
||||
return touchY[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaY() {
|
||||
return deltaY[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaY(int pointer) {
|
||||
return deltaY[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTouched() {
|
||||
return touched[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean justTouched() {
|
||||
return justTouched;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTouched(int pointer) {
|
||||
return touched[pointer];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isButtonPressed(int button) {
|
||||
return button == Buttons.LEFT && touched[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isKeyPressed(int key) {
|
||||
if (key == Keys.ANY_KEY)
|
||||
return pressedKeys.size() > 0;
|
||||
return pressedKeys.contains(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTextInput(TextInputListener listener, String title, String text) {
|
||||
TextInputDialogBox dialog = new TextInputDialogBox(title, text, null);
|
||||
final TextInputListener capturedListener = listener;
|
||||
dialog.setListener(new TextInputDialogListener() {
|
||||
@Override
|
||||
public void onPositive(String text) {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.input(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNegative() {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.canceled();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPlaceholderTextInput(TextInputListener listener, String title, String placeholder) {
|
||||
TextInputDialogBox dialog = new TextInputDialogBox(title, null, placeholder);
|
||||
final TextInputListener capturedListener = listener;
|
||||
dialog.setListener(new TextInputDialogListener() {
|
||||
@Override
|
||||
public void onPositive(String text) {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.input(text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNegative() {
|
||||
if (capturedListener != null) {
|
||||
capturedListener.canceled();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnscreenKeyboardVisible(boolean visible) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vibrate(int milliseconds) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void vibrate(long[] pattern, int repeat) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelVibrate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAzimuth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPitch() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRoll() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getRotationMatrix(float[] matrix) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentEventTime() {
|
||||
return currentEventTimeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCatchBackKey(boolean catchBack) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCatchMenuKey(boolean catchMenu) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputProcessor(InputProcessor processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputProcessor getInputProcessor() {
|
||||
return processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPeripheralAvailable(Peripheral peripheral) {
|
||||
if (peripheral == Peripheral.Accelerometer)
|
||||
return false;
|
||||
if (peripheral == Peripheral.Compass)
|
||||
return false;
|
||||
if (peripheral == Peripheral.HardwareKeyboard)
|
||||
return true;
|
||||
if (peripheral == Peripheral.MultitouchScreen)
|
||||
return isTouchScreen();
|
||||
if (peripheral == Peripheral.OnscreenKeyboard)
|
||||
return false;
|
||||
if (peripheral == Peripheral.Vibrator)
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRotation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Orientation getNativeOrientation() {
|
||||
return Orientation.Landscape;
|
||||
}
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
* @return is Cursor catched
|
||||
*/
|
||||
private native boolean isCursorCatchedJSNI() /*-{
|
||||
if (!navigator.pointer) {
|
||||
navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
|
||||
}
|
||||
if (navigator.pointer) {
|
||||
if (typeof (navigator.pointer.isLocked) === "boolean") {
|
||||
// Chrome initially launched with this interface
|
||||
return navigator.pointer.isLocked;
|
||||
} else if (typeof (navigator.pointer.isLocked) === "function") {
|
||||
// Some older builds might provide isLocked as a function
|
||||
return navigator.pointer.isLocked();
|
||||
} else if (typeof (navigator.pointer.islocked) === "function") {
|
||||
// For compatibility with early Firefox build
|
||||
return navigator.pointer.islocked();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
* @param element Canvas
|
||||
*/
|
||||
private native void setCursorCatchedJSNI(CanvasElement element) /*-{
|
||||
// Navigator pointer is not the right interface according to spec.
|
||||
// Here for backwards compatibility only
|
||||
if (!navigator.pointer) {
|
||||
navigator.pointer = navigator.webkitPointer || navigator.mozPointer;
|
||||
}
|
||||
// element.requestPointerLock
|
||||
if (!element.requestPointerLock) {
|
||||
element.requestPointerLock = (function() {
|
||||
return element.webkitRequestPointerLock
|
||||
|| element.mozRequestPointerLock || function() {
|
||||
if (navigator.pointer) {
|
||||
navigator.pointer.lock(element);
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
element.requestPointerLock();
|
||||
}-*/;
|
||||
|
||||
/** from https://github.com/toji/game-shim/blob/master/game-shim.js */
|
||||
private native void exitCursorCatchedJSNI() /*-{
|
||||
if (!$doc.exitPointerLock) {
|
||||
$doc.exitPointerLock = (function() {
|
||||
return $doc.webkitExitPointerLock || $doc.mozExitPointerLock
|
||||
|| function() {
|
||||
if (navigator.pointer) {
|
||||
var elem = this;
|
||||
navigator.pointer.unlock();
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
* @param event JavaScript Mouse Event
|
||||
* @return movement in x direction
|
||||
*/
|
||||
private native float getMovementXJSNI(NativeEvent event) /*-{
|
||||
return event.movementX || event.webkitMovementX || 0;
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* from https://github.com/toji/game-shim/blob/master/game-shim.js
|
||||
*
|
||||
* @param event JavaScript Mouse Event
|
||||
* @return movement in y direction
|
||||
*/
|
||||
private native float getMovementYJSNI(NativeEvent event) /*-{
|
||||
return event.movementY || event.webkitMovementY || 0;
|
||||
}-*/;
|
||||
|
||||
private static native boolean isTouchScreen() /*-{
|
||||
return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
|
||||
}-*/;
|
||||
|
||||
/**
|
||||
* works only for Chrome > Version 18 with enabled Mouse Lock enable in
|
||||
* about:flags or start Chrome with the
|
||||
* --enable-pointer-lock flag
|
||||
*/
|
||||
@Override
|
||||
public void setCursorCatched(boolean catched) {
|
||||
if (catched)
|
||||
setCursorCatchedJSNI(canvas);
|
||||
else
|
||||
exitCursorCatchedJSNI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCursorCatched() {
|
||||
return isCursorCatchedJSNI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorPosition(int x, int y) {
|
||||
// FIXME??
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorImage(Pixmap pixmap, int xHotspot, int yHotspot) {
|
||||
}
|
||||
|
||||
// kindly borrowed from our dear playn friends...
|
||||
static native void addEventListener(JavaScriptObject target, String name, GwtInput handler,
|
||||
boolean capture) /*-{
|
||||
target
|
||||
.addEventListener(
|
||||
name,
|
||||
function(e) {
|
||||
handler.@com.badlogic.gdx.backends.gwt.GwtInput::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e);
|
||||
}, capture);
|
||||
}-*/;
|
||||
|
||||
private static native float getMouseWheelVelocity(NativeEvent evt) /*-{
|
||||
var delta = 0.0;
|
||||
var agentInfo = @com.badlogic.gdx.backends.gwt.GwtApplication::agentInfo()();
|
||||
|
||||
if (agentInfo.isFirefox) {
|
||||
if (agentInfo.isMacOS) {
|
||||
delta = 1.0 * evt.detail;
|
||||
} else {
|
||||
delta = 1.0 * evt.detail / 3;
|
||||
}
|
||||
} else if (agentInfo.isOpera) {
|
||||
if (agentInfo.isLinux) {
|
||||
delta = -1.0 * evt.wheelDelta / 80;
|
||||
} else {
|
||||
// on mac
|
||||
delta = -1.0 * evt.wheelDelta / 40;
|
||||
}
|
||||
} else if (agentInfo.isChrome || agentInfo.isSafari) {
|
||||
delta = -1.0 * evt.wheelDelta / 120;
|
||||
// handle touchpad for chrome
|
||||
if (Math.abs(delta) < 1) {
|
||||
if (agentInfo.isWindows) {
|
||||
delta = -1.0 * evt.wheelDelta;
|
||||
} else if (agentInfo.isMacOS) {
|
||||
delta = -1.0 * evt.wheelDelta / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return delta;
|
||||
}-*/;
|
||||
|
||||
/** Kindly borrowed from PlayN. **/
|
||||
protected static native String getMouseWheelEvent() /*-{
|
||||
if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
|
||||
return "DOMMouseScroll";
|
||||
} else {
|
||||
return "mousewheel";
|
||||
}
|
||||
}-*/;
|
||||
|
||||
/** Kindly borrowed from PlayN. **/
|
||||
protected static float getRelativeX(NativeEvent e, Element target) {
|
||||
return e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft()
|
||||
+ target.getOwnerDocument().getScrollLeft();
|
||||
}
|
||||
|
||||
/** Kindly borrowed from PlayN. **/
|
||||
protected static float getRelativeY(NativeEvent e, Element target) {
|
||||
return e.getClientY() - target.getAbsoluteTop() + target.getScrollTop()
|
||||
+ target.getOwnerDocument().getScrollTop();
|
||||
}
|
||||
|
||||
private void hookEvents() {
|
||||
addEventListener(canvas, "mousedown", this, true);
|
||||
// addEventListener(Document.get(), "mousedown", this, true);
|
||||
addEventListener(canvas, "mouseup", this, true);
|
||||
// addEventListener(Document.get(), "mouseup", this, true);
|
||||
addEventListener(canvas, "mousemove", this, true);
|
||||
// addEventListener(Document.get(), "mousemove", this, true);
|
||||
addEventListener(canvas, getMouseWheelEvent(), this, true);
|
||||
// addEventListener(Document.get(), "keydown", this, false);
|
||||
// addEventListener(Document.get(), "keyup", this, false);
|
||||
// addEventListener(Document.get(), "keypress", this, false);
|
||||
addEventListener(canvas, "keydown", this, false);
|
||||
addEventListener(canvas, "keyup", this, false);
|
||||
addEventListener(canvas, "keypress", this, false);
|
||||
addEventListener(canvas, "touchstart", this, true);
|
||||
addEventListener(canvas, "touchmove", this, true);
|
||||
addEventListener(canvas, "touchcancel", this, true);
|
||||
addEventListener(canvas, "touchend", this, true);
|
||||
|
||||
}
|
||||
|
||||
private int getButton(int button) {
|
||||
if (button == NativeEvent.BUTTON_LEFT)
|
||||
return Buttons.LEFT;
|
||||
if (button == NativeEvent.BUTTON_RIGHT)
|
||||
return Buttons.RIGHT;
|
||||
if (button == NativeEvent.BUTTON_MIDDLE)
|
||||
return Buttons.MIDDLE;
|
||||
return Buttons.LEFT;
|
||||
}
|
||||
|
||||
private void handleEvent(NativeEvent e) {
|
||||
if (e.getType().equals("mousedown")) {
|
||||
if (!e.getEventTarget().equals(canvas) || touched[0]) {
|
||||
float mouseX = (int) getRelativeX(e, canvas);
|
||||
float mouseY = (int) getRelativeY(e, canvas);
|
||||
if (mouseX < 0 || mouseX > Gdx.graphics.getWidth() || mouseY < 0
|
||||
|| mouseY > Gdx.graphics.getHeight()) {
|
||||
hasFocus = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
hasFocus = true;
|
||||
this.justTouched = true;
|
||||
this.touched[0] = true;
|
||||
this.pressedButtons.add(getButton(e.getButton()));
|
||||
this.deltaX[0] = 0;
|
||||
this.deltaY[0] = 0;
|
||||
if (isCursorCatched()) {
|
||||
this.touchX[0] += getMovementXJSNI(e);
|
||||
this.touchY[0] += getMovementYJSNI(e);
|
||||
} else {
|
||||
this.touchX[0] = (int) getRelativeX(e, canvas);
|
||||
this.touchY[0] = (int) getRelativeY(e, canvas);
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
if (processor != null)
|
||||
processor.touchDown(touchX[0], touchY[0], 0, getButton(e.getButton()));
|
||||
}
|
||||
|
||||
if (e.getType().equals("mousemove")) {
|
||||
if (isCursorCatched()) {
|
||||
this.deltaX[0] = (int) getMovementXJSNI(e);
|
||||
this.deltaY[0] = (int) getMovementYJSNI(e);
|
||||
this.touchX[0] += getMovementXJSNI(e);
|
||||
this.touchY[0] += getMovementYJSNI(e);
|
||||
} else {
|
||||
this.deltaX[0] = (int) getRelativeX(e, canvas) - touchX[0];
|
||||
this.deltaY[0] = (int) getRelativeY(e, canvas) - touchY[0];
|
||||
this.touchX[0] = (int) getRelativeX(e, canvas);
|
||||
this.touchY[0] = (int) getRelativeY(e, canvas);
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
if (processor != null) {
|
||||
if (touched[0])
|
||||
processor.touchDragged(touchX[0], touchY[0], 0);
|
||||
else
|
||||
processor.mouseMoved(touchX[0], touchY[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getType().equals("mouseup")) {
|
||||
if (!touched[0])
|
||||
return;
|
||||
this.pressedButtons.remove(getButton(e.getButton()));
|
||||
this.touched[0] = pressedButtons.size() > 0;
|
||||
if (isCursorCatched()) {
|
||||
this.deltaX[0] = (int) getMovementXJSNI(e);
|
||||
this.deltaY[0] = (int) getMovementYJSNI(e);
|
||||
this.touchX[0] += getMovementXJSNI(e);
|
||||
this.touchY[0] += getMovementYJSNI(e);
|
||||
} else {
|
||||
this.deltaX[0] = (int) getRelativeX(e, canvas) - touchX[0];
|
||||
this.deltaY[0] = (int) getRelativeY(e, canvas) - touchY[0];
|
||||
this.touchX[0] = (int) getRelativeX(e, canvas);
|
||||
this.touchY[0] = (int) getRelativeY(e, canvas);
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
this.touched[0] = false;
|
||||
if (processor != null)
|
||||
processor.touchUp(touchX[0], touchY[0], 0, getButton(e.getButton()));
|
||||
}
|
||||
if (e.getType().equals(getMouseWheelEvent())) {
|
||||
if (processor != null) {
|
||||
processor.scrolled((int) getMouseWheelVelocity(e));
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.getType().equals("keydown") && hasFocus) {
|
||||
//System.out.println("keydown");
|
||||
int code = keyForCode(e.getKeyCode());
|
||||
if (code == 67) {
|
||||
e.preventDefault();
|
||||
if (processor != null) {
|
||||
processor.keyDown(code);
|
||||
processor.keyTyped('\b');
|
||||
}
|
||||
} else {
|
||||
if (this.pressedKeys.add(code) && processor != null) {
|
||||
processor.keyDown(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getType().equals("keypress") && hasFocus) {
|
||||
//System.out.println("keypress");
|
||||
char c = (char) e.getCharCode();
|
||||
if (processor != null)
|
||||
processor.keyTyped(c);
|
||||
}
|
||||
|
||||
if (e.getType().equals("keyup") && hasFocus) {
|
||||
//System.out.println("keyup");
|
||||
int code = keyForCode(e.getKeyCode());
|
||||
this.pressedKeys.remove(code);
|
||||
if (processor != null) {
|
||||
processor.keyUp(code);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getType().equals("touchstart")) {
|
||||
this.justTouched = true;
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
touched[touchId] = true;
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
deltaX[touchId] = 0;
|
||||
deltaY[touchId] = 0;
|
||||
if (processor != null) {
|
||||
processor.touchDown(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
|
||||
}
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.getType().equals("touchmove")) {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
|
||||
deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
if (processor != null) {
|
||||
processor.touchDragged(touchX[touchId], touchY[touchId], touchId);
|
||||
}
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.getType().equals("touchcancel")) {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
touched[touchId] = false;
|
||||
deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
|
||||
deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
if (processor != null) {
|
||||
processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
|
||||
}
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.getType().equals("touchend")) {
|
||||
JsArray<Touch> touches = e.getChangedTouches();
|
||||
for (int i = 0, j = touches.length(); i < j; i++) {
|
||||
Touch touch = touches.get(i);
|
||||
int touchId = touch.getIdentifier();
|
||||
touched[touchId] = false;
|
||||
deltaX[touchId] = touch.getRelativeX(canvas) - touchX[touchId];
|
||||
deltaY[touchId] = touch.getRelativeY(canvas) - touchY[touchId];
|
||||
touchX[touchId] = touch.getRelativeX(canvas);
|
||||
touchY[touchId] = touch.getRelativeY(canvas);
|
||||
if (processor != null) {
|
||||
processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT);
|
||||
}
|
||||
}
|
||||
this.currentEventTimeStamp = TimeUtils.nanoTime();
|
||||
e.preventDefault();
|
||||
}
|
||||
// if(hasFocus) e.preventDefault();
|
||||
}
|
||||
|
||||
/** borrowed from PlayN, thanks guys **/
|
||||
private static int keyForCode(int keyCode) {
|
||||
switch (keyCode) {
|
||||
case KeyCodes.KEY_ALT:
|
||||
return Keys.ALT_LEFT;
|
||||
case KeyCodes.KEY_BACKSPACE:
|
||||
return Keys.BACKSPACE;
|
||||
case KeyCodes.KEY_CTRL:
|
||||
return Keys.CONTROL_LEFT;
|
||||
case KeyCodes.KEY_DELETE:
|
||||
return Keys.DEL;
|
||||
case KeyCodes.KEY_DOWN:
|
||||
return Keys.DOWN;
|
||||
case KeyCodes.KEY_END:
|
||||
return Keys.END;
|
||||
case KeyCodes.KEY_ENTER:
|
||||
return Keys.ENTER;
|
||||
case KeyCodes.KEY_ESCAPE:
|
||||
return Keys.ESCAPE;
|
||||
case KeyCodes.KEY_HOME:
|
||||
return Keys.HOME;
|
||||
case KeyCodes.KEY_LEFT:
|
||||
return Keys.LEFT;
|
||||
case KeyCodes.KEY_PAGEDOWN:
|
||||
return Keys.PAGE_DOWN;
|
||||
case KeyCodes.KEY_PAGEUP:
|
||||
return Keys.PAGE_UP;
|
||||
case KeyCodes.KEY_RIGHT:
|
||||
return Keys.RIGHT;
|
||||
case KeyCodes.KEY_SHIFT:
|
||||
return Keys.SHIFT_LEFT;
|
||||
case KeyCodes.KEY_TAB:
|
||||
return Keys.TAB;
|
||||
case KeyCodes.KEY_UP:
|
||||
return Keys.UP;
|
||||
|
||||
case KEY_PAUSE:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_CAPS_LOCK:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_SPACE:
|
||||
return Keys.SPACE;
|
||||
case KEY_INSERT:
|
||||
return Keys.INSERT;
|
||||
case KEY_0:
|
||||
return Keys.NUM_0;
|
||||
case KEY_1:
|
||||
return Keys.NUM_1;
|
||||
case KEY_2:
|
||||
return Keys.NUM_2;
|
||||
case KEY_3:
|
||||
return Keys.NUM_3;
|
||||
case KEY_4:
|
||||
return Keys.NUM_4;
|
||||
case KEY_5:
|
||||
return Keys.NUM_5;
|
||||
case KEY_6:
|
||||
return Keys.NUM_6;
|
||||
case KEY_7:
|
||||
return Keys.NUM_7;
|
||||
case KEY_8:
|
||||
return Keys.NUM_8;
|
||||
case KEY_9:
|
||||
return Keys.NUM_9;
|
||||
case KEY_A:
|
||||
return Keys.A;
|
||||
case KEY_B:
|
||||
return Keys.B;
|
||||
case KEY_C:
|
||||
return Keys.C;
|
||||
case KEY_D:
|
||||
return Keys.D;
|
||||
case KEY_E:
|
||||
return Keys.E;
|
||||
case KEY_F:
|
||||
return Keys.F;
|
||||
case KEY_G:
|
||||
return Keys.G;
|
||||
case KEY_H:
|
||||
return Keys.H;
|
||||
case KEY_I:
|
||||
return Keys.I;
|
||||
case KEY_J:
|
||||
return Keys.J;
|
||||
case KEY_K:
|
||||
return Keys.K;
|
||||
case KEY_L:
|
||||
return Keys.L;
|
||||
case KEY_M:
|
||||
return Keys.M;
|
||||
case KEY_N:
|
||||
return Keys.N;
|
||||
case KEY_O:
|
||||
return Keys.O;
|
||||
case KEY_P:
|
||||
return Keys.P;
|
||||
case KEY_Q:
|
||||
return Keys.Q;
|
||||
case KEY_R:
|
||||
return Keys.R;
|
||||
case KEY_S:
|
||||
return Keys.S;
|
||||
case KEY_T:
|
||||
return Keys.T;
|
||||
case KEY_U:
|
||||
return Keys.U;
|
||||
case KEY_V:
|
||||
return Keys.V;
|
||||
case KEY_W:
|
||||
return Keys.W;
|
||||
case KEY_X:
|
||||
return Keys.X;
|
||||
case KEY_Y:
|
||||
return Keys.Y;
|
||||
case KEY_Z:
|
||||
return Keys.Z;
|
||||
case KEY_LEFT_WINDOW_KEY:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_RIGHT_WINDOW_KEY:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
// case KEY_SELECT_KEY: return Keys.SELECT_KEY;
|
||||
case KEY_NUMPAD0:
|
||||
return Keys.NUMPAD_0;
|
||||
case KEY_NUMPAD1:
|
||||
return Keys.NUMPAD_1;
|
||||
case KEY_NUMPAD2:
|
||||
return Keys.NUMPAD_2;
|
||||
case KEY_NUMPAD3:
|
||||
return Keys.NUMPAD_3;
|
||||
case KEY_NUMPAD4:
|
||||
return Keys.NUMPAD_4;
|
||||
case KEY_NUMPAD5:
|
||||
return Keys.NUMPAD_5;
|
||||
case KEY_NUMPAD6:
|
||||
return Keys.NUMPAD_6;
|
||||
case KEY_NUMPAD7:
|
||||
return Keys.NUMPAD_7;
|
||||
case KEY_NUMPAD8:
|
||||
return Keys.NUMPAD_8;
|
||||
case KEY_NUMPAD9:
|
||||
return Keys.NUMPAD_9;
|
||||
case KEY_MULTIPLY:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_ADD:
|
||||
return Keys.PLUS;
|
||||
case KEY_SUBTRACT:
|
||||
return Keys.MINUS;
|
||||
case KEY_DECIMAL_POINT_KEY:
|
||||
return Keys.PERIOD;
|
||||
case KEY_DIVIDE:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_F1:
|
||||
return Keys.F1;
|
||||
case KEY_F2:
|
||||
return Keys.F2;
|
||||
case KEY_F3:
|
||||
return Keys.F3;
|
||||
case KEY_F4:
|
||||
return Keys.F4;
|
||||
case KEY_F5:
|
||||
return Keys.F5;
|
||||
case KEY_F6:
|
||||
return Keys.F6;
|
||||
case KEY_F7:
|
||||
return Keys.F7;
|
||||
case KEY_F8:
|
||||
return Keys.F8;
|
||||
case KEY_F9:
|
||||
return Keys.F9;
|
||||
case KEY_F10:
|
||||
return Keys.F10;
|
||||
case KEY_F11:
|
||||
return Keys.F11;
|
||||
case KEY_F12:
|
||||
return Keys.F12;
|
||||
case KEY_NUM_LOCK:
|
||||
return Keys.NUM;
|
||||
case KEY_SCROLL_LOCK:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_SEMICOLON:
|
||||
return Keys.SEMICOLON;
|
||||
case KEY_EQUALS:
|
||||
return Keys.EQUALS;
|
||||
case KEY_COMMA:
|
||||
return Keys.COMMA;
|
||||
case KEY_DASH:
|
||||
return Keys.MINUS;
|
||||
case KEY_PERIOD:
|
||||
return Keys.PERIOD;
|
||||
case KEY_FORWARD_SLASH:
|
||||
return Keys.SLASH;
|
||||
case KEY_GRAVE_ACCENT:
|
||||
return Keys.UNKNOWN; // FIXME
|
||||
case KEY_OPEN_BRACKET:
|
||||
return Keys.LEFT_BRACKET;
|
||||
case KEY_BACKSLASH:
|
||||
return Keys.BACKSLASH;
|
||||
case KEY_CLOSE_BRACKET:
|
||||
return Keys.RIGHT_BRACKET;
|
||||
case KEY_SINGLE_QUOTE:
|
||||
return Keys.APOSTROPHE;
|
||||
default:
|
||||
return Keys.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// these are absent from KeyCodes; we know not why...
|
||||
private static final int KEY_PAUSE = 19;
|
||||
private static final int KEY_CAPS_LOCK = 20;
|
||||
private static final int KEY_SPACE = 32;
|
||||
private static final int KEY_INSERT = 45;
|
||||
private static final int KEY_0 = 48;
|
||||
private static final int KEY_1 = 49;
|
||||
private static final int KEY_2 = 50;
|
||||
private static final int KEY_3 = 51;
|
||||
private static final int KEY_4 = 52;
|
||||
private static final int KEY_5 = 53;
|
||||
private static final int KEY_6 = 54;
|
||||
private static final int KEY_7 = 55;
|
||||
private static final int KEY_8 = 56;
|
||||
private static final int KEY_9 = 57;
|
||||
private static final int KEY_A = 65;
|
||||
private static final int KEY_B = 66;
|
||||
private static final int KEY_C = 67;
|
||||
private static final int KEY_D = 68;
|
||||
private static final int KEY_E = 69;
|
||||
private static final int KEY_F = 70;
|
||||
private static final int KEY_G = 71;
|
||||
private static final int KEY_H = 72;
|
||||
private static final int KEY_I = 73;
|
||||
private static final int KEY_J = 74;
|
||||
private static final int KEY_K = 75;
|
||||
private static final int KEY_L = 76;
|
||||
private static final int KEY_M = 77;
|
||||
private static final int KEY_N = 78;
|
||||
private static final int KEY_O = 79;
|
||||
private static final int KEY_P = 80;
|
||||
private static final int KEY_Q = 81;
|
||||
private static final int KEY_R = 82;
|
||||
private static final int KEY_S = 83;
|
||||
private static final int KEY_T = 84;
|
||||
private static final int KEY_U = 85;
|
||||
private static final int KEY_V = 86;
|
||||
private static final int KEY_W = 87;
|
||||
private static final int KEY_X = 88;
|
||||
private static final int KEY_Y = 89;
|
||||
private static final int KEY_Z = 90;
|
||||
private static final int KEY_LEFT_WINDOW_KEY = 91;
|
||||
private static final int KEY_RIGHT_WINDOW_KEY = 92;
|
||||
private static final int KEY_SELECT_KEY = 93;
|
||||
private static final int KEY_NUMPAD0 = 96;
|
||||
private static final int KEY_NUMPAD1 = 97;
|
||||
private static final int KEY_NUMPAD2 = 98;
|
||||
private static final int KEY_NUMPAD3 = 99;
|
||||
private static final int KEY_NUMPAD4 = 100;
|
||||
private static final int KEY_NUMPAD5 = 101;
|
||||
private static final int KEY_NUMPAD6 = 102;
|
||||
private static final int KEY_NUMPAD7 = 103;
|
||||
private static final int KEY_NUMPAD8 = 104;
|
||||
private static final int KEY_NUMPAD9 = 105;
|
||||
private static final int KEY_MULTIPLY = 106;
|
||||
private static final int KEY_ADD = 107;
|
||||
private static final int KEY_SUBTRACT = 109;
|
||||
private static final int KEY_DECIMAL_POINT_KEY = 110;
|
||||
private static final int KEY_DIVIDE = 111;
|
||||
private static final int KEY_F1 = 112;
|
||||
private static final int KEY_F2 = 113;
|
||||
private static final int KEY_F3 = 114;
|
||||
private static final int KEY_F4 = 115;
|
||||
private static final int KEY_F5 = 116;
|
||||
private static final int KEY_F6 = 117;
|
||||
private static final int KEY_F7 = 118;
|
||||
private static final int KEY_F8 = 119;
|
||||
private static final int KEY_F9 = 120;
|
||||
private static final int KEY_F10 = 121;
|
||||
private static final int KEY_F11 = 122;
|
||||
private static final int KEY_F12 = 123;
|
||||
private static final int KEY_NUM_LOCK = 144;
|
||||
private static final int KEY_SCROLL_LOCK = 145;
|
||||
private static final int KEY_SEMICOLON = 186;
|
||||
private static final int KEY_EQUALS = 187;
|
||||
private static final int KEY_COMMA = 188;
|
||||
private static final int KEY_DASH = 189;
|
||||
private static final int KEY_PERIOD = 190;
|
||||
private static final int KEY_FORWARD_SLASH = 191;
|
||||
private static final int KEY_GRAVE_ACCENT = 192;
|
||||
private static final int KEY_OPEN_BRACKET = 219;
|
||||
private static final int KEY_BACKSLASH = 220;
|
||||
private static final int KEY_CLOSE_BRACKET = 221;
|
||||
private static final int KEY_SINGLE_QUOTE = 222;
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package com.badlogic.gdx.graphics;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.badlogic.gdx.backends.gwt.GwtFileHandle;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.BufferUtils;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.google.gwt.canvas.client.Canvas;
|
||||
import com.google.gwt.canvas.dom.client.CanvasPixelArray;
|
||||
import com.google.gwt.canvas.dom.client.Context2d;
|
||||
import com.google.gwt.canvas.dom.client.Context2d.Composite;
|
||||
import com.google.gwt.dom.client.CanvasElement;
|
||||
import com.google.gwt.dom.client.ImageElement;
|
||||
|
||||
public class Pixmap implements Disposable {
|
||||
public static Map<Integer, Pixmap> pixmaps = new HashMap<Integer, Pixmap>();
|
||||
static int nextId = 0;
|
||||
|
||||
/** Different pixel formats.
|
||||
*
|
||||
* @author mzechner */
|
||||
public enum Format {
|
||||
Alpha, Intensity, LuminanceAlpha, RGB565, RGBA4444, RGB888, RGBA8888;
|
||||
}
|
||||
|
||||
/** Blending functions to be set with {@link Pixmap#setBlending}.
|
||||
* @author mzechner */
|
||||
public enum Blending {
|
||||
None, SourceOver
|
||||
}
|
||||
|
||||
/** Filters to be used with {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
|
||||
*
|
||||
* @author mzechner */
|
||||
public enum Filter {
|
||||
NearestNeighbour, BiLinear
|
||||
}
|
||||
|
||||
int width;
|
||||
int height;
|
||||
Format format;
|
||||
Canvas canvas;
|
||||
Context2d context;
|
||||
int id;
|
||||
IntBuffer buffer;
|
||||
int r = 255, g = 255, b = 255;
|
||||
float a;
|
||||
String color = make(r, g, b, a);
|
||||
static Blending blending;
|
||||
CanvasPixelArray pixels;
|
||||
|
||||
public Context2d getContext(){
|
||||
return context;
|
||||
}
|
||||
|
||||
public Pixmap (FileHandle file) {
|
||||
GwtFileHandle gwtFile = (GwtFileHandle)file;
|
||||
ImageElement img = gwtFile.preloader.images.get(file.path());
|
||||
if (img == null) throw new GdxRuntimeException("Couldn't load image '" + file.path() + "', file does not exist");
|
||||
create(img.getWidth(), img.getHeight(), Format.RGBA8888);
|
||||
context.setGlobalCompositeOperation(Composite.COPY);
|
||||
context.drawImage(img, 0, 0);
|
||||
context.setGlobalCompositeOperation(getComposite());
|
||||
}
|
||||
|
||||
private static Composite getComposite () {
|
||||
return blending == Blending.None ? Composite.COPY : Composite.SOURCE_OVER;
|
||||
}
|
||||
|
||||
public Pixmap (ImageElement img) {
|
||||
create(img.getWidth(), img.getHeight(), Format.RGBA8888);
|
||||
context.drawImage(img, 0, 0);
|
||||
}
|
||||
|
||||
public Pixmap (int width, int height, Format format) {
|
||||
create(width, height, format);
|
||||
}
|
||||
|
||||
private void create (int width, int height, Format format2) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.format = Format.RGBA8888;
|
||||
canvas = Canvas.createIfSupported();
|
||||
canvas.getCanvasElement().setWidth(width);
|
||||
canvas.getCanvasElement().setHeight(height);
|
||||
context = canvas.getContext2d();
|
||||
context.setGlobalCompositeOperation(getComposite());
|
||||
buffer = BufferUtils.newIntBuffer(1);
|
||||
id = nextId++;
|
||||
buffer.put(0, id);
|
||||
pixmaps.put(id, this);
|
||||
}
|
||||
|
||||
public static String make (int r2, int g2, int b2, float a2) {
|
||||
return "rgba(" + r2 + "," + g2 + "," + b2 + "," + a2 + ")";
|
||||
}
|
||||
|
||||
/** Sets the type of {@link Blending} to be used for all operations. Default is {@link Blending#SourceOver}.
|
||||
* @param blending the blending type */
|
||||
public static void setBlending (Blending blending) {
|
||||
Pixmap.blending = blending;
|
||||
Composite composite = getComposite();
|
||||
for (Pixmap pixmap : pixmaps.values()) {
|
||||
pixmap.context.setGlobalCompositeOperation(composite);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return the currently set {@link Blending} */
|
||||
public static Blending getBlending () {
|
||||
return blending;
|
||||
}
|
||||
|
||||
/** Sets the type of interpolation {@link Filter} to be used in conjunction with
|
||||
* {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
|
||||
* @param filter the filter. */
|
||||
public static void setFilter (Filter filter) {
|
||||
}
|
||||
|
||||
public Format getFormat () {
|
||||
return format;
|
||||
}
|
||||
|
||||
public int getGLInternalFormat () {
|
||||
return GL20.GL_RGBA;
|
||||
}
|
||||
|
||||
public int getGLFormat () {
|
||||
return GL20.GL_RGBA;
|
||||
}
|
||||
|
||||
public int getGLType () {
|
||||
return GL20.GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
public int getWidth () {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight () {
|
||||
return height;
|
||||
}
|
||||
|
||||
public Buffer getPixels () {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose () {
|
||||
pixmaps.remove(id);
|
||||
}
|
||||
|
||||
public CanvasElement getCanvasElement () {
|
||||
return canvas.getCanvasElement();
|
||||
}
|
||||
|
||||
/** Sets the color for the following drawing operations
|
||||
* @param color the color, encoded as RGBA8888 */
|
||||
public void setColor (int color) {
|
||||
r = (color >>> 24) & 0xff;
|
||||
g = (color >>> 16) & 0xff;
|
||||
b = (color >>> 8) & 0xff;
|
||||
a = (color & 0xff) / 255f;
|
||||
this.color = make(r, g, b, a);
|
||||
context.setFillStyle(this.color);
|
||||
context.setStrokeStyle(this.color);
|
||||
}
|
||||
|
||||
/** Sets the color for the following drawing operations.
|
||||
*
|
||||
* @param r The red component.
|
||||
* @param g The green component.
|
||||
* @param b The blue component.
|
||||
* @param a The alpha component. */
|
||||
public void setColor (float r, float g, float b, float a) {
|
||||
this.r = (int)(r * 255);
|
||||
this.g = (int)(g * 255);
|
||||
this.b = (int)(b * 255);
|
||||
this.a = a;
|
||||
color = make(this.r, this.g, this.b, this.a);
|
||||
context.setFillStyle(color);
|
||||
context.setStrokeStyle(this.color);
|
||||
}
|
||||
|
||||
/** Sets the color for the following drawing operations.
|
||||
* @param color The color. */
|
||||
public void setColor (Color color) {
|
||||
setColor(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
/** Fills the complete bitmap with the currently set color. */
|
||||
public void fill () {
|
||||
context.fillRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Sets the width in pixels of strokes.
|
||||
// *
|
||||
// * @param width The stroke width in pixels.
|
||||
// */
|
||||
// public void setStrokeWidth (int width);
|
||||
|
||||
/** Draws a line between the given coordinates using the currently set color.
|
||||
*
|
||||
* @param x The x-coodinate of the first point
|
||||
* @param y The y-coordinate of the first point
|
||||
* @param x2 The x-coordinate of the first point
|
||||
* @param y2 The y-coordinate of the first point */
|
||||
public void drawLine (int x, int y, int x2, int y2) {
|
||||
context.beginPath();
|
||||
context.moveTo(x, y);
|
||||
context.lineTo(x2, y2);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
/** Draws a rectangle outline starting at x, y extending by width to the right and by height downwards (y-axis points downwards)
|
||||
* using the current color.
|
||||
*
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width in pixels
|
||||
* @param height The height in pixels */
|
||||
public void drawRectangle (int x, int y, int width, int height) {
|
||||
context.beginPath();
|
||||
context.rect(x, y, width, height);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
/** Draws an area form another Pixmap to this Pixmap.
|
||||
*
|
||||
* @param pixmap The other Pixmap
|
||||
* @param x The target x-coordinate (top left corner)
|
||||
* @param y The target y-coordinate (top left corner) */
|
||||
public void drawPixmap (Pixmap pixmap, int x, int y) {
|
||||
context.drawImage(pixmap.getCanvasElement(), x, y);
|
||||
}
|
||||
|
||||
/** Draws an area form another Pixmap to this Pixmap.
|
||||
*
|
||||
* @param pixmap The other Pixmap
|
||||
* @param x The target x-coordinate (top left corner)
|
||||
* @param y The target y-coordinate (top left corner)
|
||||
* @param srcx The source x-coordinate (top left corner)
|
||||
* @param srcy The source y-coordinate (top left corner);
|
||||
* @param srcWidth The width of the area form the other Pixmap in pixels
|
||||
* @param srcHeight The height of the area form the other Pixmap in pixles */
|
||||
public void drawPixmap (Pixmap pixmap, int x, int y, int srcx, int srcy, int srcWidth, int srcHeight) {
|
||||
context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, x, y, srcWidth, srcHeight);
|
||||
}
|
||||
|
||||
/** Draws an area form another Pixmap to this Pixmap. This will automatically scale and stretch the source image to the
|
||||
* specified target rectangle. Use {@link Pixmap#setFilter(Filter)} to specify the type of filtering to be used (nearest
|
||||
* neighbour or bilinear).
|
||||
*
|
||||
* @param pixmap The other Pixmap
|
||||
* @param srcx The source x-coordinate (top left corner)
|
||||
* @param srcy The source y-coordinate (top left corner);
|
||||
* @param srcWidth The width of the area form the other Pixmap in pixels
|
||||
* @param srcHeight The height of the area form the other Pixmap in pixles
|
||||
* @param dstx The target x-coordinate (top left corner)
|
||||
* @param dsty The target y-coordinate (top left corner)
|
||||
* @param dstWidth The target width
|
||||
* @param dstHeight the target height */
|
||||
public void drawPixmap (Pixmap pixmap, int srcx, int srcy, int srcWidth, int srcHeight, int dstx, int dsty, int dstWidth,
|
||||
int dstHeight) {
|
||||
context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, dstx, dsty, dstWidth, dstHeight);
|
||||
}
|
||||
|
||||
/** Fills a rectangle starting at x, y extending by width to the right and by height downwards (y-axis points downwards) using
|
||||
* the current color.
|
||||
*
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width in pixels
|
||||
* @param height The height in pixels */
|
||||
public void fillRectangle (int x, int y, int width, int height) {
|
||||
context.fillRect(x, y, width, height);
|
||||
}
|
||||
|
||||
/** Draws a circle outline with the center at x,y and a radius using the current color and stroke width.
|
||||
*
|
||||
* @param x The x-coordinate of the center
|
||||
* @param y The y-coordinate of the center
|
||||
* @param radius The radius in pixels */
|
||||
public void drawCircle (int x, int y, int radius) {
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||
context.stroke();
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
/** Fills a circle with the center at x,y and a radius using the current color.
|
||||
*
|
||||
* @param x The x-coordinate of the center
|
||||
* @param y The y-coordinate of the center
|
||||
* @param radius The radius in pixels */
|
||||
public void fillCircle (int x, int y, int radius) {
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||
context.fill();
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
/** Fills a triangle with vertices at x1,y1 and x2,y2 and x3,y3 using the current color.
|
||||
*
|
||||
* @param x1 The x-coordinate of vertex 1
|
||||
* @param y1 The y-coordinate of vertex 1
|
||||
* @param x2 The x-coordinate of vertex 2
|
||||
* @param y2 The y-coordinate of vertex 2
|
||||
* @param x3 The x-coordinate of vertex 3
|
||||
* @param y3 The y-coordinate of vertex 3 */
|
||||
public void fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
context.beginPath();
|
||||
context.moveTo(x1,y1);
|
||||
context.lineTo(x2,y2);
|
||||
context.lineTo(x3,y3);
|
||||
context.lineTo(x1,y1);
|
||||
context.fill();
|
||||
context.closePath();
|
||||
}
|
||||
|
||||
/** Returns the 32-bit RGBA8888 value of the pixel at x, y. For Alpha formats the RGB components will be one.
|
||||
*
|
||||
* @param x The x-coordinate
|
||||
* @param y The y-coordinate
|
||||
* @return The pixel color in RGBA8888 format. */
|
||||
public int getPixel (int x, int y) {
|
||||
if (pixels == null) pixels = context.getImageData(0, 0, width, height).getData();
|
||||
int i = x * 4 + y * width * 4;
|
||||
int r = pixels.get(i + 0) & 0xff;
|
||||
int g = pixels.get(i + 1) & 0xff;
|
||||
int b = pixels.get(i + 2) & 0xff;
|
||||
int a = pixels.get(i + 3) & 0xff;
|
||||
return (r << 24) | (g << 16) | (b << 8) | (a);
|
||||
}
|
||||
|
||||
/** Draws a pixel at the given location with the current color.
|
||||
*
|
||||
* @param x the x-coordinate
|
||||
* @param y the y-coordinate */
|
||||
public void drawPixel (int x, int y) {
|
||||
context.fillRect(x, y, 1, 1);
|
||||
}
|
||||
|
||||
/** Draws a pixel at the given location with the given color.
|
||||
*
|
||||
* @param x the x-coordinate
|
||||
* @param y the y-coordinate
|
||||
* @param color the color in RGBA8888 format. */
|
||||
public void drawPixel (int x, int y, int color) {
|
||||
setColor(color);
|
||||
drawPixel(x, y);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package java.net;
|
||||
|
||||
public class MalformedURLException extends Exception {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
22
vtm-web/src/org/oscim/gdx/emu/java/net/URL.java
Normal file
22
vtm-web/src/org/oscim/gdx/emu/java/net/URL.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package java.net;
|
||||
|
||||
public class URL {
|
||||
@Override
|
||||
public String toString() {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
String mProtocol;
|
||||
String mHostname;
|
||||
int mPort;
|
||||
String mPath;
|
||||
|
||||
public URL(String protocol, String hostName, int port, String path) {
|
||||
//mPath = "http://" +hostName +"/" + path;
|
||||
mPath = path;
|
||||
}
|
||||
|
||||
public URL(String path) throws MalformedURLException {
|
||||
mPath = path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package java.util.concurrent;
|
||||
|
||||
public class CancellationException extends IllegalStateException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package java.util.concurrent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CopyOnWriteArrayList<E> extends ArrayList<E> {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.oscim.backend;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import com.google.gwt.xml.client.NamedNodeMap;
|
||||
import com.google.gwt.xml.client.Node;
|
||||
|
||||
public class MyAttributes implements Attributes {
|
||||
private NamedNodeMap map;
|
||||
|
||||
public MyAttributes(Node n) {
|
||||
map = n.getAttributes();
|
||||
}
|
||||
|
||||
public String getValue(int i) {
|
||||
return map.item(i).getNodeValue();
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return map.getLength();
|
||||
}
|
||||
|
||||
public String getLocalName(int i) {
|
||||
return map.item(i).getNodeName();
|
||||
}
|
||||
|
||||
public String getValue(String string) {
|
||||
Node n = map.getNamedItem(string);
|
||||
if (n == null)
|
||||
return null;
|
||||
|
||||
return n.getNodeValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURI(int paramInt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQName(int paramInt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(int paramInt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(String paramString1, String paramString2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(String paramString) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(String paramString1, String paramString2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(String paramString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(String paramString1, String paramString2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.oscim.backend;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import com.google.gwt.xml.client.Document;
|
||||
import com.google.gwt.xml.client.Node;
|
||||
import com.google.gwt.xml.client.NodeList;
|
||||
import com.google.gwt.xml.client.XMLParser;
|
||||
|
||||
public class MyXMLReader {
|
||||
public void parse(InputStream is) throws SAXException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] buf = new byte[8192];
|
||||
int read;
|
||||
try {
|
||||
while ((read = is.read(buf)) >= 0) {
|
||||
if (read > 0)
|
||||
sb.append(new String(buf, 0, read));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Document d = XMLParser.parse(sb.toString());
|
||||
handleElement(d.getFirstChild());
|
||||
mHandler.endDocument();
|
||||
}
|
||||
|
||||
int level = 0;
|
||||
|
||||
void handleElement(Node n) throws SAXException {
|
||||
if (n == null) {
|
||||
return;
|
||||
}
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
|
||||
String localName = n.getNodeName();
|
||||
mHandler.startElement(null, localName, null, new MyAttributes(n));
|
||||
|
||||
if (n.hasChildNodes()) {
|
||||
NodeList l = n.getChildNodes();
|
||||
for (int i = 0, len = l.getLength(); i < len; i++) {
|
||||
handleElement(l.item(i));
|
||||
}
|
||||
}
|
||||
mHandler.endElement(null, localName, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DefaultHandler mHandler;
|
||||
|
||||
public void setContentHandler(DefaultHandler handler) {
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.oscim.backend;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
public class XMLReaderAdapter {
|
||||
public void parse(DefaultHandler handler, InputStream is) throws IOException, SAXException {
|
||||
|
||||
MyXMLReader xmlReader = new MyXMLReader();
|
||||
xmlReader.setContentHandler(handler);
|
||||
xmlReader.parse(is);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.oscim.layers.tile;
|
||||
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
|
||||
public abstract class LoadDelayTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (MapRenderer.frametime == TileLoader.lastLoadTime) {
|
||||
Gdx.app.postRunnable(this);
|
||||
return;
|
||||
}
|
||||
continueLoading();
|
||||
}
|
||||
|
||||
public abstract void continueLoading();
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.layers.tile;
|
||||
|
||||
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
import org.oscim.core.MapElement;
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.Timer;
|
||||
|
||||
public abstract class TileLoader implements ITileDataSink {
|
||||
final static Logger log = LoggerFactory.getLogger(TileLoader.class);
|
||||
|
||||
private final TileManager mTileManager;
|
||||
private Timer mTimer;
|
||||
|
||||
public TileLoader(TileManager tileManager) {
|
||||
if (mTimer == null)
|
||||
mTimer = new Timer();
|
||||
|
||||
mTileManager = tileManager;
|
||||
}
|
||||
|
||||
public abstract void cleanup();
|
||||
|
||||
protected abstract boolean loadTile(MapTile tile);
|
||||
|
||||
boolean isInterrupted;
|
||||
|
||||
public void interrupt() {
|
||||
isInterrupted = true;
|
||||
// cancel loading
|
||||
}
|
||||
|
||||
boolean mPausing;
|
||||
|
||||
public boolean isCanceled() {
|
||||
return mPausing;
|
||||
}
|
||||
|
||||
public boolean isPausing() {
|
||||
return mPausing;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
mPausing = true;
|
||||
}
|
||||
|
||||
public void proceed() {
|
||||
mPausing = false;
|
||||
// FIXME
|
||||
mWorking = false;
|
||||
if (mTileManager.hasTileJobs())
|
||||
go();
|
||||
}
|
||||
|
||||
public void awaitPausing() {
|
||||
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mPausing = false;
|
||||
}
|
||||
|
||||
protected boolean mWorking;
|
||||
protected MapTile mTile;
|
||||
|
||||
public void go() {
|
||||
if (mWorking)
|
||||
return;
|
||||
|
||||
mTile = mTileManager.getTileJob();
|
||||
|
||||
if (mTile == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
loadTile(mTile);
|
||||
mWorking = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
completed(FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
public static long lastLoadTime;
|
||||
|
||||
/**
|
||||
* Callback to be called by TileDataSource when finished
|
||||
* loading or on failure. MUST BE CALLED IN ANY CASE!
|
||||
*/
|
||||
@Override
|
||||
public void completed(QueryResult result) {
|
||||
boolean success = (result == SUCCESS) && !isInterrupted;
|
||||
long now = MapRenderer.frametime;
|
||||
|
||||
log.debug("completed {} diff time:{}", mTile, (now - lastLoadTime));
|
||||
lastLoadTime = now;
|
||||
|
||||
mTileManager.jobCompleted(mTile, success);
|
||||
mTile = null;
|
||||
|
||||
mWorking = false;
|
||||
|
||||
if (mPausing || !mTileManager.hasTileJobs())
|
||||
return;
|
||||
|
||||
Gdx.app.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
go();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TileDataSource
|
||||
*/
|
||||
@Override
|
||||
public void process(MapElement element) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by TileDataSource
|
||||
*/
|
||||
@Override
|
||||
public void setTileImage(Bitmap bitmap) {
|
||||
|
||||
}
|
||||
|
||||
public static void postLoadDelay(LoadDelayTask task) {
|
||||
Gdx.app.postRunnable(task);
|
||||
}
|
||||
|
||||
}
|
||||
620
vtm-web/src/org/oscim/gdx/emu/org/oscim/renderer/GLMatrix.java
Normal file
620
vtm-web/src/org/oscim/gdx/emu/org/oscim/renderer/GLMatrix.java
Normal file
@@ -0,0 +1,620 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2011 See libgdx AUTHORS file.
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package org.oscim.renderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class GLMatrix {
|
||||
|
||||
public static final int M00 = 0;// 0;
|
||||
public static final int M01 = 4;// 1;
|
||||
public static final int M02 = 8;// 2;
|
||||
public static final int M03 = 12;// 3;
|
||||
public static final int M10 = 1;// 4;
|
||||
public static final int M11 = 5;// 5;
|
||||
public static final int M12 = 9;// 6;
|
||||
public static final int M13 = 13;// 7;
|
||||
public static final int M20 = 2;// 8;
|
||||
public static final int M21 = 6;// 9;
|
||||
public static final int M22 = 10;// 10;
|
||||
public static final int M23 = 14;// 11;
|
||||
public static final int M30 = 3;// 12;
|
||||
public static final int M31 = 7;// 13;
|
||||
public static final int M32 = 11;// 14;
|
||||
public static final int M33 = 15;// 15;
|
||||
|
||||
private final FloatBuffer buffer = ByteBuffer.allocateDirect(16 * 4)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asFloatBuffer();
|
||||
|
||||
private final static String INVALID_INPUT = "Bad Array!";
|
||||
|
||||
public final float tmp[] = new float[16];
|
||||
public final float val[] = new float[16];
|
||||
|
||||
/**
|
||||
* Sets the matrix to the given matrix as a float array. The float array
|
||||
* must have at least 16 elements; the first 16 will be
|
||||
* copied.
|
||||
*
|
||||
* @param values The matrix, in float form, that is to be copied. Remember
|
||||
* that this matrix is in <a
|
||||
* href="http://en.wikipedia.org/wiki/Row-major_order">column
|
||||
* major</a> order.
|
||||
* @return This matrix for the purpose of chaining methods together.
|
||||
*/
|
||||
public void set(float[] values) {
|
||||
val[M00] = values[M00];
|
||||
val[M10] = values[M10];
|
||||
val[M20] = values[M20];
|
||||
val[M30] = values[M30];
|
||||
val[M01] = values[M01];
|
||||
val[M11] = values[M11];
|
||||
val[M21] = values[M21];
|
||||
val[M31] = values[M31];
|
||||
val[M02] = values[M02];
|
||||
val[M12] = values[M12];
|
||||
val[M22] = values[M22];
|
||||
val[M32] = values[M32];
|
||||
val[M03] = values[M03];
|
||||
val[M13] = values[M13];
|
||||
val[M23] = values[M23];
|
||||
val[M33] = values[M33];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Matrix as float array
|
||||
*
|
||||
* @param m float array to store Matrix
|
||||
*/
|
||||
public void get(float[] m) {
|
||||
|
||||
if (m == null || m.length != 16)
|
||||
throw new IllegalArgumentException(INVALID_INPUT);
|
||||
|
||||
System.arraycopy(val, 0, m, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy values from mat
|
||||
*
|
||||
* @param mat Matrix to copy
|
||||
*/
|
||||
public void copy(GLMatrix m) {
|
||||
if (m == null || m.val.length != 16)
|
||||
throw new IllegalArgumentException(INVALID_INPUT);
|
||||
|
||||
System.arraycopy(m.val, 0, val, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Project Vector with Matrix
|
||||
*
|
||||
* @param vec3 Vector to project
|
||||
*/
|
||||
public void prj(float[] vec3) {
|
||||
if (vec3 == null || vec3.length < 3)
|
||||
throw new IllegalArgumentException(INVALID_INPUT);
|
||||
|
||||
matrix4_proj(val, vec3);
|
||||
}
|
||||
|
||||
static void matrix4_proj(float[] mat, float[] vec) {
|
||||
float inv_w = 1.0f / (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32] + mat[M33]);
|
||||
float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03]) * inv_w;
|
||||
float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13]) * inv_w;
|
||||
float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23]) * inv_w;
|
||||
vec[0] = x;
|
||||
vec[1] = y;
|
||||
vec[2] = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply rhs onto Matrix.
|
||||
*
|
||||
* @param rhs right hand side
|
||||
*/
|
||||
public void multiplyRhs(GLMatrix rhs) {
|
||||
matrix4_mul(val, rhs.val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this matrix as rhs, multiply it on lhs and store result.
|
||||
*
|
||||
* @param lhs right hand side
|
||||
*/
|
||||
public void multiplyLhs(GLMatrix lhs) {
|
||||
System.arraycopy(lhs.val, 0, tmp, 0, 16);
|
||||
matrix4_mul(tmp, val);
|
||||
System.arraycopy(tmp, 0, val, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply rhs onto lhs and store result in Matrix.
|
||||
*
|
||||
* This matrix MUST be different from lhs and rhs!
|
||||
*
|
||||
* As you know, when combining matrices for vector projection
|
||||
* this has the same effect first as applying rhs then lhs.
|
||||
*
|
||||
* @param lhs left hand side
|
||||
* @param rhs right hand side
|
||||
*/
|
||||
public void multiplyMM(GLMatrix lhs, GLMatrix rhs) {
|
||||
System.arraycopy(lhs.val, 0, tmp, 0, 16);
|
||||
matrix4_mul(tmp, rhs.val);
|
||||
System.arraycopy(tmp, 0, val, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transpose mat and store result in Matrix
|
||||
*
|
||||
* @param mat to transpose
|
||||
*/
|
||||
public void transposeM(GLMatrix mat) {
|
||||
val[M00] = mat.val[M00];
|
||||
val[M01] = mat.val[M10];
|
||||
val[M02] = mat.val[M20];
|
||||
val[M03] = mat.val[M30];
|
||||
val[M10] = mat.val[M01];
|
||||
val[M11] = mat.val[M11];
|
||||
val[M12] = mat.val[M21];
|
||||
val[M13] = mat.val[M31];
|
||||
val[M20] = mat.val[M02];
|
||||
val[M21] = mat.val[M12];
|
||||
val[M22] = mat.val[M22];
|
||||
val[M23] = mat.val[M32];
|
||||
val[M30] = mat.val[M03];
|
||||
val[M31] = mat.val[M13];
|
||||
val[M32] = mat.val[M23];
|
||||
val[M33] = mat.val[M33];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set rotation
|
||||
*
|
||||
* @param a angle in degree
|
||||
* @param x around x-axis
|
||||
* @param y around y-axis
|
||||
* @param z around z-axis
|
||||
*/
|
||||
public void setRotation(float a, float x, float y, float z) {
|
||||
setRotateM(val, 0, a, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set translation
|
||||
*
|
||||
* @param x along x-axis
|
||||
* @param y along y-axis
|
||||
* @param z along z-axis
|
||||
*/
|
||||
public void setTranslation(float x, float y, float z) {
|
||||
setIdentity();
|
||||
val[M03] = x;
|
||||
val[M13] = y;
|
||||
val[M23] = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set scale factor
|
||||
*
|
||||
* @param x axis
|
||||
* @param y axis
|
||||
* @param z axis
|
||||
*/
|
||||
public void setScale(float x, float y, float z) {
|
||||
setIdentity();
|
||||
val[M00] = x;
|
||||
val[M11] = y;
|
||||
val[M22] = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set translation and x,y scale
|
||||
*
|
||||
* @param tx translate x
|
||||
* @param ty translate y
|
||||
* @param scale factor x,y
|
||||
*/
|
||||
public void setTransScale(float tx, float ty, float scale) {
|
||||
setIdentity();
|
||||
val[M03] = tx;
|
||||
val[M13] = ty;
|
||||
|
||||
val[M00] = scale;
|
||||
val[M11] = scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Matrix with glUniformMatrix
|
||||
*
|
||||
* @param location GL location id
|
||||
*/
|
||||
public void setAsUniform(int location) {
|
||||
buffer.clear();
|
||||
buffer.put(val, 0, 16);
|
||||
buffer.position(0);
|
||||
MapRenderer.GL.glUniformMatrix4fv(location, 1, false, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set single value
|
||||
*
|
||||
* @param pos at position
|
||||
* @param value value to set
|
||||
*/
|
||||
public void setValue(int pos, float value) {
|
||||
val[pos] = value;
|
||||
}
|
||||
|
||||
static float PiTimesThumb = 1.0f / (1 << 11);
|
||||
|
||||
/**
|
||||
* add some offset (similar to glDepthOffset)
|
||||
*
|
||||
* @param delta offset
|
||||
*/
|
||||
public void addDepthOffset(int delta) {
|
||||
val[10] *= 1.0f + PiTimesThumb * delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set identity matrix
|
||||
*/
|
||||
public void setIdentity() {
|
||||
val[M00] = 1;
|
||||
val[M01] = 0;
|
||||
val[M02] = 0;
|
||||
val[M03] = 0;
|
||||
val[M10] = 0;
|
||||
val[M11] = 1;
|
||||
val[M12] = 0;
|
||||
val[M13] = 0;
|
||||
val[M20] = 0;
|
||||
val[M21] = 0;
|
||||
val[M22] = 1;
|
||||
val[M23] = 0;
|
||||
val[M30] = 0;
|
||||
val[M31] = 0;
|
||||
val[M32] = 0;
|
||||
val[M33] = 1;
|
||||
}
|
||||
|
||||
static void matrix4_mul(float[] mata, float[] matb) {
|
||||
float tmp[] = new float[16];
|
||||
tmp[M00] = mata[M00] * matb[M00] + mata[M01] * matb[M10] + mata[M02] * matb[M20]
|
||||
+ mata[M03] * matb[M30];
|
||||
tmp[M01] = mata[M00] * matb[M01] + mata[M01] * matb[M11] + mata[M02] * matb[M21]
|
||||
+ mata[M03] * matb[M31];
|
||||
tmp[M02] = mata[M00] * matb[M02] + mata[M01] * matb[M12] + mata[M02] * matb[M22]
|
||||
+ mata[M03] * matb[M32];
|
||||
tmp[M03] = mata[M00] * matb[M03] + mata[M01] * matb[M13] + mata[M02] * matb[M23]
|
||||
+ mata[M03] * matb[M33];
|
||||
tmp[M10] = mata[M10] * matb[M00] + mata[M11] * matb[M10] + mata[M12] * matb[M20]
|
||||
+ mata[M13] * matb[M30];
|
||||
tmp[M11] = mata[M10] * matb[M01] + mata[M11] * matb[M11] + mata[M12] * matb[M21]
|
||||
+ mata[M13] * matb[M31];
|
||||
tmp[M12] = mata[M10] * matb[M02] + mata[M11] * matb[M12] + mata[M12] * matb[M22]
|
||||
+ mata[M13] * matb[M32];
|
||||
tmp[M13] = mata[M10] * matb[M03] + mata[M11] * matb[M13] + mata[M12] * matb[M23]
|
||||
+ mata[M13] * matb[M33];
|
||||
tmp[M20] = mata[M20] * matb[M00] + mata[M21] * matb[M10] + mata[M22] * matb[M20]
|
||||
+ mata[M23] * matb[M30];
|
||||
tmp[M21] = mata[M20] * matb[M01] + mata[M21] * matb[M11] + mata[M22] * matb[M21]
|
||||
+ mata[M23] * matb[M31];
|
||||
tmp[M22] = mata[M20] * matb[M02] + mata[M21] * matb[M12] + mata[M22] * matb[M22]
|
||||
+ mata[M23] * matb[M32];
|
||||
tmp[M23] = mata[M20] * matb[M03] + mata[M21] * matb[M13] + mata[M22] * matb[M23]
|
||||
+ mata[M23] * matb[M33];
|
||||
tmp[M30] = mata[M30] * matb[M00] + mata[M31] * matb[M10] + mata[M32] * matb[M20]
|
||||
+ mata[M33] * matb[M30];
|
||||
tmp[M31] = mata[M30] * matb[M01] + mata[M31] * matb[M11] + mata[M32] * matb[M21]
|
||||
+ mata[M33] * matb[M31];
|
||||
tmp[M32] = mata[M30] * matb[M02] + mata[M31] * matb[M12] + mata[M32] * matb[M22]
|
||||
+ mata[M33] * matb[M32];
|
||||
tmp[M33] = mata[M30] * matb[M03] + mata[M31] * matb[M13] + mata[M32] * matb[M23]
|
||||
+ mata[M33] * matb[M33];
|
||||
System.arraycopy(tmp, 0, mata, 0, 16);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void finalize() {
|
||||
// if (pointer != 0)
|
||||
// delete(pointer);
|
||||
// }
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define a projection matrix in terms of six clip planes
|
||||
*
|
||||
* @param m the float array that holds the perspective matrix
|
||||
* @param offset the offset into float array m where the perspective
|
||||
* matrix data is written
|
||||
*/
|
||||
public static void frustumM(float[] m, int offset,
|
||||
float left, float right, float bottom, float top,
|
||||
float near, float far) {
|
||||
if (left == right) {
|
||||
throw new IllegalArgumentException("left == right");
|
||||
}
|
||||
if (top == bottom) {
|
||||
throw new IllegalArgumentException("top == bottom");
|
||||
}
|
||||
if (near == far) {
|
||||
throw new IllegalArgumentException("near == far");
|
||||
}
|
||||
if (near <= 0.0f) {
|
||||
throw new IllegalArgumentException("near <= 0.0f");
|
||||
}
|
||||
if (far <= 0.0f) {
|
||||
throw new IllegalArgumentException("far <= 0.0f");
|
||||
}
|
||||
final float r_width = 1.0f / (right - left);
|
||||
final float r_height = 1.0f / (top - bottom);
|
||||
final float r_depth = 1.0f / (near - far);
|
||||
final float x = 2.0f * (near * r_width);
|
||||
final float y = 2.0f * (near * r_height);
|
||||
final float A = (right + left) * r_width;
|
||||
final float B = (top + bottom) * r_height;
|
||||
final float C = (far + near) * r_depth;
|
||||
final float D = 2.0f * (far * near * r_depth);
|
||||
m[offset + 0] = x;
|
||||
m[offset + 5] = y;
|
||||
m[offset + 8] = A;
|
||||
m[offset + 9] = B;
|
||||
m[offset + 10] = C;
|
||||
m[offset + 14] = D;
|
||||
m[offset + 11] = -1.0f;
|
||||
m[offset + 1] = 0.0f;
|
||||
m[offset + 2] = 0.0f;
|
||||
m[offset + 3] = 0.0f;
|
||||
m[offset + 4] = 0.0f;
|
||||
m[offset + 6] = 0.0f;
|
||||
m[offset + 7] = 0.0f;
|
||||
m[offset + 12] = 0.0f;
|
||||
m[offset + 13] = 0.0f;
|
||||
m[offset + 15] = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts a 4 x 4 matrix.
|
||||
*
|
||||
* @param mInv the array that holds the output inverted matrix
|
||||
* @param mInvOffset an offset into mInv where the inverted matrix is
|
||||
* stored.
|
||||
* @param m the input array
|
||||
* @param mOffset an offset into m where the matrix is stored.
|
||||
* @return true if the matrix could be inverted, false if it could not.
|
||||
*/
|
||||
public static boolean invertM(float[] mInv, int mInvOffset, float[] m,
|
||||
int mOffset) {
|
||||
// Invert a 4 x 4 matrix using Cramer's Rule
|
||||
|
||||
// transpose matrix
|
||||
final float src0 = m[mOffset + 0];
|
||||
final float src4 = m[mOffset + 1];
|
||||
final float src8 = m[mOffset + 2];
|
||||
final float src12 = m[mOffset + 3];
|
||||
|
||||
final float src1 = m[mOffset + 4];
|
||||
final float src5 = m[mOffset + 5];
|
||||
final float src9 = m[mOffset + 6];
|
||||
final float src13 = m[mOffset + 7];
|
||||
|
||||
final float src2 = m[mOffset + 8];
|
||||
final float src6 = m[mOffset + 9];
|
||||
final float src10 = m[mOffset + 10];
|
||||
final float src14 = m[mOffset + 11];
|
||||
|
||||
final float src3 = m[mOffset + 12];
|
||||
final float src7 = m[mOffset + 13];
|
||||
final float src11 = m[mOffset + 14];
|
||||
final float src15 = m[mOffset + 15];
|
||||
|
||||
// calculate pairs for first 8 elements (cofactors)
|
||||
final float atmp0 = src10 * src15;
|
||||
final float atmp1 = src11 * src14;
|
||||
final float atmp2 = src9 * src15;
|
||||
final float atmp3 = src11 * src13;
|
||||
final float atmp4 = src9 * src14;
|
||||
final float atmp5 = src10 * src13;
|
||||
final float atmp6 = src8 * src15;
|
||||
final float atmp7 = src11 * src12;
|
||||
final float atmp8 = src8 * src14;
|
||||
final float atmp9 = src10 * src12;
|
||||
final float atmp10 = src8 * src13;
|
||||
final float atmp11 = src9 * src12;
|
||||
|
||||
// calculate first 8 elements (cofactors)
|
||||
final float dst0 = (atmp0 * src5 + atmp3 * src6 + atmp4 * src7)
|
||||
- (atmp1 * src5 + atmp2 * src6 + atmp5 * src7);
|
||||
final float dst1 = (atmp1 * src4 + atmp6 * src6 + atmp9 * src7)
|
||||
- (atmp0 * src4 + atmp7 * src6 + atmp8 * src7);
|
||||
final float dst2 = (atmp2 * src4 + atmp7 * src5 + atmp10 * src7)
|
||||
- (atmp3 * src4 + atmp6 * src5 + atmp11 * src7);
|
||||
final float dst3 = (atmp5 * src4 + atmp8 * src5 + atmp11 * src6)
|
||||
- (atmp4 * src4 + atmp9 * src5 + atmp10 * src6);
|
||||
final float dst4 = (atmp1 * src1 + atmp2 * src2 + atmp5 * src3)
|
||||
- (atmp0 * src1 + atmp3 * src2 + atmp4 * src3);
|
||||
final float dst5 = (atmp0 * src0 + atmp7 * src2 + atmp8 * src3)
|
||||
- (atmp1 * src0 + atmp6 * src2 + atmp9 * src3);
|
||||
final float dst6 = (atmp3 * src0 + atmp6 * src1 + atmp11 * src3)
|
||||
- (atmp2 * src0 + atmp7 * src1 + atmp10 * src3);
|
||||
final float dst7 = (atmp4 * src0 + atmp9 * src1 + atmp10 * src2)
|
||||
- (atmp5 * src0 + atmp8 * src1 + atmp11 * src2);
|
||||
|
||||
// calculate pairs for second 8 elements (cofactors)
|
||||
final float btmp0 = src2 * src7;
|
||||
final float btmp1 = src3 * src6;
|
||||
final float btmp2 = src1 * src7;
|
||||
final float btmp3 = src3 * src5;
|
||||
final float btmp4 = src1 * src6;
|
||||
final float btmp5 = src2 * src5;
|
||||
final float btmp6 = src0 * src7;
|
||||
final float btmp7 = src3 * src4;
|
||||
final float btmp8 = src0 * src6;
|
||||
final float btmp9 = src2 * src4;
|
||||
final float btmp10 = src0 * src5;
|
||||
final float btmp11 = src1 * src4;
|
||||
|
||||
// calculate second 8 elements (cofactors)
|
||||
final float dst8 = (btmp0 * src13 + btmp3 * src14 + btmp4 * src15)
|
||||
- (btmp1 * src13 + btmp2 * src14 + btmp5 * src15);
|
||||
final float dst9 = (btmp1 * src12 + btmp6 * src14 + btmp9 * src15)
|
||||
- (btmp0 * src12 + btmp7 * src14 + btmp8 * src15);
|
||||
final float dst10 = (btmp2 * src12 + btmp7 * src13 + btmp10 * src15)
|
||||
- (btmp3 * src12 + btmp6 * src13 + btmp11 * src15);
|
||||
final float dst11 = (btmp5 * src12 + btmp8 * src13 + btmp11 * src14)
|
||||
- (btmp4 * src12 + btmp9 * src13 + btmp10 * src14);
|
||||
final float dst12 = (btmp2 * src10 + btmp5 * src11 + btmp1 * src9)
|
||||
- (btmp4 * src11 + btmp0 * src9 + btmp3 * src10);
|
||||
final float dst13 = (btmp8 * src11 + btmp0 * src8 + btmp7 * src10)
|
||||
- (btmp6 * src10 + btmp9 * src11 + btmp1 * src8);
|
||||
final float dst14 = (btmp6 * src9 + btmp11 * src11 + btmp3 * src8)
|
||||
- (btmp10 * src11 + btmp2 * src8 + btmp7 * src9);
|
||||
final float dst15 = (btmp10 * src10 + btmp4 * src8 + btmp9 * src9)
|
||||
- (btmp8 * src9 + btmp11 * src10 + btmp5 * src8);
|
||||
|
||||
// calculate determinant
|
||||
final float det =
|
||||
src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3;
|
||||
|
||||
if (det == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// calculate matrix inverse
|
||||
final float invdet = 1.0f / det;
|
||||
mInv[mInvOffset] = dst0 * invdet;
|
||||
mInv[1 + mInvOffset] = dst1 * invdet;
|
||||
mInv[2 + mInvOffset] = dst2 * invdet;
|
||||
mInv[3 + mInvOffset] = dst3 * invdet;
|
||||
|
||||
mInv[4 + mInvOffset] = dst4 * invdet;
|
||||
mInv[5 + mInvOffset] = dst5 * invdet;
|
||||
mInv[6 + mInvOffset] = dst6 * invdet;
|
||||
mInv[7 + mInvOffset] = dst7 * invdet;
|
||||
|
||||
mInv[8 + mInvOffset] = dst8 * invdet;
|
||||
mInv[9 + mInvOffset] = dst9 * invdet;
|
||||
mInv[10 + mInvOffset] = dst10 * invdet;
|
||||
mInv[11 + mInvOffset] = dst11 * invdet;
|
||||
|
||||
mInv[12 + mInvOffset] = dst12 * invdet;
|
||||
mInv[13 + mInvOffset] = dst13 * invdet;
|
||||
mInv[14 + mInvOffset] = dst14 * invdet;
|
||||
mInv[15 + mInvOffset] = dst15 * invdet;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setRotateM(float[] rm, int rmOffset, float a, float x, float y, float z)
|
||||
{
|
||||
rm[rmOffset + 3] = 0;
|
||||
rm[rmOffset + 7] = 0;
|
||||
rm[rmOffset + 11] = 0;
|
||||
rm[rmOffset + 12] = 0;
|
||||
rm[rmOffset + 13] = 0;
|
||||
rm[rmOffset + 14] = 0;
|
||||
rm[rmOffset + 15] = 1;
|
||||
a *= (float) (Math.PI / 180.0f);
|
||||
float s = (float) Math.sin(a);
|
||||
float c = (float) Math.cos(a);
|
||||
if (1.0f == x && 0.0f == y && 0.0f == z)
|
||||
{
|
||||
rm[rmOffset + 5] = c;
|
||||
rm[rmOffset + 10] = c;
|
||||
rm[rmOffset + 6] = s;
|
||||
rm[rmOffset + 9] = -s;
|
||||
rm[rmOffset + 1] = 0;
|
||||
rm[rmOffset + 2] = 0;
|
||||
rm[rmOffset + 4] = 0;
|
||||
rm[rmOffset + 8] = 0;
|
||||
rm[rmOffset + 0] = 1;
|
||||
}
|
||||
else if (0.0f == x && 1.0f == y && 0.0f == z)
|
||||
{
|
||||
rm[rmOffset + 0] = c;
|
||||
rm[rmOffset + 10] = c;
|
||||
rm[rmOffset + 8] = s;
|
||||
rm[rmOffset + 2] = -s;
|
||||
rm[rmOffset + 1] = 0;
|
||||
rm[rmOffset + 4] = 0;
|
||||
rm[rmOffset + 6] = 0;
|
||||
rm[rmOffset + 9] = 0;
|
||||
rm[rmOffset + 5] = 1;
|
||||
}
|
||||
else if (0.0f == x && 0.0f == y && 1.0f == z)
|
||||
{
|
||||
rm[rmOffset + 0] = c;
|
||||
rm[rmOffset + 5] = c;
|
||||
rm[rmOffset + 1] = s;
|
||||
rm[rmOffset + 4] = -s;
|
||||
rm[rmOffset + 2] = 0;
|
||||
rm[rmOffset + 6] = 0;
|
||||
rm[rmOffset + 8] = 0;
|
||||
rm[rmOffset + 9] = 0;
|
||||
rm[rmOffset + 10] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
float len = (float) Math.sqrt(x * x + y * y + z * z);
|
||||
if (1.0f != len)
|
||||
{
|
||||
float recipLen = 1.0f / len;
|
||||
x *= recipLen;
|
||||
y *= recipLen;
|
||||
z *= recipLen;
|
||||
}
|
||||
float nc = 1.0f - c;
|
||||
float xy = x * y;
|
||||
float yz = y * z;
|
||||
float zx = z * x;
|
||||
float xs = x * s;
|
||||
float ys = y * s;
|
||||
float zs = z * s;
|
||||
rm[rmOffset + 0] = x * x * nc + c;
|
||||
rm[rmOffset + 4] = xy * nc - zs;
|
||||
rm[rmOffset + 8] = zx * nc + ys;
|
||||
rm[rmOffset + 1] = xy * nc + zs;
|
||||
rm[rmOffset + 5] = y * y * nc + c;
|
||||
rm[rmOffset + 9] = yz * nc - xs;
|
||||
rm[rmOffset + 2] = zx * nc - ys;
|
||||
rm[rmOffset + 6] = yz * nc + xs;
|
||||
rm[rmOffset + 10] = z * z * nc + c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2013 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.tiling.source;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.tiling.source.UrlTileDataSource;
|
||||
|
||||
import com.google.gwt.typedarrays.client.Uint8ArrayNative;
|
||||
import com.google.gwt.typedarrays.shared.Uint8Array;
|
||||
import com.google.gwt.xhr.client.ReadyStateChangeHandler;
|
||||
import com.google.gwt.xhr.client.XMLHttpRequest;
|
||||
import com.google.gwt.xhr.client.XMLHttpRequest.ResponseType;
|
||||
|
||||
public class LwHttp {
|
||||
//static final Logger log = LoggerFactory.getLogger(LwHttp.class);
|
||||
|
||||
private final String mUrlPath;
|
||||
private final byte[] mRequestBuffer;
|
||||
|
||||
|
||||
private int mContentLength = -1;
|
||||
private XMLHttpRequest mHttpRequest;
|
||||
|
||||
private ReadyStateChangeHandler mResponseHandler;
|
||||
|
||||
public LwHttp(URL url) {
|
||||
mUrlPath = url.toString();
|
||||
mRequestBuffer = new byte[1024];
|
||||
}
|
||||
|
||||
static class Buffer extends InputStream {
|
||||
Uint8Array mBuffer;
|
||||
int mPos;
|
||||
int mEnd;
|
||||
|
||||
public Buffer(Uint8Array buf) {
|
||||
mBuffer = buf;
|
||||
mPos = 0;
|
||||
mEnd = buf.byteLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int read() throws IOException {
|
||||
if (mPos < mEnd)
|
||||
return mBuffer.get(mPos++);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (mHttpRequest != null)
|
||||
mHttpRequest.abort();
|
||||
}
|
||||
|
||||
private UrlTileDataSource mDataSource;
|
||||
|
||||
public boolean sendRequest(Tile tile, UrlTileDataSource dataSource) throws IOException {
|
||||
mDataSource = dataSource;
|
||||
|
||||
byte[] request = mRequestBuffer;
|
||||
int pos = 0;
|
||||
|
||||
pos = dataSource.getTileSource().formatTilePath(tile, request, pos);
|
||||
|
||||
String url = mUrlPath + (new String(request, 0, pos));
|
||||
|
||||
mHttpRequest = XMLHttpRequest.create();
|
||||
mHttpRequest.open("GET", url);
|
||||
mHttpRequest.setResponseType(ResponseType.ArrayBuffer);
|
||||
|
||||
mResponseHandler = new ReadyStateChangeHandler() {
|
||||
|
||||
@Override
|
||||
public void onReadyStateChange(XMLHttpRequest xhr) {
|
||||
int state = xhr.getReadyState();
|
||||
//log.debug(mCurrentUrl + "response " + status + "/" + state);
|
||||
|
||||
if (state == XMLHttpRequest.DONE) {
|
||||
|
||||
int status = xhr.getStatus();
|
||||
|
||||
if (status == 200) {
|
||||
Uint8Array buf = Uint8ArrayNative.create(xhr.getResponseArrayBuffer());
|
||||
|
||||
mDataSource.process(new Buffer(buf));
|
||||
} else {
|
||||
mDataSource.process(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mHttpRequest.setOnReadyStateChange(mResponseHandler);
|
||||
mHttpRequest.send();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// write (positive) integer to byte array
|
||||
protected static int writeInt(int val, int pos, byte[] buf) {
|
||||
if (val == 0) {
|
||||
buf[pos] = '0';
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (int n = val; n > 0; n = n / 10, i++)
|
||||
buf[pos + i] = (byte) ('0' + n % 10);
|
||||
|
||||
// reverse bytes
|
||||
for (int j = pos, end = pos + i - 1, mid = pos + i / 2; j < mid; j++, end--) {
|
||||
byte tmp = buf[j];
|
||||
buf[j] = buf[end];
|
||||
buf[end] = tmp;
|
||||
}
|
||||
|
||||
return pos + i;
|
||||
}
|
||||
|
||||
// parse (positive) integer from byte array
|
||||
protected static int parseInt(byte[] buf, int pos, int end) {
|
||||
int val = 0;
|
||||
for (; pos < end; pos++)
|
||||
val = val * 10 + (buf[pos]) - '0';
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public void requestCompleted() {
|
||||
|
||||
mHttpRequest.clearOnReadyStateChange();
|
||||
mHttpRequest = null;
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return mContentLength;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.tiling.source;
|
||||
|
||||
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.layers.tile.TileLoader;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class UrlTileDataSource implements ITileDataSource {
|
||||
static final Logger log = LoggerFactory.getLogger(UrlTileDataSource.class);
|
||||
|
||||
protected final LwHttp mConn;
|
||||
protected final ITileDecoder mTileDecoder;
|
||||
protected final UrlTileSource mTileSource;
|
||||
|
||||
public UrlTileDataSource(UrlTileSource tileSource, ITileDecoder tileDecoder, LwHttp conn) {
|
||||
mTileSource = tileSource;
|
||||
mTileDecoder = tileDecoder;
|
||||
mConn = conn;
|
||||
}
|
||||
|
||||
UrlTileSource getTileSource() {
|
||||
return mTileSource;
|
||||
}
|
||||
|
||||
private ITileDataSink mSink;
|
||||
private MapTile mTile;
|
||||
|
||||
@Override
|
||||
public void query(MapTile tile, ITileDataSink sink) {
|
||||
mTile = tile;
|
||||
mSink = sink;
|
||||
try {
|
||||
mConn.sendRequest(tile, this);
|
||||
} catch (Exception e) {
|
||||
///e.printStackTrace();
|
||||
log.error("{} {}", mTile, e.getMessage());
|
||||
sink.completed(FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
public void process(final InputStream is) {
|
||||
TileLoader.postLoadDelay(new org.oscim.layers.tile.LoadDelayTask() {
|
||||
|
||||
@Override
|
||||
public void continueLoading() {
|
||||
if (!mTile.state(MapTile.State.LOADING)) {
|
||||
mConn.requestCompleted();
|
||||
mSink.completed(FAILED);
|
||||
mTile = null;
|
||||
mSink = null;
|
||||
}
|
||||
boolean win = false;
|
||||
if (is != null) {
|
||||
try {
|
||||
win = mTileDecoder.decode(mTile, mSink, is);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (!win)
|
||||
log.debug("{} failed", mTile);
|
||||
|
||||
mConn.requestCompleted();
|
||||
|
||||
mSink.completed(win ? SUCCESS : FAILED);
|
||||
|
||||
mTile = null;
|
||||
mSink = null;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
mConn.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package org.oscim.tiling.source.bitmap;
|
||||
|
||||
import static org.oscim.tiling.ITileDataSink.QueryResult.FAILED;
|
||||
import static org.oscim.tiling.ITileDataSink.QueryResult.SUCCESS;
|
||||
|
||||
import org.oscim.gdx.client.GwtBitmap;
|
||||
import org.oscim.layers.tile.MapTile;
|
||||
import org.oscim.layers.tile.TileLoader;
|
||||
import org.oscim.tiling.ITileDataSink;
|
||||
import org.oscim.tiling.ITileDataSource;
|
||||
import org.oscim.tiling.source.LwHttp;
|
||||
import org.oscim.tiling.source.UrlTileSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gwt.event.dom.client.ErrorEvent;
|
||||
import com.google.gwt.event.dom.client.ErrorHandler;
|
||||
import com.google.gwt.event.dom.client.LoadEvent;
|
||||
import com.google.gwt.event.dom.client.LoadHandler;
|
||||
import com.google.gwt.safehtml.shared.SafeUri;
|
||||
import com.google.gwt.safehtml.shared.UriUtils;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
|
||||
public abstract class BitmapTileSource extends UrlTileSource {
|
||||
static final Logger log = LoggerFactory.getLogger(LwHttp.class);
|
||||
|
||||
/**
|
||||
* Create BitmapTileSource for 'url'
|
||||
*
|
||||
* By default path will be formatted as: url/z/x/y.png
|
||||
* Use e.g. setExtension(".jpg") to overide ending or
|
||||
* implement getUrlString() for custom formatting.
|
||||
*/
|
||||
public BitmapTileSource(String url, int zoomMin, int zoomMax) {
|
||||
super(url, zoomMin, zoomMax);
|
||||
setExtension(".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITileDataSource getDataSource() {
|
||||
return new BitmapTileDataSource(this);
|
||||
}
|
||||
|
||||
public static class BitmapTileDataSource implements ITileDataSource {
|
||||
|
||||
protected final UrlTileSource mTileSource;
|
||||
private final byte[] mRequestBuffer = new byte[1024];
|
||||
|
||||
public BitmapTileDataSource(BitmapTileSource bitmapTileSource) {
|
||||
mTileSource = bitmapTileSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void query(final MapTile tile, final ITileDataSink sink) {
|
||||
|
||||
int pos = mTileSource.formatTilePath(tile, mRequestBuffer, 0);
|
||||
|
||||
String url = mTileSource.getUrl()
|
||||
+ (new String(mRequestBuffer, 0, pos));
|
||||
|
||||
SafeUri uri = UriUtils.fromTrustedString(url);
|
||||
|
||||
final Image img = new Image();
|
||||
img.setVisible(false);
|
||||
|
||||
/* As if researching CORS issues doesnt result in
|
||||
* enough headache...
|
||||
*
|
||||
* Here are some more special Chrome/Webkit quirks:
|
||||
* MUST SET CORS BEFORE URL! */
|
||||
img.getElement().setAttribute("crossorigin", "anonymous");
|
||||
img.setUrl(uri);
|
||||
|
||||
RootPanel.get().add(img);
|
||||
|
||||
img.addLoadHandler(new LoadHandler() {
|
||||
public void onLoad(LoadEvent event) {
|
||||
TileLoader.postLoadDelay(new org.oscim.layers.tile.LoadDelayTask() {
|
||||
|
||||
@Override
|
||||
public void continueLoading() {
|
||||
if (!tile.state(MapTile.State.LOADING)) {
|
||||
sink.completed(FAILED);
|
||||
RootPanel.get().remove(img);
|
||||
} else {
|
||||
sink.setTileImage(new GwtBitmap(img));
|
||||
sink.completed(SUCCESS);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
img.addErrorHandler(new ErrorHandler() {
|
||||
|
||||
@Override
|
||||
public void onError(ErrorEvent event) {
|
||||
sink.completed(FAILED);
|
||||
RootPanel.get().remove(img);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
||||
}
|
||||
58
vtm-web/src/org/oscim/gdx/emu/org/oscim/utils/IOUtils.java
Normal file
58
vtm-web/src/org/oscim/gdx/emu/org/oscim/utils/IOUtils.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.utils;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A utility class with IO-specific helper methods.
|
||||
*/
|
||||
public final class IOUtils {
|
||||
|
||||
/**
|
||||
* Invokes the {@link Closeable#close()} method on the given object. If an
|
||||
* {@link IOException} occurs during the
|
||||
* method call, it will be caught and logged on level {@link Level#WARNING}.
|
||||
*
|
||||
* @param closeable
|
||||
* the data source which should be closed (may be null).
|
||||
*/
|
||||
public static void closeQuietly(OutputStream closeable) {
|
||||
try {
|
||||
if (closeable != null) {
|
||||
closeable.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//log.debug(e.getMessage() + " " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeQuietly(InputStream closeable) {
|
||||
try {
|
||||
if (closeable != null) {
|
||||
closeable.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//log.debug(e.getMessage() + " " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private IOUtils() {
|
||||
}
|
||||
}
|
||||
200
vtm-web/src/org/oscim/gdx/emu/org/oscim/utils/Tessellator.java
Normal file
200
vtm-web/src/org/oscim/gdx/emu/org/oscim/utils/Tessellator.java
Normal file
@@ -0,0 +1,200 @@
|
||||
package org.oscim.utils;
|
||||
|
||||
import org.oscim.core.GeometryBuffer;
|
||||
import org.oscim.renderer.elements.VertexItem;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gwt.core.client.JavaScriptException;
|
||||
import com.google.gwt.core.client.JavaScriptObject;
|
||||
import com.google.gwt.core.client.JsArrayInteger;
|
||||
import com.google.gwt.core.client.JsArrayNumber;
|
||||
import com.google.gwt.core.client.JsArrayUtils;
|
||||
import com.google.gwt.typedarrays.shared.Float32Array;
|
||||
import com.google.gwt.typedarrays.shared.Int32Array;
|
||||
|
||||
public class Tessellator {
|
||||
static final Logger log = LoggerFactory.getLogger(Tessellator.class);
|
||||
|
||||
public static int tessellate(GeometryBuffer geom, float scale,
|
||||
VertexItem outPoints, VertexItem outTris, int vertexOffset) {
|
||||
|
||||
int numIndices = 0;
|
||||
int indexPos = 0;
|
||||
int pointPos = 0;
|
||||
int indexEnd = geom.index.length;
|
||||
|
||||
JsArrayNumber jspoints = JsArrayUtils.readOnlyJsArray(geom.points);
|
||||
JsArrayInteger jsindex = JsArrayUtils.readOnlyJsArray(geom.index);
|
||||
|
||||
for (int idx = 0; idx < indexEnd && geom.index[idx] > 0; idx++) {
|
||||
indexPos = idx;
|
||||
|
||||
int numRings = 1;
|
||||
int numPoints = geom.index[idx++];
|
||||
|
||||
for (; idx < indexEnd && geom.index[idx] > 0; idx++) {
|
||||
numRings++;
|
||||
numPoints += geom.index[idx];
|
||||
}
|
||||
|
||||
if (numPoints <= 0 && numRings == 1){
|
||||
log.debug("tessellation skip empty");
|
||||
pointPos += numPoints;
|
||||
continue;
|
||||
}
|
||||
|
||||
TessResult res;
|
||||
try {
|
||||
res = tessellate2(jspoints, pointPos, numPoints,
|
||||
jsindex, indexPos, numRings);
|
||||
} catch (JavaScriptException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
pointPos += numPoints;
|
||||
|
||||
if (res == null) {
|
||||
log.debug("tessellation failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
Int32Array io = res.getIndices(res);
|
||||
int resIndices = io.length();
|
||||
numIndices += resIndices;
|
||||
|
||||
for (int k = 0, cnt = 0; k < resIndices; k += cnt) {
|
||||
|
||||
if (outTris.used == VertexItem.SIZE) {
|
||||
outTris.next = VertexItem.pool.get();
|
||||
outTris = outTris.next;
|
||||
}
|
||||
|
||||
cnt = VertexItem.SIZE - outTris.used;
|
||||
|
||||
if (k + cnt > resIndices)
|
||||
cnt = resIndices - k;
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
outTris.vertices[outTris.used + i] =
|
||||
(short) (vertexOffset + io.get(k + i));
|
||||
|
||||
outTris.used += cnt;
|
||||
}
|
||||
|
||||
Float32Array po = res.getPoints(res);
|
||||
int resPoints = po.length();
|
||||
|
||||
vertexOffset += (resPoints >> 1);
|
||||
|
||||
for (int k = 0, cnt = 0; k < resPoints; k += cnt) {
|
||||
|
||||
if (outPoints.used == VertexItem.SIZE) {
|
||||
outPoints.next = VertexItem.pool.get();
|
||||
outPoints = outPoints.next;
|
||||
}
|
||||
|
||||
cnt = VertexItem.SIZE - outPoints.used;
|
||||
|
||||
if (k + cnt > resPoints)
|
||||
cnt = resPoints - k;
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
outPoints.vertices[outPoints.used + i] =
|
||||
(short) (po.get(k + i) * scale);
|
||||
|
||||
outPoints.used += cnt;
|
||||
}
|
||||
|
||||
if (idx >= indexEnd || geom.index[idx] < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return numIndices;
|
||||
}
|
||||
|
||||
public static int tessellate(float[] points, int ppos, int plen, short[] index,
|
||||
int ipos, int rings, int vertexOffset, VertexItem outTris) {
|
||||
|
||||
Int32Array io;
|
||||
try {
|
||||
io = tessellate(JsArrayUtils.readOnlyJsArray(points), ppos, plen,
|
||||
JsArrayUtils.readOnlyJsArray(index), ipos, rings);
|
||||
} catch (JavaScriptException e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (io == null) {
|
||||
//log.debug("building tessellation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if (vo.length() != plen) {
|
||||
// // TODO handle different output points
|
||||
// log.debug(" + io.length());
|
||||
//
|
||||
// //for (int i = 0; i < vo.length(); i += 2)
|
||||
// // log.debug(vo.get(i) + " " + vo.get(i + 1));
|
||||
// //for (int i = ppos; i < ppos + plen; i += 2)
|
||||
// // log.debug( points[i]+ " " + points[i + 1]);
|
||||
//
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int numIndices = io.length();
|
||||
|
||||
for (int k = 0, cnt = 0; k < numIndices; k += cnt) {
|
||||
|
||||
if (outTris.used == VertexItem.SIZE) {
|
||||
outTris.next = VertexItem.pool.get();
|
||||
outTris = outTris.next;
|
||||
}
|
||||
|
||||
cnt = VertexItem.SIZE - outTris.used;
|
||||
|
||||
if (k + cnt > numIndices)
|
||||
cnt = numIndices - k;
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
int idx = (vertexOffset + io.get(k + i));
|
||||
outTris.vertices[outTris.used + i] = (short) idx;
|
||||
}
|
||||
outTris.used += cnt;
|
||||
}
|
||||
|
||||
return numIndices;
|
||||
}
|
||||
|
||||
public static int tessellate(GeometryBuffer geom, GeometryBuffer out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static native Int32Array tessellate(JsArrayNumber points, int pOffset, int pLength,
|
||||
JsArrayInteger bounds, int bOffset, int bLength)/*-{
|
||||
|
||||
return $wnd.tessellate(points, pOffset, pOffset + pLength, bounds,
|
||||
bOffset, bOffset + bLength, false);
|
||||
}-*/;
|
||||
|
||||
static native TessResult tessellate2(JsArrayNumber points, int pOffset, int pLength,
|
||||
JsArrayInteger bounds, int bOffset, int bLength)
|
||||
/*-{
|
||||
|
||||
return $wnd.tessellate(points, pOffset, pOffset + pLength, bounds,
|
||||
bOffset, bOffset + bLength, true);
|
||||
}-*/;
|
||||
|
||||
static final class TessResult extends JavaScriptObject {
|
||||
protected TessResult() {
|
||||
}
|
||||
|
||||
native Float32Array getPoints(JavaScriptObject result)/*-{
|
||||
return result.vertices;
|
||||
}-*/;
|
||||
|
||||
native Int32Array getIndices(JavaScriptObject result)/*-{
|
||||
return result.triangles;
|
||||
}-*/;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.oscim.utils.async;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
/**
|
||||
* GWT emulation of AsynchExecutor, will call tasks immediately :D
|
||||
*
|
||||
* @author badlogic
|
||||
*
|
||||
*/
|
||||
public class AsyncExecutor implements Disposable {
|
||||
|
||||
/**
|
||||
* Creates a new AsynchExecutor that allows maxConcurrent {@link Runnable}
|
||||
* instances to run in parallel.
|
||||
*
|
||||
* @param maxConcurrent
|
||||
*/
|
||||
public AsyncExecutor(int maxConcurrent) {
|
||||
}
|
||||
|
||||
// FIXME TODO add wrap into 'FakeFuture' and run via Gdx.app.post()
|
||||
/**
|
||||
* Submits a {@link Runnable} to be executed asynchronously. If
|
||||
* maxConcurrent runnables are already running, the runnable
|
||||
* will be queued.
|
||||
*
|
||||
* @param task the task to execute asynchronously
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public <T> AsyncResult<T> submit(final AsyncTask<T> task) {
|
||||
|
||||
T result = null;
|
||||
boolean error = false;
|
||||
try {
|
||||
task.run();
|
||||
result = task.getResult();
|
||||
} catch (Throwable t) {
|
||||
error = true;
|
||||
}
|
||||
if (error)
|
||||
return null;
|
||||
|
||||
return new AsyncResult(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits a {@link Runnable} to be executed asynchronously. If
|
||||
* maxConcurrent runnables are already running, the runnable
|
||||
* will be queued.
|
||||
*
|
||||
* @param task the task to execute asynchronously
|
||||
*/
|
||||
public boolean post(Runnable task) {
|
||||
Gdx.app.postRunnable(task);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for running {@link AsyncTask} instances to finish,
|
||||
* then destroys any resources like threads. Can not be used
|
||||
* after this method is called.
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2013 See libgdx AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package org.oscim.utils.async;
|
||||
|
||||
//import java.util.concurrent.ExecutionException;
|
||||
//import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* Returned by {@link AsyncExecutor#submit(AsyncTask)}, allows to poll
|
||||
* for the result of the asynch workload.
|
||||
*
|
||||
* @author badlogic
|
||||
*
|
||||
*/
|
||||
public class AsyncResult<T> {
|
||||
private final T result;
|
||||
|
||||
AsyncResult(T result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the {@link AsyncTask} is done
|
||||
*/
|
||||
public boolean isDone() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the result, or null if there was an error, no result, or the task
|
||||
* is still running
|
||||
*/
|
||||
public T get() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2013 See libgdx AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package org.oscim.utils.async;
|
||||
|
||||
/**
|
||||
* Task to be submitted to an {@link AsyncExecutor}, returning a result of type
|
||||
* T.
|
||||
*
|
||||
* @author badlogic
|
||||
*
|
||||
*/
|
||||
public interface AsyncTask<T> extends Runnable {
|
||||
public boolean cancel();
|
||||
|
||||
public T getResult() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2013 See libgdx AUTHORS file.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
package org.oscim.utils.async;
|
||||
|
||||
/**
|
||||
* GWT emulation of ThreadUtils, does nothing.
|
||||
*
|
||||
* @author badlogic
|
||||
*
|
||||
*/
|
||||
public class ThreadUtils {
|
||||
public static void yield() {
|
||||
}
|
||||
}
|
||||
27
vtm-web/src/org/oscim/gdx/emu/org/xml/sax/Attributes.java
Normal file
27
vtm-web/src/org/oscim/gdx/emu/org/xml/sax/Attributes.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package org.xml.sax;
|
||||
|
||||
public abstract interface Attributes {
|
||||
public abstract int getLength();
|
||||
|
||||
public abstract String getURI(int paramInt);
|
||||
|
||||
public abstract String getLocalName(int paramInt);
|
||||
|
||||
public abstract String getQName(int paramInt);
|
||||
|
||||
public abstract String getType(int paramInt);
|
||||
|
||||
public abstract String getValue(int paramInt);
|
||||
|
||||
public abstract int getIndex(String paramString1, String paramString2);
|
||||
|
||||
public abstract int getIndex(String paramString);
|
||||
|
||||
public abstract String getType(String paramString1, String paramString2);
|
||||
|
||||
public abstract String getType(String paramString);
|
||||
|
||||
public abstract String getValue(String paramString1, String paramString2);
|
||||
|
||||
public abstract String getValue(String paramString);
|
||||
}
|
||||
20
vtm-web/src/org/oscim/gdx/emu/org/xml/sax/SAXException.java
Normal file
20
vtm-web/src/org/oscim/gdx/emu/org/xml/sax/SAXException.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.xml.sax;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SAXException extends IOException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SAXException(String str) {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public SAXException(String str, Throwable throwable)
|
||||
{
|
||||
super(str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.xml.sax;
|
||||
|
||||
public class SAXParseException extends SAXException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SAXParseException(String str) {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public SAXParseException(String str, Throwable throwable)
|
||||
{
|
||||
super(str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.xml.sax.helpers;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
public class DefaultHandler {
|
||||
public void endDocument() {
|
||||
|
||||
}
|
||||
|
||||
public void error(SAXParseException exception) {
|
||||
|
||||
}
|
||||
|
||||
public void warning(SAXParseException exception) {
|
||||
|
||||
}
|
||||
|
||||
public void startElement(String uri, String localName, String qName,
|
||||
Attributes attributes) throws SAXException {
|
||||
|
||||
}
|
||||
|
||||
public void endElement(String uri, String localName, String qName) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user