org.oscim.utils.Tessellator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vtm-web Show documentation
Show all versions of vtm-web Show documentation
OpenGL vector map library written in Java - running on Android, iOS, Desktop and within the browser.
package org.oscim.utils;
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;
import org.oscim.core.GeometryBuffer;
import org.oscim.renderer.bucket.VertexData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tessellator {
static final Logger log = LoggerFactory.getLogger(Tessellator.class);
public static int tessellate(GeometryBuffer geom, float scale,
VertexData outPoints, VertexData 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) {
VertexData.Chunk chunk = outTris.obtainChunk();
cnt = VertexData.SIZE - chunk.used;
if (k + cnt > resIndices)
cnt = resIndices - k;
for (int i = 0; i < cnt; i++)
chunk.vertices[chunk.used + i] =
(short) (vertexOffset + io.get(k + i));
chunk.used += cnt;
outTris.releaseChunk();
}
Float32Array po = res.getPoints(res);
int resPoints = po.length();
vertexOffset += (resPoints >> 1);
for (int k = 0, cnt = 0; k < resPoints; k += cnt) {
VertexData.Chunk chunk = outPoints.obtainChunk();
cnt = VertexData.SIZE - chunk.used;
if (k + cnt > resPoints)
cnt = resPoints - k;
for (int i = 0; i < cnt; i++)
chunk.vertices[chunk.used + i] =
(short) (po.get(k + i) * scale);
chunk.used += cnt;
outPoints.releaseChunk();
}
if (idx >= indexEnd || geom.index[idx] < 0)
break;
}
return numIndices;
}
public static int tessellate(float[] points, int ppos, int plen, int[] index,
int ipos, int rings, int vertexOffset, VertexData 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) {
VertexData.Chunk chunk = outTris.obtainChunk();
cnt = VertexData.SIZE - chunk.used;
if (k + cnt > numIndices)
cnt = numIndices - k;
for (int i = 0; i < cnt; i++) {
int idx = (vertexOffset + io.get(k + i));
chunk.vertices[chunk.used + i] = (short) idx;
}
chunk.used += cnt;
outTris.releaseChunk();
}
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;
}-*/;
}
}