📄 d0f2c3bddec5001d1cd1e38dc83e3a87
字号:
if (corners[SE]) {
setInterleaved(se, hSE);
if (corners[E]) {
setInterleaved(e, hE);
if (corners[NE]) {
setInterleaved(c, hC );
setInterleaved(e, hE );
setInterleaved(ne, hNE);
}
}
else {
if (corners[NE]) { setInterleaved(ne, hNE); }
else { setInterleaved(e, hE ); }
}
setInterleaved(c, hC);
}
else if (corners[E] || corners[NE]) {
setInterleaved(e, hE );
setInterleaved(ne, hNE);
setInterleaved(c, hC );
}
//--- check northern quarter ----------------------------------------------
if (corners[NE]) {
setInterleaved(ne, hNE);
if (corners[N]) {
setInterleaved(n, hN);
if (corners[NW]) {
setInterleaved(c, hC );
setInterleaved(n, hN );
setInterleaved(nw, hNW);
}
}
else {
if (corners[NW]) { setInterleaved(nw, hNW); }
else { setInterleaved(n, hN ); }
}
setInterleaved(c, hC);
}
else if (corners[N] || corners[NW]) {
setInterleaved(n, hN );
setInterleaved(nw, hNW);
setInterleaved(c, hC );
}
NumFans++;
}
private float getHeight(int index, int width, int dirToFather, int neswc, float blend,
float rhNW, float rhNE, float rhSW, float rhSE) {
//--- init vars ------------------------------------------------------------------------
float height = Vertices[index*3+1];
//--- determine blend values if this is a leaf -----------------------------------------
if (GeoMorph) {
//--- init other vars --------------------------------------------------------
int rx = width / 2; // radius offset in x dir.
int rz = rx * Width; // radius offset in z dir.
int z = index / Width; // z coord. of index
int x = index - (z * Width); // x coord. of index
//--- determine offset and center indices ------------------------------------
switch (neswc) {
case C: switch (dirToFather) {
case SE:
case NW: height = (1.0f-blend) * (rhNW + rhSE)/2.0f
+ blend*height;
break;
case NE:
case SW: height = (1.0f-blend) * (rhNE+rhSW)/2.0f
+ blend*height;
break;
}
break;
case N: if (z - rx >= 0) {
blend=Math.min(blend,QuadMatrix[index - rz]);
}
height = (1.0f-blend) * (rhNW+rhNE)/2.0f + blend*height;
break;
case S: if (z + rx < Width) {
blend=Math.min(blend,QuadMatrix[index + rz]);
}
height = (1.0f-blend) * (rhSW+rhSE)/2.0f + blend*height;
break;
case W: if (x - rx >= 0) {
blend=Math.min(blend,QuadMatrix[index - rx]);
}
height = (1.0f-blend) * (rhNW+rhSW)/2.0f + blend*height;
break;
case E: if (x + rx < Width) {
blend=Math.min(blend,QuadMatrix[index + rx]);
}
height = (1.0f-blend) * (rhNE+rhSE)/2.0f + blend*height;
break;
}
}
return height;
}
private void setInterleaved(int index, float height) {
//--- init vars ------------------------------------------------------------
int ii = VNum * FLOATS_PER_VERTEX;
int iv = index * 3;
int it = index * 2;
//--- set vertex data ------------------------------------------------------
Interleaved[ii++] = TexCoords[it];
Interleaved[ii++] = (TextureRamp) ? height / MaxHeight : TexCoords[it+1];
Interleaved[ii++] = Vertices[iv];
Interleaved[ii++] = height;
Interleaved[ii++] = Vertices[iv+2];
VNum++;
}
//=== Geometry update ======================================================================================
private void calcViewFrustum() {
//--- get view frustum parameters ---------------------------------------------
View view = SimpleU.getViewer().getView();
double fcd = view.getBackClipDistance() * 6;
double ncd = view.getFrontClipDistance();
double fovx = view.getFieldOfView();
double aspr = (double) view.getCanvas3D(0).getWidth() /
(double) view.getCanvas3D(0).getHeight();
//--- calculate the 6 view frustum points -------------------------------------
double nrx = Math.tan(fovx / 2) * ncd;
double nry = nrx / aspr;
double frx = (nrx / ncd) * fcd;
double fry = frx / aspr;
Points[NUL].set(-nrx, nry, -ncd); Points[NLL].set(-nrx, -nry, -ncd);
Points[NLR].set( nrx, -nry, -ncd); Points[NUR].set( nrx, nry, -ncd);
Points[FUL].set(-frx, fry, -fcd); Points[FLL].set(-frx, -fry, -fcd);
Points[FLR].set( frx, -fry, -fcd); Points[FUR].set( frx, fry, -fcd);
//--- calculate normals -------------------------------------------------------
Vector3d[] n = Normals; // shortcut
Vector3d[] v = Vectors; // shortcut
v[0].sub(Points[NUL], Points[NLL]);
v[1].sub(Points[FLL], Points[NLL]);
n[LEFT ].cross(v[0], v[1]);
n[RIGHT].set(-n[LEFT].x, n[LEFT].y, n[LEFT].z);
v[0].sub(Points[NUR], Points[NUL]);
v[1].sub(Points[FUL], Points[NUL]);
n[TOP ].cross(v[0], v[1]);
n[BOTTOM].set(n[TOP].x, -n[TOP].y, n[TOP].z);
n[NEAR].set(0.0f, 0.0f, 1.0f);
n[FAR ].set(0.0f, 0.0f, -1.0f);
for (int i = 0; i < n.length; i++) { GUT3D.transform(n[i]); }
//--- create view frustum BoundingPolytope ------------------------------------
GUT3D.transform(Points[NUL]);
GUT3D.transform(Points[FLR]);
v[0].set((Tuple3d) Points[NUL]);
v[1].set((Tuple3d) Points[FLR]);
Planes[0].set(n[LEFT ].x, n[LEFT ].y, n[LEFT ].z, -n[LEFT ].dot(v[0]));
Planes[1].set(n[RIGHT ].x, n[RIGHT ].y, n[RIGHT ].z, -n[RIGHT ].dot(v[1]));
Planes[2].set(n[TOP ].x, n[TOP ].y, n[TOP ].z, -n[TOP ].dot(v[0]));
Planes[3].set(n[BOTTOM].x, n[BOTTOM].y, n[BOTTOM].z, -n[BOTTOM].dot(v[1]));
Planes[4].set(n[NEAR ].x, n[NEAR ].y, n[NEAR ].z, -n[NEAR ].dot(v[0]));
Planes[5].set(n[FAR ].x, n[FAR ].y, n[FAR ].z, -n[FAR ].dot(v[1]));
ViewFrustum.setPlanes(Planes);
}
private void createGeometry() {
//--- get T3D and calc view frustum ---------------------------------------------------
SimpleU.getViewingPlatform().getViewPlatformTransform().getTransform(GUT3D);
GUT3D.get(EyePos);
calcViewFrustum();
VNum = NumFans = 0;
//--- triangulate Mesh ----------------------------------------------------------------
HeightAboveGround = getHeightAboveGround();
triangulateMeshRec(Width*Width / 2, Width-1, 1);//, C);
//--- create Terrain Mesh -------------------------------------------------------------
float hNW = Vertices[0 + 1];
float hNE = Vertices[(Width-1)*3 + 1];
float hSW = Vertices[(Width-1)*Width*3 + 1];
float hSE = Vertices[((Width-1)*Width+(Width-1))*3 + 1];
renderMeshRec(Width/2, Width/2, Width-1, 1, C, hNW, hNE, hSW, hSE);
if (CreateNewTA) {
TerrainTA = new TriangleArray(Interleaved.length / FLOATS_PER_VERTEX,
TriangleFanArray.COORDINATES |
TriangleFanArray.TEXTURE_COORDINATE_2 |
TriangleFanArray.BY_REFERENCE |
TriangleFanArray.INTERLEAVED );
TerrainTA.setCapability(TriangleFanArray.ALLOW_REF_DATA_WRITE);
TerrainTA.setCapability(TriangleFanArray.ALLOW_COUNT_WRITE);
TerrainTA.setInterleavedVertices(Interleaved);
TGeometry = TerrainTA;
CreateNewTA = false;
setGeometry(TGeometry);
}
TerrainTA.setValidVertexCount(VNum);
}
//=== Appearance settings ==================================================================================
private Appearance createAppearance(boolean filled) {
//--- create appearance attributes ---------------------------------------
Appearance app = new Appearance();
ColoringAttributes ca = new ColoringAttributes();
PolygonAttributes pa = new PolygonAttributes();
TextureAttributes ta = new TextureAttributes();
//--- set settings -------------------------------------------------------
app.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_READ);
ca.setShadeModel(ColoringAttributes.SHADE_FLAT);
pa.setCullFace(PolygonAttributes.CULL_NONE);
pa.setCapability(PolygonAttributes.ALLOW_MODE_WRITE);
if (!filled) { pa.setPolygonMode(PolygonAttributes.POLYGON_LINE); }
app.setColoringAttributes(ca);
app.setPolygonAttributes(pa);
app.setTexture(Texture);
return app;
}
public void setFilledPolys(boolean filled) {
PolygonAttributes pa = TAppearance.getPolygonAttributes();
if (filled) { pa.setPolygonMode(PolygonAttributes.POLYGON_LINE); }
else { pa.setPolygonMode(PolygonAttributes.POLYGON_FILL); }
}
public void toggleGeoMorphing() {
GeoMorph = (GeoMorph) ? false : true;
updateTerrain();
}
public void moreDetail(boolean updateNow) {
DesiredRes += 0.5f;
if (updateNow) { updateTerrain(); }
}
public void lessDetail(boolean updateNow) {
if (DesiredRes >= 0.5f) { DesiredRes -= 0.5f; }
if (updateNow) { updateTerrain(); }
}
//=== MouseBehaviorCallback part ===========================================================================
public void transformChanged(int type, Transform3D transform) {
updateTerrain();
}
//=== common update Terrain method =========================================================================
public void updateTerrain() {
TerrainTA.updateData(this);
}
//=== GeometryUpdater part =================================================================================
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// THIS WILL BE USED WITH EITHER:
// TriangleArray where setValidVertexIndex(int) already works OR WITH
// TriangleFanArray when setValidVertexIndex(int) works (J3D Version 1.3)
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public void updateData(Geometry geometry) {
createGeometry();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -