?? rectangularnormaltessellator.java
字號:
if (showTileBoundary)
this.renderPatchBoundary(dc, tile, gl);
gl.glPopAttrib();
}
private void renderPatchBoundary(DrawContext dc, RectTile tile, GL gl)
{
// TODO: Currently only works if called from renderWireframe because no state is set here.
// TODO: Draw the boundary using the vertices along the boundary rather than just at the corners.
gl.glColor4d(1d, 0, 0, 1d);
Vec4[] corners = tile.sector.computeCornerPoints(dc.getGlobe(), dc.getVerticalExaggeration());
gl.glBegin(javax.media.opengl.GL.GL_QUADS);
gl.glVertex3d(corners[0].x, corners[0].y, corners[0].z);
gl.glVertex3d(corners[1].x, corners[1].y, corners[1].z);
gl.glVertex3d(corners[2].x, corners[2].y, corners[2].z);
gl.glVertex3d(corners[3].x, corners[3].y, corners[3].z);
gl.glEnd();
}
private void renderBoundingVolume(DrawContext dc, RectTile tile)
{
Extent extent = tile.getExtent();
if (extent == null)
return;
if (extent instanceof Cylinder)
((Cylinder) extent).render(dc);
}
private PickedObject[] pick(DrawContext dc, RectTile tile,
List<? extends Point> pickPoints)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (pickPoints.size() == 0)
return null;
if (tile.ri == null)
return null;
PickedObject[] pos = new PickedObject[pickPoints.size()];
this.renderTrianglesWithUniqueColors(dc, tile);
for (int i = 0; i < pickPoints.size(); i++)
{
pos[i] = this.resolvePick(dc, tile, pickPoints.get(i));
}
return pos;
}
private void pick(DrawContext dc, RectTile tile, Point pickPoint)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (tile.ri == null)
return;
renderTrianglesWithUniqueColors(dc, tile);
PickedObject po = this.resolvePick(dc, tile, pickPoint);
if (po != null)
dc.addPickedObject(po);
}
private void renderTrianglesWithUniqueColors(DrawContext dc, RectTile tile)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalStateException(message);
}
if (tile.ri.vertices == null)
return;
tile.ri.vertices.rewind();
tile.ri.indices.rewind();
javax.media.opengl.GL gl = dc.getGL();
if (null != tile.ri.referenceCenter)
dc.getView().pushReferenceCenter(dc, tile.ri.referenceCenter);
tile.minColorCode = dc.getUniquePickColor().getRGB();
int trianglesNum = tile.ri.indices.capacity() - 2;
gl.glBegin(GL.GL_TRIANGLES);
for (int i = 0; i < trianglesNum; i++)
{
java.awt.Color color = dc.getUniquePickColor();
gl.glColor3ub((byte) (color.getRed() & 0xFF), (byte) (color
.getGreen() & 0xFF), (byte) (color.getBlue() & 0xFF));
int vIndex = 3 * tile.ri.indices.get(i);
gl.glVertex3d(tile.ri.vertices.get(vIndex), tile.ri.vertices
.get(vIndex + 1), tile.ri.vertices.get(vIndex + 2));
vIndex = 3 * tile.ri.indices.get(i + 1);
gl.glVertex3d(tile.ri.vertices.get(vIndex), tile.ri.vertices
.get(vIndex + 1), tile.ri.vertices.get(vIndex + 2));
vIndex = 3 * tile.ri.indices.get(i + 2);
gl.glVertex3d(tile.ri.vertices.get(vIndex), tile.ri.vertices
.get(vIndex + 1), tile.ri.vertices.get(vIndex + 2));
}
gl.glEnd();
tile.maxColorCode = dc.getUniquePickColor().getRGB();
if (null != tile.ri.referenceCenter)
dc.getView().popReferenceCenter(dc);
}
private PickedObject resolvePick(DrawContext dc, RectTile tile,
Point pickPoint)
{
int colorCode = this.pickSupport.getTopColor(dc, pickPoint);
if (colorCode < tile.minColorCode || colorCode > tile.maxColorCode)
return null;
double EPSILON = (double) 0.00001f;
int triangleIndex = colorCode - tile.minColorCode - 1;
if (tile.ri.indices == null
|| triangleIndex >= (tile.ri.indices.capacity() - 2))
return null;
double centerX = tile.ri.referenceCenter.x;
double centerY = tile.ri.referenceCenter.y;
double centerZ = tile.ri.referenceCenter.z;
int vIndex = 3 * tile.ri.indices.get(triangleIndex);
Vec4 v0 = new Vec4((tile.ri.vertices.get(vIndex++) + centerX),
(tile.ri.vertices.get(vIndex++) + centerY), (tile.ri.vertices
.get(vIndex) + centerZ));
vIndex = 3 * tile.ri.indices.get(triangleIndex + 1);
Vec4 v1 = new Vec4((tile.ri.vertices.get(vIndex++) + centerX),
(tile.ri.vertices.get(vIndex++) + centerY), (tile.ri.vertices
.get(vIndex) + centerZ));
vIndex = 3 * tile.ri.indices.get(triangleIndex + 2);
Vec4 v2 = new Vec4((tile.ri.vertices.get(vIndex++) + centerX),
(tile.ri.vertices.get(vIndex++) + centerY), (tile.ri.vertices
.get(vIndex) + centerZ));
// get triangle edge vectors and plane normal
Vec4 e1 = v1.subtract3(v0);
Vec4 e2 = v2.subtract3(v0);
Vec4 N = e1.cross3(e2); // if N is 0, the triangle is degenerate, we are not dealing with it
Line ray = dc.getView().computeRayFromScreenPoint(pickPoint.getX(),
pickPoint.getY());
Vec4 w0 = ray.getOrigin().subtract3(v0);
double a = -N.dot3(w0);
double b = N.dot3(ray.getDirection());
if (java.lang.Math.abs(b) < EPSILON) // ray is parallel to triangle plane
return null; // if a == 0 , ray lies in triangle plane
double r = a / b;
Vec4 intersect = ray.getOrigin().add3(ray.getDirection().multiply3(r));
Position pp = dc.getGlobe().computePositionFromPoint(intersect);
// Draw the elevation from the elevation model, not the geode.
double elev = dc.getGlobe().getElevation(pp.getLatitude(),
pp.getLongitude());
Position p = new Position(pp.getLatitude(), pp.getLongitude(), elev);
return new PickedObject(pickPoint, colorCode, p, pp.getLatitude(), pp
.getLongitude(), elev, true);
}
/**
* Determines if and where a ray intersects a <code>RectTile</code> geometry.
*
* @param tile the <Code>RectTile</code> which geometry is to be tested for intersection.
* @param line the ray for which an intersection is to be found.
* @return an array of <code>Intersection</code> sorted by increasing distance from the line origin, or null if
* no intersection was found.
*/
private Intersection[] intersect(RectTile tile, Line line)
{
if (line == null)
{
String msg = Logging.getMessage("nullValue.LineIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (tile.ri.vertices == null)
return null;
// Compute 'vertical' plane perpendicular to the ground, that contains the ray
Vec4 normalV = line.getDirection().cross3(globe.computeSurfaceNormalAtPoint(line.getOrigin()));
Plane verticalPlane = new Plane(normalV.x(), normalV.y(), normalV.z(), -line.getOrigin().dot3(normalV));
if (!tile.getExtent().intersects(verticalPlane))
return null;
// Compute 'horizontal' plane perpendicular to the vertical plane, that contains the ray
Vec4 normalH = line.getDirection().cross3(normalV);
Plane horizontalPlane = new Plane(normalH.x(), normalH.y(), normalH.z(), -line.getOrigin().dot3(normalH));
if (!tile.getExtent().intersects(horizontalPlane))
return null;
Intersection[] hits;
ArrayList<Intersection> list = new ArrayList<Intersection>();
int[] indices = new int[tile.ri.indices.limit()];
double[] coords = new double[tile.ri.vertices.limit()];
tile.ri.indices.rewind();
tile.ri.vertices.rewind();
tile.ri.indices.get(indices, 0, indices.length);
tile.ri.vertices.get(coords, 0, coords.length);
tile.ri.indices.rewind();
tile.ri.vertices.rewind();
int trianglesNum = tile.ri.indices.capacity() - 2;
double centerX = tile.ri.referenceCenter.x;
double centerY = tile.ri.referenceCenter.y;
double centerZ = tile.ri.referenceCenter.z;
// Compute maximum cell size based on tile delta lat, density and globe radius
double cellSide = tile.getSector().getDeltaLatRadians() * globe.getRadius() / density;
double maxCellRadius = Math.sqrt(cellSide * cellSide * 2) / 2; // half cell diagonal
// Compute maximum elevation difference - assume cylinder as Extent
double elevationSpan = ((Cylinder)tile.getExtent()).getCylinderHeight();
// TODO: ignore back facing triangles?
// Loop through all tile cells - triangle pairs
int startIndice = (density + 2) * 2 + 6; // skip firts skirt row and a couple degenerate cells
int endIndice = trianglesNum - startIndice; // ignore last skirt row and a couple degenerate cells
int k = -1;
for (int i = startIndice; i < endIndice; i += 2)
{
// Skip skirts and degenerate triangle cells - based on indice sequence.
k = k == density - 1 ? -4 : k + 1; // density x terrain cells interleaved with 4 skirt and degenerate cells.
if (k < 0)
continue;
// Triangle pair diagonal - v1 & v2
int vIndex = 3 * indices[i + 1];
Vec4 v1 = new Vec4(
coords[vIndex++] + centerX,
coords[vIndex++] + centerY,
coords[vIndex] + centerZ);
vIndex = 3 * indices[i + 2];
Vec4 v2 = new Vec4(
coords[vIndex++] + centerX,
coords[vIndex++] + centerY,
coords[vIndex] + centerZ);
Vec4 cellCenter = Vec4.mix3(.5, v1, v2);
// Test cell center distance to vertical plane
if (Math.abs(verticalPlane.distanceTo(cellCenter)) > maxCellRadius)
continue;
// Test cell center distance to horizontal plane
if (Math.abs(horizontalPlane.distanceTo(cellCenter)) > elevationSpan)
continue;
// Prepare to test triangles - get other two vertices v0 & v3
Vec4 p;
vIndex = 3 * indices[i];
Vec4 v0 = new Vec4(
coords[vIndex++] + centerX,
coords[vIndex++] + centerY,
coords[vIndex] + centerZ);
vIndex = 3 * indices[i + 3];
Vec4 v3 = new Vec4(
coords[vIndex++] + centerX,
coords[vIndex++] + centerY,
coords[vIndex] + centerZ);
// Test triangle 1 intersection w ray
Triangle t = new Triangle(v0, v1, v2);
if ((p = t.intersect(line)) != null)
{
list.add(new Intersection(p, false));
}
// Test triangle 2 intersection w ray
t = new Triangle(v1, v2, v3);
if ((p = t.intersect(line)) != null)
{
list.add(new Intersection(p, false));
}
}
int numHits = list.size();
if (numHits == 0)
return null;
hits = new Intersection[numHits];
list.toArray(hits);
final Vec4 origin = line.getOrigin();
Arrays.sort(hits, new Comparator<Intersection>()
{
public int compare(Intersection i1, Intersection i2)
{
if (i1 == null && i2 == null)
return 0;
if (i2 == null)
return -1;
if (i1 == null)
return 1;
Vec4 v1 = i1.getIntersectionPoint();
Vec4 v2 = i2.getIntersectionPoint();
double d1 = origin.distanceTo3(v1);
double d2 = origin.distanceTo3(v2);
return Double.compare(d1, d2);
}
});
return hits;
}
/**
* Determines if and where a <code>RectTile</code> geometry intersects the globe ellipsoid at a given elevation.
* The returned array of <code>Intersection</code> describes a list of individual segments - two
* <code>Intersection</code> for each, corresponding to each geometry triangle that intersects the given elevation.
*
* @param tile the <Code>RectTile</code> which geometry is to be tested for intersection.
* @param elevation the elevation for which intersection points are to be found.
* @return an array of <code>Intersection</code> pairs or null if no intersection was found.
*/
private Intersection[] intersect(RectTile tile, double elevation)
{
if (tile.ri.vertices == null)
return null;
// Check whether the tile includes the intersection elevation - assume cylinder as Extent
Cylinder cylinder = ((Cylinder)tile.getExtent());
if (!(globe.isPointAboveElevation(cylinder.getBottomCenter(), elevation)
^ globe.isPointAboveElevation(cylinder.getTopCenter(), elevation)))
return null;
Intersection[] hits;
ArrayList<Intersection> list = new ArrayList<Intersection>();
int[] indices = new int[tile.ri.indices.limit()];
double[] coords = new double[tile.ri.vertices.limit()];
tile.ri.indices.rewind();
tile.ri.vertices.rewind();
tile.ri.indices.get(indices, 0, indices.length);
tile.ri.vertices.get(coords, 0, coords.length);
tile.ri.indices.rewind();
tile.ri.vertices.rewind();
int trianglesNum = tile.ri.indices.capacity() - 2;
double centerX = tile.ri.referenceCenter.x;
double centerY = tile.ri.referenceCenter.y;
double centerZ = tile.ri.referenceCenter.z;
// Loop through all tile cells - triangle pairs
int startIndice = (density + 2) * 2 + 6; // skip firts skirt row and a couple degenerate cells
int endIndice = trianglesNum - startIndice; // ignore last skirt row and a couple degenerate cells
int k = -1;
for (int i = startIndice; i < endIndice; i += 2)
{
// Skip skirts and degenerate triangle cells - based on indice sequence.
k = k == density - 1 ? -4 : k + 1; // density x terrain cells interleaved with 4 skirt and degenerate cells.
if (k < 0)
continue;
// Get the four cell corners
int vIndex = 3 * indices[i];
Vec4 v0 = new Vec4(
coords[vIndex++] + centerX,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -