⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 202f0d37e0c5001d1cd1e38dc83e3a87

📁 使用java实现applet插件
💻
📖 第 1 页 / 共 3 页
字号:
package JavaTerrain;

import java.awt.Image;
import java.awt.image.*;
import java.awt.Component;
import java.util.*;

import javax.media.j3d.*;
import javax.vecmath.*;
import javax.media.j3d.*;
import javax.swing.JButton;

import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.mouse.*;
import com.sun.j3d.utils.image.TextureLoader;




public class Terrain extends Shape3D implements GeometryUpdater, MouseBehaviorCallback {

       //=== CONSTANTS ===============================================================================================

        private static final float MAX_F = Float.MAX_VALUE;     // shortcut

        private static final int FLOATS_PER_VERTEX = 5;         // s,t, x,y,z

        private static final int NW = 0, W = 1, SW = 2, S = 3, SE = 4, E = 5, NE = 6, N = 7, C = 8;

        private static final int NUL   = 0, NLL   = 1, NLR = 2, NUR    = 3,
                                 FUL   = 4, FLL   = 5, FLR = 6, FUR    = 7;
        private static final int LEFT  = 0, RIGHT = 1, TOP = 2, BOTTOM = 3, NEAR = 4, FAR = 5;



       //=== VARIABLES ===============================================================================================

       //--- some Java 3D classes ----------------------------------------------------------------

        private SimpleUniverse SimpleU;         // ref. to Universe

        private Texture2D      Texture;         // the texture

        private TriangleArray  TerrainTA;       // contains vertices and tex coords

        private Geometry       TGeometry;       // local geometry
        private Appearance     TAppearance;     // local appearance


       //--- arrays ------------------------------------------------------------------------------

        private float[] Vertices;               // positions  saved for reference
        private float[] TexCoords;              // tex coords saved for reference

        private float[] Interleaved;            // working array, size: max #vertices * 5

        private float[] QuadMatrix;             // represents quad tree (and contains heights)
        private float[] ErrorMatrix;            // contains d2 error values


       //--- diverse values ----------------------------------------------------------------------

        private int   MinGlobalRes = 12;        // min global res., the higher the more vertices
        private float DesiredRes   = 22.0f;     // desired global resolution
        private float D2K;                      // factor for neighboring D2-values


        private float VertexSpacing;            // distance between two height values (resolution)
        private int   Width;                    // num. of height values in x- and y-direction
        private int   Level;                    // max num of levels
        private float MaxHeight;                // height of 'highest' elevation

        private int   NumFans;                  // num of Fans
        private int   VNum;                     // num of Vertices

        private float HeightAboveGround;        // height above ground


       //--- for Geometry updates ----------------------------------------------------------------

        private Transform3D GUT3D   = new Transform3D();
        private Vector3f    EyePos  = new Vector3f();

        private boolean CreateNewTA = true;     // if array has been resized
        private boolean GeoMorph    = true;     // use geomorphing?

        private boolean TextureRamp = false;    // real texture or generated ramp?


       //--- for view frustum culling ------------------------------------------------------------

        private Point3d          Point        = new Point3d();

        private Vector4d[]       Planes       = new Vector4d[6];
        private Vector3d[]       Normals      = new Vector3d[6];
        private Vector3d[]       Vectors      = new Vector3d[2];
        private Point3d[]        Points       = new Point3d[8];

        private BoundingPolytope ViewFrustum  = new BoundingPolytope();
        private BoundingSphere   BoundsSphere = new BoundingSphere();

        private JButton Abutton = new JButton();

       //=== METHODS =================================================================================================

       //=== Constructor ==========================================================================================

        public Terrain(SimpleUniverse su, int[] hMap, Texture2D tex2D, float cx, float cz, float vertSpacing,
                       float maxHeight) {

               //--- initialization ----------------------------------------------------------------------

                SimpleU       = su;
                Texture       = tex2D;
                VertexSpacing = vertSpacing;
                MaxHeight     = maxHeight;

                D2K         = (float) MinGlobalRes / (2.0f * (MinGlobalRes - 1.0f));

                Width       = (int)  Math.sqrt((double) hMap.length);
                Level       = (int) (Math.log ((double) (Width - 1)) / Math.log(2.0d));
                NumFans     = (int)  Math.pow (4.0, (double) (Level - 1));


               //--- create Texture2D ? ------------------------------------------------------------------

                int h = 256;

                if (Texture == null) {

                        TextureRamp = true;

                        int[] c     = new int[2 * h];
                        int   index = 0;


                        for (int y = h-1; y >= 0; y--) {

                                int val   = 255 << 24;
                                int green = ((y * 135) / (h - 1)) + 120;

                                if (y % 10 == 0) {  green -= 20;  }

                                val |= (green << 8);

                                c[index++] = val;
                                c[index++] = val;
                        }


                        Canvas3D c3d  = SimpleU.getViewer().getCanvases();
                        Image    img  = c3d.createImage((ImageProducer)
                                        new MemoryImageSource(2, h, c, 0, 2));

                        TextureLoader    texLoader = new TextureLoader(img, c3d);
                        ImageComponent2D ic2d      = texLoader.getImage();
                        Texture                    = new Texture2D(Texture.BASE_LEVEL, Texture.RGB,
                                                                   ic2d.getWidth(), ic2d.getHeight());

                        Texture.setImage(0, ic2d);
                        Texture.setEnable(true);
                        Texture.setMinFilter(Texture.NICEST);
                        Texture.setMagFilter(Texture.NICEST);
                }


               //--- allocate memory ---------------------------------------------------------------------

                for (int i = 0; i < Planes.length;  i++)  {  Planes [i] = new Vector4d();    }
                for (int i = 0; i < Normals.length; i++)  {  Normals[i] = new Vector3d();    }
                for (int i = 0; i < Vectors.length; i++)  {  Vectors[i] = new Vector3d();    }
                for (int i = 0; i < Points.length;  i++)  {  Points [i] = new Point3d();     }


                Vertices    = new float[Width * Width * 3];
                TexCoords   = new float[Width * Width * 2];

                QuadMatrix  = new float[Width * Width    ];
                ErrorMatrix = new float[Width * Width    ];

                Interleaved = new float[10002 * FLOATS_PER_VERTEX];

                Arrays.fill(QuadMatrix, MAX_F);


               //--- fill Vertices and TexCoords arrays with values --------------------------------------

                float mid  = (float) Width * VertexSpacing / 2.0f;

                float step = 1.0f / (float) Width;              // Width steps between [0..1.0] for:
                float s, t = 1.0f;                              // tex coords
                int   vnum = 0;                                 // vertex number


                float heightSteps = MaxHeight / 255.0f;

                for (int z = 0; z < Width; z++, t-=step) {

                        s = 0.0f;

                        for (int x = 0; x < Width; x++, vnum++, s+=step) {

                                setVertex(Vertices, vnum,(x * VertexSpacing - mid + cx),
                                                         ((float) hMap[vnum] * heightSteps),
                                                         (z * VertexSpacing - mid + cz));

                                if (TextureRamp) {

                                        setVertex2(TexCoords, vnum,
                                                   0.25f, ((float) hMap[vnum] / 255.0f));
                                }
                                else {
                                        setVertex2(TexCoords, vnum, s, t);
                                }
                        }
                }


               //--- set Geometry and Appearance ---------------------------------------------------------

                setCapability(ALLOW_GEOMETRY_WRITE);
                setCapability(ALLOW_APPEARANCE_WRITE);
                
                Abutton.setText("Option");

                calcD2ErrorMatrix();

                              createGeometry();
                TAppearance = createAppearance(true);

                setAppearance(TAppearance);     // setGeometry(TGeometry) exec. in createGeometry
        }




       //=== Vertex manipulation ==================================================================================

        private void setVertex(float[] array, int vnum, float x, float y, float z) {

                vnum *= 3;                              // vertex number * #values per vertex

                array[vnum  ] = x;
                array[vnum+1] = y;
                array[vnum+2] = z;
        }

        private void setVertex2(float[] array, int vnum, float s, float t) {

                vnum *= 2;                              // vertex number * #values per vertex

                array[vnum  ] = s;
                array[vnum+1] = t;
        }



        private void getVertex(int vnum, Point3d point) {

                vnum *= 3;

                point.x = Vertices[vnum    ];
                point.y = Vertices[vnum + 1];
                point.z = Vertices[vnum + 2];
        }




       //=== ErrorMatrix calculations =============================================================================

        private void calcD2ErrorMatrix() {

               //--- call recursive function for setting initial D2-Values ---

                calcD2ErrorMatrixRec(Width / 2, Width / 2, Width, 1);


               //--- ensure max level difference of 1 ------------------------

                propagateD2Errors();
        }



        private void calcD2ErrorMatrixRec(int centerX, int centerZ, int width, int level) {

                if (level <= Level) {

                       //--- current value -------------------------------------------------------------

                        int nodeIndex = centerZ * Width + centerX;

                        ErrorMatrix[nodeIndex] = calcD2Value(centerX, centerZ, width);


                       //--- descend tree --------------------------------------------------------------

                        int w2 = width / 2;
                        int w4 = width / 4;

                        calcD2ErrorMatrixRec(centerX - w4, centerZ + w4, w2, level + 1);  // nw child
                        calcD2ErrorMatrixRec(centerX + w4, centerZ + w4, w2, level + 1);  // ne child
                        calcD2ErrorMatrixRec(centerX + w4, centerZ - w4, w2, level + 1);  // se child
                        calcD2ErrorMatrixRec(centerX - w4, centerZ - w4, w2, level + 1);  // sw child
                }
        }



        private float calcD2Value(int centerX, int centerZ, int width) {

               //--- init needed vars -------------------------------------------------------------

                int rx = width / 2;                     // radius offset in x direction
                int rz = rx * Width;                    // radius offset in z direction

                int c  = centerZ * Width + centerX;     // center vertex
                int n  = c - rz;                        // northern vertex
                int w  = c - rx;                        // western
                int s  = c + rz;                        // southern
                int e  = c + rx;                        // eastern
                int nw = n - rx;                        // ...
                int sw = s - rx;
                int se = s + rx;
                int ne = n + rx;

                float[] v = Vertices;                   // shortcut


               //--- north, east, south, west errors ----------------------------------------------

                float nErr = Math.abs((float) v[n*3+1] - (float) (v[nw*3+1] + v[ne*3+1]) / 2.0f);
                float eErr = Math.abs((float) v[e*3+1] - (float) (v[ne*3+1] + v[se*3+1]) / 2.0f);
                float sErr = Math.abs((float) v[s*3+1] - (float) (v[se*3+1] + v[sw*3+1]) / 2.0f);
                float wErr = Math.abs((float) v[w*3+1] - (float) (v[sw*3+1] + v[nw*3+1]) / 2.0f);


               //--- 1. and 2. diagonal error -----------------------------------------------------

                float d1Err = Math.abs((float) v[c*3+1] - (float) (v[nw*3+1] + v[se*3+1]) / 2.0f);
                float d2Err = Math.abs((float) v[c*3+1] - (float) (v[ne*3+1] + v[sw*3+1]) / 2.0f);


               //--- determine max of the 6 errors ------------------------------------------------

                float maxErr = Math.max(Math.max(nErr, eErr),
                               Math.max(Math.max(sErr, wErr), Math.max(d1Err, d2Err)));


                return (maxErr / ((float) width * VertexSpacing));
        }



        private void propagateD2Errors() {

                // find the highest level

               //--- init vars --------------------------------------------------------------------

                int steps = Width / 2;
                int width = 2;

                int centerX, centerZ;

                int w2;
                int p1, p2, p3;                 // indices of parents
		int p1x = 0, p1z = 0, 
		    p2x = 0, p2z = 0, 
		    p3x = 0, p3z = 0;

                float[] em = ErrorMatrix;       // shortcut


               //--- iterate through all levels ---------------------------------------------------

                while (steps > 1) {

                        w2 = width / 2;

  		        centerX = w2;

                        for (int i = 0; i < steps; i++) {

   		                centerZ = w2;

                                for (int j = 0; j < steps; j++) {

					//--- determine parents' indices ------------------------

					switch ((centerX/width)%2 + 2*((centerZ/width)%2)) {

					case 0: p1x = centerX+w2;
						p1z = centerZ+w2;
						p2x = centerX-width-w2;
						p2z = centerZ+w2;
						p3x = centerX+w2;
						p3z = centerZ-width-w2;
						break;

					case 1: p1x = centerX-w2;
						p1z = centerZ+w2;
						p2x = centerX-w2;
						p2z = centerZ-width-w2;
						p3x = centerX+width+w2;
						p3z = centerZ+w2;
						break;

					case 2: p1x = centerX+w2;
						p1z = centerZ-w2;
						p2x = centerX+w2;
						p2z = centerZ+width+w2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -