vtm/src/org/oscim/core/GeometryBuffer.java

189 lines
3.7 KiB
Java

package org.oscim.core;
public class GeometryBuffer {
public enum GeometryType {
NONE(0),
POINT(1),
LINE(2),
POLY(3),
TRIS(4);
private GeometryType(int type) {
nativeInt = type;
}
public final int nativeInt;
}
// TODO
// - check indexPos < Short.Max
// - make internals private
final static boolean CHECK_STATE = true;
public float[] points;
public short[] index;
public int indexPos;
public int pointPos;
public GeometryType type;
public GeometryBuffer(float[] points, short[] index) {
if (points == null)
throw new IllegalArgumentException("GeometryBuffer points is null");
if (index == null)
throw new IllegalArgumentException("GeometryBuffer index is null");
this.points = points;
this.index = index;
this.type = GeometryType.NONE;
this.indexPos = 0;
this.pointPos = 0;
}
public GeometryBuffer(int numPoints, int numIndices) {
this.points = new float[numPoints * 2];
this.index = new short[numIndices];
this.type = GeometryType.NONE;
this.indexPos = 0;
this.pointPos = 0;
}
// ---- API ----
public void clear() {
index[0] = -1;
indexPos = 0;
pointPos = 0;
type = GeometryType.NONE;
}
public void addPoint(float x, float y) {
if (pointPos >= points.length - 1)
ensurePointSize((pointPos >> 1) + 1, true);
points[pointPos++] = x;
points[pointPos++] = y;
index[indexPos] += 2;
}
public boolean isPoly(){
return type == GeometryType.POLY;
}
public boolean isLine(){
return type == GeometryType.LINE;
}
public boolean isPoint(){
return type == GeometryType.POINT;
}
public void setPoint(int pos, float x, float y) {
points[(pos << 1) + 0] = x;
points[(pos << 1) + 1] = y;
}
public void startPoints() {
if (CHECK_STATE)
setOrCheckMode(GeometryType.POINT);
}
public void startLine() {
if (CHECK_STATE)
setOrCheckMode(GeometryType.LINE);
// start next
if ((index[0] >= 0) && (++indexPos >= index.length))
ensureIndexSize(indexPos, true);
// initialize with zero points
index[indexPos] = 0;
// set new end marker
if (index.length > indexPos + 1)
index[indexPos + 1] = -1;
}
public void startPolygon() {
boolean start = (type == GeometryType.NONE);
if (CHECK_STATE)
setOrCheckMode(GeometryType.POLY);
if ((indexPos + 3) > index.length)
ensureIndexSize(indexPos + 2, true);
if (!start) {
// end polygon
index[++indexPos] = 0;
// next polygon start
indexPos++;
}
// initialize with zero points
index[indexPos] = 0;
// set new end marker
if (index.length > indexPos + 1)
index[indexPos + 1] = -1;
}
public void startHole() {
if (CHECK_STATE)
checkMode(GeometryType.POLY);
if ((indexPos + 2) > index.length)
ensureIndexSize(indexPos + 1, true);
// initialize with zero points
index[++indexPos] = 0;
// set new end marker
if (index.length > indexPos + 1)
index[indexPos + 1] = -1;
}
// ---- internals ----
public float[] ensurePointSize(int size, boolean copy) {
if (size * 2 < points.length)
return points;
float[] tmp = new float[size * 2 + 512];
if (copy)
System.arraycopy(points, 0, tmp, 0, points.length);
points = tmp;
return points;
}
public short[] ensureIndexSize(int size, boolean copy) {
if (size < index.length)
return index;
short[] tmp = new short[size + 64];
if (copy)
System.arraycopy(index, 0, tmp, 0, index.length);
index = tmp;
return index;
}
private void setOrCheckMode(GeometryType m) {
if (type == m)
return;
if (type != GeometryType.NONE)
throw new IllegalArgumentException("GeometryBuffer not cleared " + m + "<>" + type);
type = m;
}
private void checkMode(GeometryType m) {
if (type != m)
throw new IllegalArgumentException("GeometryBuffer not cleared " + m + "<>" + type);
}
}