added Scatter VBO, with List<Coord3d> data loader

This commit is contained in:
Martin Pernollet 2015-04-05 18:45:18 +02:00
parent b476382b9d
commit 5eec39a1b4
5 changed files with 409 additions and 169 deletions

View File

@ -1,6 +1,8 @@
package org.jzy3d.maths; package org.jzy3d.maths;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/** /**
* A {@link Coord3d} stores a 3 dimensional coordinate for cartesian or polar * A {@link Coord3d} stores a 3 dimensional coordinate for cartesian or polar
@ -14,6 +16,23 @@ import java.io.Serializable;
* *
*/ */
public class Coord3d implements Serializable{ public class Coord3d implements Serializable{
public static List<Coord3d> list(int size){
return new ArrayList<Coord3d>(size);
}
public static Range getZRange(List<Coord3d> coords) {
float min = Float.POSITIVE_INFINITY;
float max = Float.NEGATIVE_INFINITY;
for(Coord3d c: coords){
if(c.z>max)
max = c.z;
if(c.z<min)
min = c.z;
}
return new Range(min, max);
}
/** The origin is a Coord3d having value 0 for each dimension. */ /** The origin is a Coord3d having value 0 for each dimension. */
public static final Coord3d ORIGIN = new Coord3d(0.0f, 0.0f, 0.0f); public static final Coord3d ORIGIN = new Coord3d(0.0f, 0.0f, 0.0f);

View File

@ -13,215 +13,285 @@ import org.apache.log4j.Logger;
import org.jzy3d.colors.Color; import org.jzy3d.colors.Color;
import org.jzy3d.io.IGLLoader; import org.jzy3d.io.IGLLoader;
import org.jzy3d.maths.BoundingBox3d; import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.plot3d.primitives.AbstractDrawable; import org.jzy3d.plot3d.primitives.AbstractDrawable;
import org.jzy3d.plot3d.primitives.IGLBindedResource; import org.jzy3d.plot3d.primitives.IGLBindedResource;
import org.jzy3d.plot3d.rendering.compat.GLES2CompatUtils; import org.jzy3d.plot3d.rendering.compat.GLES2CompatUtils;
import org.jzy3d.plot3d.rendering.view.Camera; import org.jzy3d.plot3d.rendering.view.Camera;
import org.jzy3d.plot3d.transform.Rotate;
import org.jzy3d.plot3d.transform.Rotator;
import org.jzy3d.plot3d.transform.Transform; import org.jzy3d.plot3d.transform.Transform;
import com.jogamp.common.nio.Buffers; import com.jogamp.common.nio.Buffers;
/** /**
* A {@link DrawableVBO} is able to efficiently draw a large collection of geometries. * A {@link DrawableVBO} is able to efficiently draw a large collection of
* geometries.
*
* The user must provide a loader that will be later called when the GL context
* requires loading the VBO data in GPU memory.
*
* The loader might freely make settings on the drawable as it is called with a
* reference to the {@link DrawableVBO} is will be loading data into.
*
* One can separate data and appearance by setting geometry settings out of
* loading process.
*
* DrawableVBO shape1 = new DrawableVBO(new MemoryVBOLoader(getScatter(size)));
* shape1.setGeometry(GL.GL_POINTS); shape1.setColor(Color.WHITE);
* *
* @author Martin Pernollet * @author Martin Pernollet
*/ */
public class DrawableVBO extends AbstractDrawable implements IGLBindedResource { public class DrawableVBO extends AbstractDrawable implements IGLBindedResource {
public DrawableVBO(IGLLoader<DrawableVBO> loader) { protected int geometry = GL.GL_TRIANGLES;
this.loader = loader;
}
@Override protected int colorChannelNumber = 3;
public DrawableVBO(IGLLoader<DrawableVBO> loader) {
this.loader = loader;
}
@Override
public boolean hasMountedOnce() { public boolean hasMountedOnce() {
return hasMountedOnce; return hasMountedOnce;
} }
// element array buffer is an index: // element array buffer is an index:
// @see // @see
// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/ // http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/
@Override @Override
public void draw(GL gl, GLU glu, Camera cam) { public void draw(GL gl, GLU glu, Camera cam) {
if (hasMountedOnce) { if (hasMountedOnce) {
doTransform(gl, glu, cam); doTransform(gl, glu, cam);
configure(gl); configure(gl);
doDrawElements(gl); doDrawElements(gl);
doDrawBounds(gl, glu, cam); doDrawBounds(gl, glu, cam);
} }
} }
/**
* rotate around Z axis
*/
public Rotator rotator(boolean start) {
final Rotate r = new Rotate(25, new Coord3d(0, 0, 1));
Transform t = new Transform();
t.add(r);
setTransformBefore(t);
Rotator rotator = new Rotator(10, r);
if(start)
rotator.start();
return rotator;
}
/*
* An OBJ file appears to be really really slow to render without a
* FRONT_AND_BACK spec, probably because such a big polygon set has huge
* cost to have culling status computed (culling enabled by depth peeling).
*/
protected void configure(GL gl) {
// gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_FILL);
// gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_LINE);
// gl.glColor4f(1f,0f,1f,0.6f);
// gl.glLineWidth(0.00001f);
if (gl.isGL2()) {
gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
} else {
GLES2CompatUtils.glPolygonMode(GL.GL_FRONT_AND_BACK,
GL2GL3.GL_FILL);
}
call(gl, color);
}
protected void doDrawElements(GL gl) { /*
if (gl.isGL2()) { * An OBJ file appears to be really really slow to render without a
gl.getGL2().glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]); * FRONT_AND_BACK spec, probably because such a big polygon set has huge
gl.getGL2().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]); * cost to have culling status computed (culling enabled by depth peeling).
*/
protected void configure(GL gl) {
// gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_FILL);
// gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_LINE);
// gl.glColor4f(1f,0f,1f,0.6f);
// gl.glLineWidth(0.00001f);
if (gl.isGL2()) {
gl.getGL2().glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
} else {
GLES2CompatUtils.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_FILL);
}
call(gl, color);
}
gl.getGL2().glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer); boolean hasColorBuffer = false;
gl.getGL2().glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset);
gl.getGL2().glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.getGL2().glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
gl.getGL2().glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer);
public boolean isHasColorBuffer() {
return hasColorBuffer;
}
gl.getGL2().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]); public void setHasColorBuffer(boolean hasColorBuffer) {
gl.getGL2().glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]); this.hasColorBuffer = hasColorBuffer;
gl.getGL2().glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY); }
gl.getGL2().glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
} else {
GLES2CompatUtils.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
GLES2CompatUtils.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
GLES2CompatUtils.glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer); protected void doDrawElements(GL gl) {
GLES2CompatUtils.glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset); if (gl.isGL2()) {
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY); doBindGL2(gl);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
GLES2CompatUtils.glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer); gl.getGL2().glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer);
gl.getGL2().glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset);
GLES2CompatUtils.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]); if (hasColorBuffer) {
GLES2CompatUtils.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]); // int bo = 6 * Buffers.SIZEOF_FLOAT;
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY); int p = 3 * Buffers.SIZEOF_FLOAT;
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY); gl.getGL2().glEnableClientState(GL2.GL_COLOR_ARRAY);
} gl.getGL2().glColorPointer(colorChannelNumber, GL.GL_FLOAT, byteOffset, p);
} }
protected int getGeometry() { // enable
return GL.GL_TRIANGLES; gl.getGL2().glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
} gl.getGL2().glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
@Override // draw
gl.getGL2().glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer);
doBindGL2(gl);
// disable
gl.getGL2().glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.getGL2().glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
if (hasColorBuffer) {
gl.getGL2().glDisableClientState(GL2.GL_COLOR_ARRAY);
}
} else {
GLES2CompatUtils.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
GLES2CompatUtils.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
GLES2CompatUtils.glVertexPointer(dimensions, GL.GL_FLOAT, byteOffset, pointer);
GLES2CompatUtils.glNormalPointer(GL.GL_FLOAT, byteOffset, normalOffset);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
GLES2CompatUtils.glDrawElements(getGeometry(), size, GL.GL_UNSIGNED_INT, pointer);
GLES2CompatUtils.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
GLES2CompatUtils.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
GLES2CompatUtils.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
}
}
private void doBindGL2(GL gl) {
gl.getGL2().glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
gl.getGL2().glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
}
public int getGeometry() {
return geometry;
}
/**
* Set geometry, use: GL.GL_TRIANGLES (default) ...
*
* @param geometry
*/
public void setGeometry(int geometry) {
this.geometry = geometry;
}
@Override
public void applyGeometryTransform(Transform transform) { public void applyGeometryTransform(Transform transform) {
/* /*
* Coord3d c = transform.compute(new Coord3d(x,y, z)); x = c.x; y = c.y; * Coord3d c = transform.compute(new Coord3d(x,y, z)); x = c.x; y = c.y;
* z = c.z; * z = c.z;
*/ */
Logger.getLogger(DrawableVBO.class).warn("not implemented"); Logger.getLogger(DrawableVBO.class).warn("not implemented");
} }
@Override @Override
public void updateBounds() { // requires smart reload public void updateBounds() { // requires smart reload
Logger.getLogger(DrawableVBO.class).warn("not implemented"); Logger.getLogger(DrawableVBO.class).warn("not implemented");
/* /*
* bbox.reset(); bbox.add(x+Math.max(radiusBottom, radiusTop), * bbox.reset(); bbox.add(x+Math.max(radiusBottom, radiusTop),
* y+Math.max(radiusBottom, radiusTop), z); * y+Math.max(radiusBottom, radiusTop), z);
* bbox.add(x-Math.max(radiusBottom, radiusTop), * bbox.add(x-Math.max(radiusBottom, radiusTop),
* y-Math.max(radiusBottom, radiusTop), z); * y-Math.max(radiusBottom, radiusTop), z);
* bbox.add(x+Math.max(radiusBottom, radiusTop), * bbox.add(x+Math.max(radiusBottom, radiusTop),
* y+Math.max(radiusBottom, radiusTop), z+height); * y+Math.max(radiusBottom, radiusTop), z+height);
* bbox.add(x-Math.max(radiusBottom, radiusTop), * bbox.add(x-Math.max(radiusBottom, radiusTop),
* y-Math.max(radiusBottom, radiusTop), z+height); * y-Math.max(radiusBottom, radiusTop), z+height);
*/ */
} }
/* IO */ /* IO */
@Override @Override
public void mount(GL gl) { public void mount(GL gl) {
try { try {
loader.load(gl, this); loader.load(gl, this);
hasMountedOnce = true; hasMountedOnce = true;
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(DrawableVBO.class).error(e, e); Logger.getLogger(DrawableVBO.class).error(e, e);
} }
} }
public void setData(GL gl, IntBuffer indices, FloatBuffer vertices, public void setData(GL gl, IntBuffer indices, FloatBuffer vertices, BoundingBox3d bounds) {
BoundingBox3d bounds) { setData(gl.getGL2(), indices, vertices, bounds, 0);
setData(gl.getGL2(), indices, vertices, bounds, 0); }
}
public void setData(GL2 gl, IntBuffer indices, FloatBuffer vertices, public void setData(GL2 gl, IntBuffer indices, FloatBuffer vertices, BoundingBox3d bounds, int pointer) {
BoundingBox3d bounds, int pointer) { doConfigure(pointer, indices.capacity());
doConfigure(pointer, indices.capacity()); doLoadArrayBuffer(gl, vertices);
doLoadArrayBuffer(gl, vertices); doLoadElementBuffer(gl, indices);
doLoadElementBuffer(gl, indices); doSetBoundingBox(bounds);
doSetBoundingBox(bounds); }
}
public void doConfigure(int pointer, int size) { public void doConfigure(int pointer, int size) {
int dimensions = 3; int dimensions = 3;
int byteOffset = (dimensions * 2) * Buffers.SIZEOF_FLOAT; // (coord+normal) int byteOffset = (dimensions * 2) * Buffers.SIZEOF_FLOAT; // (coord+normal)
int normalOffset = dimensions * Buffers.SIZEOF_FLOAT; int normalOffset = dimensions * Buffers.SIZEOF_FLOAT;
doConfigure(pointer, size, byteOffset, normalOffset, dimensions); doConfigure(pointer, size, byteOffset, normalOffset, dimensions);
} }
public void doConfigure(int pointer, int size, int byteOffset, public void doConfigure(int pointer, int size, int byteOffset, int normalOffset, int dimensions) {
int normalOffset, int dimensions) { this.byteOffset = byteOffset;
this.byteOffset = byteOffset; this.normalOffset = normalOffset;
this.normalOffset = normalOffset; this.dimensions = dimensions;
this.dimensions = dimensions; this.size = size;
this.size = size; this.pointer = pointer;
this.pointer = pointer; }
}
public void doLoadArrayBuffer(GL gl, FloatBuffer vertices) { public void doLoadArrayBuffer(GL gl, FloatBuffer vertices) {
doLoadArrayBuffer(gl, vertices.capacity() * Buffers.SIZEOF_FLOAT, doLoadArrayBuffer(gl, vertices.capacity() * Buffers.SIZEOF_FLOAT, vertices);
vertices); }
}
public void doLoadArrayBuffer(GL gl, int vertexSize, FloatBuffer vertices) { public void doLoadArrayBuffer(GL gl, int vertexSize, FloatBuffer vertices) {
gl.glGenBuffers(1, arrayName, 0); gl.glGenBuffers(1, arrayName, 0);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, arrayName[0]);
gl.glBufferData(GL.GL_ARRAY_BUFFER, vertexSize, vertices, gl.glBufferData(GL.GL_ARRAY_BUFFER, vertexSize, vertices, GL.GL_STATIC_DRAW);
GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, pointer);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, pointer); }
}
public void doLoadElementBuffer(GL gl, IntBuffer indices) { public void doLoadElementBuffer(GL gl, IntBuffer indices) {
doLoadElementBuffer(gl, indices.capacity() * Buffers.SIZEOF_INT, doLoadElementBuffer(gl, indices.capacity() * Buffers.SIZEOF_INT, indices);
indices); }
}
public void doLoadElementBuffer(GL gl, int indexSize, IntBuffer indices) { public void doLoadElementBuffer(GL gl, int indexSize, IntBuffer indices) {
gl.glGenBuffers(1, elementName, 0); gl.glGenBuffers(1, elementName, 0);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]); gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, elementName[0]);
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexSize, indices, gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexSize, indices, GL.GL_STATIC_DRAW);
GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, pointer);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, pointer); }
}
public void doSetBoundingBox(BoundingBox3d bounds) { public void doSetBoundingBox(BoundingBox3d bounds) {
bbox = bounds; bbox = bounds;
} }
/* */ /* */
public Color getColor() { public Color getColor() {
return color; return color;
} }
public void setColor(Color color) { public void setColor(Color color) {
this.color = color; this.color = color;
} }
protected IGLLoader<DrawableVBO> loader; protected IGLLoader<DrawableVBO> loader;
protected int byteOffset; protected int byteOffset;
protected int normalOffset; protected int normalOffset;
protected int dimensions; protected int dimensions;
protected int size; protected int size;
protected int pointer; protected int pointer;
protected int arrayName[] = new int[1]; protected int arrayName[] = new int[1];
protected int elementName[] = new int[1]; protected int elementName[] = new int[1];
protected boolean hasMountedOnce = false; protected boolean hasMountedOnce = false;
protected Color color = new Color(1f, 0f, 1f, 0.75f); protected Color color = new Color(1f, 0f, 1f, 0.75f);
} }

View File

@ -0,0 +1,131 @@
package org.jzy3d.plot3d.primitives.vbo;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Collection;
import java.util.List;
import javax.media.opengl.GL;
import org.apache.log4j.Logger;
import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.io.IGLLoader;
import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.plot3d.primitives.vbo.DrawableVBO;
/**
* A simple loader loading an existing collection of coordinates into a Vertex
* Buffer Objects once GL initialization stage requires it to be loaded.
*
* If a colormapper is given, color buffer will be filled according to coloring policy.
*
* @author martin
*/
public class ListCoord3dVBOLoader implements IGLLoader<DrawableVBO> {
protected List<Coord3d> coordinates = null;
protected ColorMapper coloring = null;
public ListCoord3dVBOLoader(List<Coord3d> coordinates) {
this.coordinates = coordinates;
}
public ListCoord3dVBOLoader(List<Coord3d> coordinates, ColorMapper coloring) {
this.coordinates = coordinates;
this.coloring = coloring;
}
// @Override
// @SuppressWarnings("unchecked")
public void load(GL gl, DrawableVBO drawable) throws Exception {
// configure
boolean hasNormal = false;
int n = coordinates.size();
int dimension = 3; // x, y, z
int geometrySize = computeGeometrySize(drawable);
int verticeBufferSize = computeVerticeBufferSize(n, dimension, geometrySize, hasNormal, coloring!=null);
int indexBufferSize = n * geometrySize;
// build and load buffers
FloatBuffer vertices = FloatBuffer.allocate(verticeBufferSize);
IntBuffer indices = IntBuffer.allocate(indexBufferSize);
BoundingBox3d bounds = new BoundingBox3d();
fillBuffersWithCollection(drawable, vertices, indices, bounds);
// Store in GPU
drawable.setData(gl, indices, vertices, bounds);
Logger.getLogger(ListCoord3dVBOLoader.class).info("done loading " + n + " coords");
}
protected void fillBuffersWithCollection(DrawableVBO drawable, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds) {
fillBuffersWithCollection(drawable, coordinates, coloring, vertices, indices, bounds);
}
protected void fillBuffersWithCollection(DrawableVBO drawable, Collection<Coord3d> coordinates, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds) {
fillBuffersWithCollection(drawable, coordinates, null, vertices, indices, bounds);
}
protected void fillBuffersWithCollection(DrawableVBO drawable, Collection<Coord3d> coordinates, ColorMapper colors, FloatBuffer vertices, IntBuffer indices, BoundingBox3d bounds) {
drawable.setHasColorBuffer(colors!=null);
int size = 0;
for (Coord3d c : coordinates) {
indices.put(size++);
putCoord(vertices, c);
bounds.add(c);
if(colors!=null){
putColor(vertices, colors.getColor(c));
}
}
vertices.rewind();
indices.rewind();
}
protected void putCoord(FloatBuffer vertices, Coord3d c) {
vertices.put(c.x);
vertices.put(c.y);
vertices.put(c.z);
}
protected void putColor(FloatBuffer vertices, Color color) {
vertices.put(color.r);
vertices.put(color.g);
vertices.put(color.b);
}
protected int computeVerticeBufferSize(int n, int dimension, int geometrysize, boolean hasNormal, boolean hasColor) {
int verticeBufferSize = 0;
if(hasColor){
verticeBufferSize = n * (dimension * 2) * geometrysize;// *2 normals
}
if (hasNormal) {
verticeBufferSize = n * (dimension * 2) * geometrysize;// *2 normals
} else {
verticeBufferSize = n * dimension * geometrysize;
}
if(hasColor){
verticeBufferSize = n * (dimension * 2) * geometrysize;// *2 color
}
return verticeBufferSize;
}
protected int computeGeometrySize(DrawableVBO drawable) {
int geomsize = 0; // triangle
if (drawable.getGeometry() == GL.GL_POINTS) {
geomsize = 1;
} else if (drawable.getGeometry() == GL.GL_TRIANGLES) {
geomsize = 3;
}
return geomsize;
}
}

View File

@ -0,0 +1,13 @@
package org.jzy3d.plot3d.primitives.vbo;
import javax.media.opengl.GL;
import org.jzy3d.io.IGLLoader;
public class ScatterVBO extends DrawableVBO{
public ScatterVBO(IGLLoader<DrawableVBO> loader) {
super(loader);
geometry = GL.GL_POINTS;
}
}

View File

@ -597,14 +597,21 @@ public class View {
else if (boundmode == ViewBoundMode.MANUAL) else if (boundmode == ViewBoundMode.MANUAL)
bounds = viewbounds; bounds = viewbounds;
else { else {
throw new RuntimeException("Unknown bounds"); throw new RuntimeException("Unknown bounds mode");
} }
// Compute factors // Compute factors
float xLen = spaceTransformer.getX().compute(bounds.getXmax()) - spaceTransformer.getX().compute(bounds.getXmin()); float xLen = 1;
float yLen = spaceTransformer.getY().compute(bounds.getYmax()) - spaceTransformer.getY().compute(bounds.getYmin()); float yLen = 1;
float zLen = spaceTransformer.getZ().compute(bounds.getZmax()) - spaceTransformer.getZ().compute(bounds.getZmin()); float zLen = 1;
float lmax = (float) Math.max(Math.max(xLen, yLen), zLen); float lmax = 1;
if(bounds!=null){
xLen = spaceTransformer.getX().compute(bounds.getXmax()) - spaceTransformer.getX().compute(bounds.getXmin());
yLen = spaceTransformer.getY().compute(bounds.getYmax()) - spaceTransformer.getY().compute(bounds.getYmin());
zLen = spaceTransformer.getZ().compute(bounds.getZmax()) - spaceTransformer.getZ().compute(bounds.getZmin());
lmax = (float) Math.max(Math.max(xLen, yLen), zLen);
}
if (Float.isInfinite(xLen) || Float.isNaN(xLen) || xLen == 0) if (Float.isInfinite(xLen) || Float.isNaN(xLen) || xLen == 0)
xLen = 1; xLen = 1;