edu.mines.jtk.sgl.QuadGroup Maven / Gradle / Ivy
Show all versions of edu-mines-jtk Show documentation
/****************************************************************************
Copyright 2011, Colorado School of Mines and others.
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 edu.mines.jtk.sgl;
import java.nio.FloatBuffer;
import java.util.HashMap;
import edu.mines.jtk.dsp.Sampling;
import static edu.mines.jtk.ogl.Gl.*;
import edu.mines.jtk.util.Direct;
import java.awt.Color;
/**
* A group of quads that represents a surface.
*
* Quads may be specified by providing an array of packed vertex
* (x,y,z) coordinates and an array of packed (i,j,k,l) vertex indices.
* Each set (i,j,k,l) of four vertex indices corresponds to one quad.
*
* Alternatively, quads may be specified by providing only the array
* of packed vertex (x,y,z) coordinates. In this case, a vertex index is
* assigned automatically to each vertex.
*
* Normal vectors are computed for each vertex as an area-weighted
* average of the vectors normal to all quads that reference that
* vertex with the same index. These area-weighted normal vectors are
* used in lighting.
* @author Dave Hale, Colorado School of Mines
* @version 2011.12.05
*/
public class QuadGroup extends Group implements Selectable {
/**
* Constructs a quad group with specified vertex coordinates.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3. The number
* of quads is nq = nv/4 = xyz.length/12.
*
* Normal vectors may be computed for either vertices or quads.
* When computed for a vertex, a normal vector is the area-weighted
* average of the normal vectors for all quads with that vertex.
*
* If no vertices have the same (x,y,z) coordinates, then vertex and
* quad normal vectors are the same vectors, but quad normal vectors
* are less costly to compute.
* @param vn true, for vertex normals; false, for quad normals.
* @param xyz array[3*nv] of packed vertex coordinates.
*/
public QuadGroup(boolean vn, float[] xyz) {
this(vn,xyz,null);
}
/**
* Constructs a quad group with specified vertex coordinates.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3. The number
* of quads is nq = nv/4 = xyz.length/12.
*
* The (r,g,b) components of colors are packed into the specified
* array rgb. The number of colors equals the number of vertices.
*
* Normal vectors may be computed for either vertices or quads.
* When computed for a vertex, a normal vector is the area-weighted
* average of the normal vectors for all quads with that vertex.
*
* If no vertices have the same (x,y,z) coordinates, then vertex and
* quad normal vectors are the same vectors, but quad normal vectors
* are less costly to compute.
* @param vn true, for vertex normals; false, for quad normals.
* @param xyz array[3*nv] of packed vertex coordinates.
* @param rgb array[3*nv] of packed color components.
*/
public QuadGroup(boolean vn, float[] xyz, float[] rgb) {
int[] ijkl = indexVertices(!vn,xyz);
float[] uvw = computeNormals(ijkl,xyz);
buildTree(ijkl,xyz,uvw,rgb);
setDefaultStates();
}
/**
* Constructs a quad group for a sampled function z = f(x,y).
* @param vn true, for vertex normals; false, for quad normals.
* @param sx sampling of x coordinates; may be non-uniform.
* @param sy sampling of y coordinates; may be non-uniform.
* @param z array[nx][ny] of z coordinates z = f(x,y).
*/
public QuadGroup(boolean vn, Sampling sx, Sampling sy, float[][] z) {
this(vn,makeVertices(sx,sy,z));
}
/**
* Constructs a quad group for a sampled function z = f(x,y).
* @param vn true, for vertex normals; false, for quad normals.
* @param sx sampling of x coordinates; may be non-uniform.
* @param sy sampling of y coordinates; may be non-uniform.
* @param z array[nx][ny] of z coordinates z = f(x,y).
* @param r array[nx][ny] of red color components.
* @param g array[nx][ny] of green color components.
* @param b array[nx][ny] of blue color components.
*/
public QuadGroup(
boolean vn, Sampling sx, Sampling sy, float[][] z,
float[][] r, float[][] g, float[][] b)
{
this(vn,makeVertices(sx,sy,z),makeColors(r,g,b));
}
private static float[] makeVertices(Sampling sx, Sampling sy, float[][] z) {
int nx = sx.getCount()-1;
int ny = sy.getCount()-1;
float[] xyz = new float[3*6*nx*ny];
for (int ix=0,i=0; ix
* Quads are specified by sets of four vertex indices (i,j,k,l),
* one set per quad, packed into the specified array of integers
* ijkl. The number of quads is nq = ijkl.length/4.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3.
*
* For any vertex with index iv, this method computes a normal vector
* as an area-weighted average of the normal vectors for all quads
* specified with index iv.
* @param ijkl array[4*nq] of packed vertex indices.
* @param xyz array[3*nv] of packed vertex coordinates.
*/
public QuadGroup(int[] ijkl, float[] xyz) {
this(ijkl,xyz,null);
}
/**
* Constructs a quad group with specified vertex coordinates.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3.
*
* The (u,v,w) components of normal vectors are packed into the specified
* array uvw. The number of normal vectors equals the number of vertices.
* @param xyz array[3*nv] of packed vertex coordinates.
* @param uvw array[3*nv] of packed normal vector components.
*/
public QuadGroup(float[] xyz, float[] uvw) {
this(indexVertices(true,xyz),xyz,uvw,null);
}
/**
* Constructs a quad group with specified vertex coordinates.
*
* Quads are specified by sets of four vertex indices (i,j,k,l),
* one set per quad, packed into the specified array of integers
* ijkl. The number of quads is nq = ijkl.length/4.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3.
*
* The (u,v,w) components of normal vectors are packed into the specified
* array uvw. The number of normal vectors equals the number of vertices.
* @param ijkl array[4*nq] of packed vertex indices.
* @param xyz array[3*nv] of packed vertex coordinates.
* @param uvw array[3*nv] of packed normal vector components.
*/
public QuadGroup(int[] ijkl, float[] xyz, float[] uvw) {
this(ijkl,xyz,uvw,null);
}
/**
* Constructs a quad group with specified vertex coordinates
* and optional corresponding normal vectors and colors.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3.
*
* The (u,v,w) components of normal vectors are packed into the specified
* array uvw. The number of normal vectors equals the number of vertices.
*
* The (r,g,b) components of colors are packed into the specified array
* rgb. The number of colors equals the number of vertices.
* @param xyz array[3*nv] of packed vertex coordinates.
* @param uvw array[3*nv] of packed normal vector components.
* @param rgb array[3*nv] of packed color components.
*/
public QuadGroup(float[] xyz, float[] uvw, float[] rgb) {
this(indexVertices(true,xyz),xyz,uvw,rgb);
}
/**
* Constructs a quad group with specified vertex coordinates
* and optional corresponding normal vectors and colors.
*
* Quads are specified by sets of four vertex indices (i,j,k),
* one set per quad, packed into the specified array of integers
* ijkl. The number of quads is nq = ijkl.length/4.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3.
*
* The (u,v,w) components of normal vectors are packed into the specified
* array uvw. If not null, the number of normal vectors equals the number
* of vertices.
*
* The (r,g,b) components of colors are packed into the specified array
* rgb. If not null, the number of colors equals the number of vertices.
* @param ijkl array[4*nq] of packed vertex indices.
* @param xyz array[3*nv] of packed vertex coordinates.
* @param uvw array[3*nv] of packed normal vector components.
* @param rgb array[3*nv] of packed color components.
*/
public QuadGroup(int[] ijkl, float[] xyz, float[] uvw, float[] rgb) {
if (uvw==null)
uvw = computeNormals(ijkl,xyz);
buildTree(ijkl,xyz,uvw,rgb);
setDefaultStates();
}
/**
* Computes indices ijkl for quad vertex coordinates xyz.
*
* The (x,y,z) coordinates of vertices are packed into the specified
* array xyz. The number of vertices is nv = xyz.length/3. The number
* of quads is nq = nv/4 = xyz.length/12.
*
* For each quad, this method computes a set (i,j,k,l) of integer
* vertex indices. A vertex index is an integer in the range [0,nv-1].
* The (x,y,z) coordinates of a vertex with index iv are xyz[3*iv+0],
* xyz[3*iv+1] and xyz[3*iv+2], respectively.
*
* The simplest indexing is the sequence {0, 1, 2, ..., nv-1}. In this
* case, indices are assigned sequentially, so that every vertex of
* every quad has a different index.
*
* In non-sequential indexing, vertices with the same (x,y,z) coordinates
* are assigned the same index. Again, index vertices will be in the range
* [0,nv-1], but some integers in this range may not be used. Whereas
* sequential indexing would assign integers ia and ib to two vertices
* that have the same (x,y,z) coordinates, non-sequential indexing will
* assign the smaller index min(ia,ib) to both vertices; the larger index
* max(ia,ib) will be unused.
*
* Sets of four indices (i,j,k,l), one set per quad, are packed
* into the returned array of integers ijkl, which has length 4*nq.
* @param sequential true, for sequential indexing; false, otherwise.
* @param xyz array[3*nv] of packed vertex coordinates.
* @return an array[4*nq] of packed vertex indices.
*/
public static int[] indexVertices(boolean sequential, float[] xyz) {
// Number of vertices and quads.
int nv = xyz.length/3;
int nq = nv/4;
// Array of vertex indices, one per vertex.
int[] ijkl = new int[nv];
// For sequential indexing, simply fill the array. For non-sequential
// indexing, map each unique vertex to a unique vertex index.
if (sequential) {
for (int iv=0; iv vimap = new HashMap(nv);
for (int iq=0; iq© 2015 - 2025 Weber Informatics LLC | Privacy Policy