?? rectangularnormaltessellator.java
字號:
coords[vIndex++] + centerY,
coords[vIndex] + centerZ);
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);
vIndex = 3 * indices[i + 3];
Vec4 v3 = new Vec4(
coords[vIndex++] + centerX,
coords[vIndex++] + centerY,
coords[vIndex] + centerZ);
Intersection[] inter;
// Test triangle 1 intersection
if ((inter = globe.intersect(new Triangle(v0, v1, v2), elevation)) != null)
{
list.add(inter[0]);
list.add(inter[1]);
}
// Test triangle 2 intersection
if ((inter = globe.intersect(new Triangle(v1, v2, v3), elevation)) != null)
{
list.add(inter[0]);
list.add(inter[1]);
}
}
int numHits = list.size();
if (numHits == 0)
return null;
hits = new Intersection[numHits];
list.toArray(hits);
return hits;
}
private Vec4 getSurfacePoint(RectTile tile, Angle latitude,
Angle longitude, double metersOffset)
{
Vec4 result = this.getSurfacePoint(tile, latitude, longitude);
if (metersOffset != 0 && result != null)
result = applyOffset(this.globe, result, metersOffset);
return result;
}
/**
* Offsets <code>point</code> by <code>metersOffset</code> meters.
*
* @param globe
* the <code>Globe</code> from which to offset
* @param point
* the <code>Vec4</code> to offset
* @param metersOffset
* the magnitude of the offset
* @return <code>point</code> offset along its surface normal as if it were
* on <code>globe</code>
*/
private static Vec4 applyOffset(Globe globe, Vec4 point, double metersOffset)
{
Vec4 normal = globe.computeSurfaceNormalAtPoint(point);
point = Vec4.fromLine3(point, metersOffset, normal);
return point;
}
private Vec4 getSurfacePoint(RectTile tile, Angle latitude, Angle longitude)
{
if (latitude == null || longitude == null)
{
String msg = Logging.getMessage("nullValue.LatLonIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (!tile.sector.contains(latitude, longitude))
{
// not on this geometry
return null;
}
if (tile.ri == null)
return null;
double lat = latitude.getDegrees();
double lon = longitude.getDegrees();
double bottom = tile.sector.getMinLatitude().getDegrees();
double top = tile.sector.getMaxLatitude().getDegrees();
double left = tile.sector.getMinLongitude().getDegrees();
double right = tile.sector.getMaxLongitude().getDegrees();
double leftDecimal = (lon - left) / (right - left);
double bottomDecimal = (lat - bottom) / (top - bottom);
int row = (int) (bottomDecimal * (tile.density));
int column = (int) (leftDecimal * (tile.density));
double l = createPosition(column, leftDecimal, tile.ri.density);
double h = createPosition(row, bottomDecimal, tile.ri.density);
Vec4 result = interpolate(row, column, l, h, tile.ri);
result = result.add3(tile.ri.referenceCenter);
return result;
}
/**
* Computes from a column (or row) number, and a given offset ranged [0,1]
* corresponding to the distance along the edge of this sector, where
* between this column and the next column the corresponding position will
* fall, in the range [0,1].
*
* @param start
* the number of the column or row to the left, below or on this
* position
* @param decimal
* the distance from the left or bottom of the current sector
* that this position falls
* @param density
* the number of intervals along the sector's side
* @return a decimal ranged [0,1] representing the position between two
* columns or rows, rather than between two edges of the sector
*/
private static double createPosition(int start, double decimal, int density)
{
double l = ((double) start) / (double) density;
double r = ((double) (start + 1)) / (double) density;
return (decimal - l) / (r - l);
}
/**
* Calculates a <code>Point</code> that sits at <code>xDec</code> offset
* from <code>column</code> to <code>column +
* 1</code> and at <code>yDec</code> offset from <code>row</code> to
* <code>row + 1</code>. Accounts for the diagonals.
*
* @param row
* represents the row which corresponds to a <code>yDec</code>
* value of 0
* @param column
* represents the column which corresponds to an
* <code>xDec</code> value of 0
* @param xDec
* constrained to [0,1]
* @param yDec
* constrained to [0,1]
* @param ri
* the render info holding the vertices, etc.
* @return a <code>Point</code> geometrically within or on the boundary of
* the quadrilateral whose bottom left corner is indexed by (
* <code>row</code>, <code>column</code>)
*/
private static Vec4 interpolate(int row, int column, double xDec,
double yDec, RenderInfo ri)
{
row++;
column++;
int numVerticesPerEdge = ri.density + 3;
int bottomLeft = row * numVerticesPerEdge + column;
bottomLeft *= 3;
int numVertsTimesThree = numVerticesPerEdge * 3;
Vec4 bL = new Vec4(ri.vertices.get(bottomLeft), ri.vertices
.get(bottomLeft + 1), ri.vertices.get(bottomLeft + 2));
Vec4 bR = new Vec4(ri.vertices.get(bottomLeft + 3), ri.vertices
.get(bottomLeft + 4), ri.vertices.get(bottomLeft + 5));
bottomLeft += numVertsTimesThree;
Vec4 tL = new Vec4(ri.vertices.get(bottomLeft), ri.vertices
.get(bottomLeft + 1), ri.vertices.get(bottomLeft + 2));
Vec4 tR = new Vec4(ri.vertices.get(bottomLeft + 3), ri.vertices
.get(bottomLeft + 4), ri.vertices.get(bottomLeft + 5));
return interpolate(bL, bR, tR, tL, xDec, yDec);
}
/**
* Calculates the point at (xDec, yDec) in the two triangles defined by {bL,
* bR, tL} and {bR, tR, tL}. If thought of as a quadrilateral, the diagonal
* runs from tL to bR. Of course, this isn't a quad, it's two triangles.
*
* @param bL
* the bottom left corner
* @param bR
* the bottom right corner
* @param tR
* the top right corner
* @param tL
* the top left corner
* @param xDec
* how far along, [0,1] 0 = left edge, 1 = right edge
* @param yDec
* how far along, [0,1] 0 = bottom edge, 1 = top edge
* @return the point xDec, yDec in the co-ordinate system defined by bL, bR,
* tR, tL
*/
private static Vec4 interpolate(Vec4 bL, Vec4 bR, Vec4 tR, Vec4 tL,
double xDec, double yDec)
{
double pos = xDec + yDec;
if (pos == 1)
{
// on the diagonal - what's more, we don't need to do any "oneMinusT" calculation
return new Vec4(tL.x * yDec + bR.x * xDec, tL.y * yDec + bR.y
* xDec, tL.z * yDec + bR.z * xDec);
}
else if (pos > 1)
{
// in the "top right" half
// vectors pointing from top right towards the point we want (can be thought of as "negative" vectors)
Vec4 horizontalVector = (tL.subtract3(tR)).multiply3(1 - xDec);
Vec4 verticalVector = (bR.subtract3(tR)).multiply3(1 - yDec);
return tR.add3(horizontalVector).add3(verticalVector);
}
else
{
// pos < 1 - in the "bottom left" half
// vectors pointing from the bottom left towards the point we want
Vec4 horizontalVector = (bR.subtract3(bL)).multiply3(xDec);
Vec4 verticalVector = (tL.subtract3(bL)).multiply3(yDec);
return bL.add3(horizontalVector).add3(verticalVector);
}
}
private static double[] baryCentricCoordsRequireInside(Vec4 pnt, Vec4[] V)
{
// if pnt is in the interior of the triangle determined by V, return its
// barycentric coordinates with respect to V. Otherwise return null.
// b0:
final double tol = 1.0e-4;
double[] b0b1b2 = new double[3];
double triangleHeight =
distanceFromLine(V[0],V[1],V[2].subtract3(V[1]));
double heightFromPoint =
distanceFromLine(pnt,V[1],V[2].subtract3(V[1]));
b0b1b2[0] = heightFromPoint/triangleHeight;
if (Math.abs(b0b1b2[0]) < tol) b0b1b2[0] = 0.0;
else if (Math.abs(1.0-b0b1b2[0]) < tol) b0b1b2[0] = 1.0;
if (b0b1b2[0] < 0.0 || b0b1b2[0] > 1.0)
return null;
// b1:
triangleHeight = distanceFromLine(V[1],V[0],V[2].subtract3(V[0]));
heightFromPoint = distanceFromLine(pnt,V[0],V[2].subtract3(V[0]));
b0b1b2[1] = heightFromPoint/triangleHeight;
if (Math.abs(b0b1b2[1]) < tol) b0b1b2[1] = 0.0;
else if (Math.abs(1.0-b0b1b2[1]) < tol) b0b1b2[1] = 1.0;
if (b0b1b2[1] < 0.0 || b0b1b2[1] > 1.0)
return null;
// b2:
b0b1b2[2] = 1.0 - b0b1b2[0] - b0b1b2[1];
if (Math.abs(b0b1b2[2]) < tol) b0b1b2[2] = 0.0;
else if (Math.abs(1.0-b0b1b2[2]) < tol) b0b1b2[2] = 1.0;
if (b0b1b2[2] < 0.0)
return null;
return b0b1b2;
}
private static double distanceFromLine(Vec4 pnt, Vec4 P, Vec4 u)
{
// Return distance from pnt to line(P,u)
// Pythagorean theorem approach: c^2 = a^2 + b^2. The
// The square of the distance we seek is b^2:
Vec4 toPoint = pnt.subtract3(P);
double cSquared = toPoint.dot3(toPoint);
double aSquared = u.normalize3().dot3(toPoint);
aSquared *= aSquared;
double distSquared = cSquared - aSquared;
if (distSquared < 0.0)
// must be a tiny number that really ought to be 0.0
return 0.0;
return Math.sqrt(distSquared);
}
protected DoubleBuffer makeGeographicTexCoords(SectorGeometry sg,
SectorGeometry.GeographicTextureCoordinateComputer computer)
{
if (sg == null)
{
String msg = Logging.getMessage("nullValue.SectorGeometryIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (computer == null)
{
String msg = Logging.getMessage("nullValue.TextureCoordinateComputerIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
RectTile rt = (RectTile) sg;
int density = rt.density;
if (density < 1)
density = 1;
int coordCount = (density + 3) * (density + 3);
DoubleBuffer p = BufferUtil.newDoubleBuffer(2 * coordCount);
double deltaLat = rt.sector.getDeltaLatRadians() / density;
double deltaLon = rt.sector.getDeltaLonRadians() / density;
Angle minLat = rt.sector.getMinLatitude();
Angle maxLat = rt.sector.getMaxLatitude();
Angle minLon = rt.sector.getMinLongitude();
Angle maxLon = rt.sector.getMaxLongitude();
double[] uv; // for return values from computer
int k = 2 * (density + 3);
for (int j = 0; j < density; j++)
{
Angle lat = Angle.fromRadians(minLat.radians + j * deltaLat);
// skirt column; duplicate first column
uv = computer.compute(lat, minLon);
p.put(k++, uv[0]).put(k++, uv[1]);
// interior columns
for (int i = 0; i < density; i++)
{
Angle lon = Angle.fromRadians(minLon.radians + i * deltaLon);
uv = computer.compute(lat, lon);
p.put(k++, uv[0]).put(k++, uv[1]);
}
// last interior column; force u to 1.
uv = computer.compute(lat, maxLon);
p.put(k++, uv[0]).put(k++, uv[1]);
// skirt column; duplicate previous column
p.put(k++, uv[0]).put(k++, uv[1]);
}
// Last interior row
uv = computer.compute(maxLat, minLon); // skirt column
p.put(k++, uv[0]).put(k++, uv[1]);
for (int i = 0; i < density; i++)
{
Angle lon = Angle.fromRadians(minLon.radians + i * deltaLon); // u
uv = computer.compute(maxLat, lon);
p.put(k++, uv[0]).put(k++, uv[1]);
}
uv = computer.compute(maxLat, maxLon); // last interior column
p.put(k++, uv[0]).put(k++, uv[1]);
p.put(k++, uv[0]).put(k++, uv[1]); // skirt column
// last skirt row
int kk = k - 2 * (density + 3);
for (int i = 0; i < density + 3; i++)
{
p.put(k++, p.get(kk++));
p.put(k++, p.get(kk++));
}
// first skirt row
k = 0;
kk = 2 * (density + 3);
for (int i = 0; i < density + 3; i++)
{
p.put(k++, p.get(kk++));
p.put(k++, p.get(kk++));
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -