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

📄 rectangularnormaltessellator.java

📁 world wind java sdk 源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	private void selectVisibleTiles(DrawContext dc, RectTile tile)
	{
		Extent extent = tile.getExtent();
		if (extent != null && !extent.intersects(this.currentFrustum))
			return;

		if (this.currentLevel < this.maxLevel - 1 && this.needToSplit(dc, tile))
		{
			++this.currentLevel;
			RectTile[] subtiles = this.split(dc, tile);
			for (RectTile child : subtiles)
			{
				this.selectVisibleTiles(dc, child);
			}
			--this.currentLevel;
			return;
		}
		this.currentCoverage = tile.getSector().union(this.currentCoverage);
		this.currentTiles.add(tile);
	}

	private boolean needToSplit(DrawContext dc, RectTile tile)
	{
		Vec4[] corners = tile.sector.computeCornerPoints(dc.getGlobe(), dc.getVerticalExaggeration());
		Vec4 centerPoint = tile.sector.computeCenterPoint(dc.getGlobe(), dc.getVerticalExaggeration());

		View view = dc.getView();
		double d1 = view.getEyePoint().distanceTo3(corners[0]);
		double d2 = view.getEyePoint().distanceTo3(corners[1]);
		double d3 = view.getEyePoint().distanceTo3(corners[2]);
		double d4 = view.getEyePoint().distanceTo3(corners[3]);
		double d5 = view.getEyePoint().distanceTo3(centerPoint);

		double minDistance = d1;
		if (d2 < minDistance)
			minDistance = d2;
		if (d3 < minDistance)
			minDistance = d3;
		if (d4 < minDistance)
			minDistance = d4;
		if (d5 < minDistance)
			minDistance = d5;

		double logDist = Math.log10(minDistance);
		boolean useTile = tile.log10CellSize <= (logDist - DEFAULT_LOG10_RESOLUTION_TARGET);

		return !useTile;
	}

	private RectTile[] split(DrawContext dc, RectTile tile)
	{
		Sector[] sectors = tile.sector.subdivide();

		RectTile[] subTiles = new RectTile[4];
		subTiles[0] = this.createTile(dc, sectors[0], tile.level + 1);
		subTiles[1] = this.createTile(dc, sectors[1], tile.level + 1);
		subTiles[2] = this.createTile(dc, sectors[2], tile.level + 1);
		subTiles[3] = this.createTile(dc, sectors[3], tile.level + 1);

		return subTiles;
	}

    private RectangularNormalTessellator.CacheKey createCacheKey(DrawContext dc, RectTile tile)
    {
        return new CacheKey(dc, tile.sector, tile.density);
    }

    private void makeVerts(DrawContext dc, RectTile tile)
    {
        // First see if the vertices have been previously computed and are in the cache. Since the elevation model
        // can change between frames, regenerate and re-cache vertices every second.
        MemoryCache cache = WorldWind.getMemoryCache(CACHE_ID);
        CacheKey cacheKey = this.createCacheKey(dc, tile);
        tile.ri = (RenderInfo) cache.getObject(cacheKey);
        if (tile.ri != null && tile.ri.time >= System.currentTimeMillis() - 1000) // Regenerate cache after one second
            return;

        tile.ri = this.buildVerts(dc, tile, this.makeTileSkirts);
        if (tile.ri != null)
        {
            cacheKey = this.createCacheKey(dc, tile);
            cache.add(cacheKey, tile.ri, tile.ri.getSizeInBytes());
        }
    }

	public RenderInfo buildVerts(DrawContext dc, RectTile tile, boolean makeSkirts)
	{
		int density = tile.density;
		int side = density + 3;
		int numVertices = side * side;
		java.nio.DoubleBuffer verts = BufferUtil.newDoubleBuffer(numVertices * 3);
        ArrayList<LatLon> latlons = this.computeLocations(tile);
        double[] elevations = new double[latlons.size()];
        dc.getGlobe().getElevations(tile.sector, latlons, tile.getResolution(), elevations);

		Globe globe = dc.getGlobe();

		Angle dLat = tile.sector.getDeltaLat().divide(density);
		Angle latMin = tile.sector.getMinLatitude();
		Angle latMax = tile.sector.getMaxLatitude();

		Angle dLon = tile.sector.getDeltaLon().divide(density);
		Angle lonMin = tile.sector.getMinLongitude();
		Angle lonMax = tile.sector.getMaxLongitude();

		Angle lat, lon;
		int iv = 0;
		double elevation, verticalExaggeration = dc.getVerticalExaggeration();
		Vec4 p;

		LatLon centroid = tile.sector.getCentroid();
		Vec4 refCenter = globe.computePointFromPosition(centroid.getLatitude(), centroid.getLongitude(), 0d);

        int ie = 0;
        Iterator<LatLon> latLonIter = latlons.iterator();

        // Compute verts without skirts
		for (int j = 0; j < side; j++)
		{
			for (int i = 0; i < side; i++)
			{
                LatLon latlon = latLonIter.next();
                elevation = verticalExaggeration * elevations[ie++];
				p = globe.computePointFromPosition(latlon.getLatitude(), latlon.getLongitude(), elevation);
				verts.put(iv++, p.x - refCenter.x).put(iv++, p.y - refCenter.y).put(iv++, p.z - refCenter.z);
			}
		}

		// Compute indices and normals
		java.nio.IntBuffer indices = getIndices(density);
		java.nio.DoubleBuffer norms = getNormals(density, verts, indices, refCenter);

		// Fold down the sides as skirts
		double exaggeratedMinElevation = makeSkirts ? Math.abs(globe.getMinElevation() * verticalExaggeration) : 0;
		lat = latMin;
		for (int j = 0; j < side; j++)
		{
			//min longitude side
            ie = j * side + 1;
            elevation = verticalExaggeration * elevations[ie];
			elevation -= exaggeratedMinElevation >= 0 ? exaggeratedMinElevation : -exaggeratedMinElevation;
			p = globe.computePointFromPosition(lat, lonMin, elevation);
			iv = (j * side) * 3;
			verts.put(iv++, p.x - refCenter.x).put(iv++, p.y - refCenter.y)
					.put(iv++, p.z - refCenter.z);

			//max longitude side
            ie += side - 2;
            elevation = verticalExaggeration * elevations[ie];
			elevation -= exaggeratedMinElevation >= 0 ? exaggeratedMinElevation : -exaggeratedMinElevation;
			p = globe.computePointFromPosition(lat, lonMax, elevation);
			iv = ((j + 1) * side - 1) * 3;
			verts.put(iv++, p.x - refCenter.x).put(iv++, p.y - refCenter.y)
					.put(iv++, p.z - refCenter.z);

			if (j > density)
				lat = latMax;
			else if (j != 0)
				lat = lat.add(dLat);
		}

		lon = lonMin;
		for (int i = 0; i < side; i++)
		{
			//min latitude side
            ie = i + side;
            elevation = verticalExaggeration * elevations[ie];
			elevation -= exaggeratedMinElevation >= 0 ? exaggeratedMinElevation : -exaggeratedMinElevation;
			p = globe.computePointFromPosition(latMin, lon, elevation);
			iv = i * 3;
			verts.put(iv++, p.x - refCenter.x).put(iv++, p.y - refCenter.y)
					.put(iv++, p.z - refCenter.z);

			//max latitude side
            ie += (side - 2) * side;
            elevation = verticalExaggeration * elevations[ie];
			elevation -= exaggeratedMinElevation >= 0 ? exaggeratedMinElevation : -exaggeratedMinElevation;
			p = globe.computePointFromPosition(latMax, lon, elevation);
			iv = (side * (side - 1) + i) * 3;
			verts.put(iv++, p.x - refCenter.x).put(iv++, p.y - refCenter.y)
					.put(iv++, p.z - refCenter.z);

			if (i > density)
				lon = lonMax;
			else if (i != 0)
				lon = lon.add(dLon);
		}

		return new RenderInfo(density, verts, getTextureCoordinates(density), norms, refCenter);
	}

    private ArrayList<LatLon> computeLocations(RectTile tile)
    {
        int density = tile.density;
        int numVertices = (density + 3) * (density + 3);

        Angle latMax = tile.sector.getMaxLatitude();
        Angle dLat = tile.sector.getDeltaLat().divide(density);
        Angle lat = tile.sector.getMinLatitude().subtract(dLat);

        Angle lonMin = tile.sector.getMinLongitude();
        Angle lonMax = tile.sector.getMaxLongitude();
        Angle dLon = tile.sector.getDeltaLon().divide(density);

        ArrayList<LatLon> latlons = new ArrayList<LatLon>(numVertices);
        for (int j = 0; j <= density + 2; j++)
        {
            Angle lon = lonMin.subtract(dLon);
            for (int i = 0; i <= density + 2; i++)
            {
                latlons.add(new LatLon(lat, lon));

                lon = lon.add(dLon);

                if (lon.degrees < -180)
                    lon = Angle.NEG180;
                else if (lon.degrees > 180)
                    lon = Angle.POS180;
            }

            lat = lat.add(dLat);
        }

        return latlons;
    }

    private void renderMultiTexture(DrawContext dc, RectTile tile,
			int numTextureUnits)
	{
		if (dc == null)
		{
			String msg = Logging.getMessage("nullValue.DrawContextIsNull");
			Logging.logger().severe(msg);
			throw new IllegalArgumentException(msg);
		}

		if (numTextureUnits < 1)
		{
			String msg = Logging
					.getMessage("generic.NumTextureUnitsLessThanOne");
			Logging.logger().severe(msg);
			throw new IllegalArgumentException(msg);
		}

		this.render(dc, tile, numTextureUnits);
	}

	private void render(DrawContext dc, RectTile tile)
	{
		if (dc == null)
		{
			String msg = Logging.getMessage("nullValue.DrawContextIsNull");
			Logging.logger().severe(msg);
			throw new IllegalArgumentException(msg);
		}

		this.render(dc, tile, 1);
	}

	private long render(DrawContext dc, RectTile tile, int numTextureUnits)
	{
		if (tile.ri == null)
		{
			String msg = Logging.getMessage("nullValue.RenderInfoIsNull");
			Logging.logger().severe(msg);
			throw new IllegalStateException(msg);
		}

		dc.getView().pushReferenceCenter(dc, tile.ri.referenceCenter);

        if (!dc.isPickingMode() && this.lightDirection != null)
            beginLighting(dc);

        GL gl = dc.getGL();
		gl.glPushClientAttrib(GL.GL_CLIENT_VERTEX_ARRAY_BIT);
		gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL.GL_DOUBLE, 0, tile.ri.vertices.rewind());

		gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
		gl.glNormalPointer(GL.GL_DOUBLE, 0, tile.ri.normals.rewind());

		for (int i = 0; i < numTextureUnits; i++)
		{
			gl.glClientActiveTexture(GL.GL_TEXTURE0 + i);
			gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
            Object texCoords = dc.getValue(AVKey.TEXTURE_COORDINATES);
            if (texCoords != null && texCoords instanceof DoubleBuffer)
                gl.glTexCoordPointer(2, GL.GL_DOUBLE, 0, ((DoubleBuffer) texCoords).rewind());
            else
                gl.glTexCoordPointer(2, GL.GL_DOUBLE, 0, tile.ri.texCoords.rewind());
		}

		gl.glDrawElements(javax.media.opengl.GL.GL_TRIANGLE_STRIP,
				tile.ri.indices.limit(), javax.media.opengl.GL.GL_UNSIGNED_INT,
				tile.ri.indices.rewind());

		gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
		gl.glPopClientAttrib();

        if (!dc.isPickingMode() && this.lightDirection != null)
            endLighting(dc);

        dc.getView().popReferenceCenter(dc);

		return tile.ri.indices.limit() - 2; // return number of triangles rendered
	}

    private void beginLighting(DrawContext dc)
    {
        GL gl = dc.getGL();
        gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_CURRENT_BIT | GL.GL_LIGHTING_BIT);

        this.material.apply(gl, GL.GL_FRONT);
        gl.glDisable(GL.GL_COLOR_MATERIAL);

        float[] lightPosition = {(float)-lightDirection.x, (float)-lightDirection.y, (float)-lightDirection.z, 0.0f};
        float[] lightDiffuse = new float[4];
        float[] lightAmbient = new float[4];
        lightColor.getRGBComponents(lightDiffuse);
        ambientColor.getRGBComponents(lightAmbient);

        gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPosition, 0);
        gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, lightDiffuse, 0);
        gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightAmbient, 0);

        gl.glDisable(GL.GL_LIGHT0);
        gl.glEnable(GL.GL_LIGHT1);
        gl.glEnable(GL.GL_LIGHTING);
    }

    private void endLighting(DrawContext dc)
    {
        GL gl = dc.getGL();

        gl.glDisable(GL.GL_LIGHT1);
        gl.glEnable(GL.GL_LIGHT0);
        gl.glDisable(GL.GL_LIGHTING);

        gl.glPopAttrib();
    }

    private void renderWireframe(DrawContext dc, RectTile tile,
			boolean showTriangles, boolean showTileBoundary)
	{
		if (dc == null)
		{
			String msg = Logging.getMessage("nullValue.DrawContextIsNull");
			Logging.logger().severe(msg);
			throw new IllegalArgumentException(msg);
		}

		if (tile.ri == null)
		{
			String msg = Logging.getMessage("nullValue.RenderInfoIsNull");
			Logging.logger().severe(msg);
			throw new IllegalStateException(msg);
		}

		java.nio.IntBuffer indices = getIndices(tile.ri.density);
		indices.rewind();

		dc.getView().pushReferenceCenter(dc, tile.ri.referenceCenter);

		javax.media.opengl.GL gl = dc.getGL();
		gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT | GL.GL_POLYGON_BIT
				| GL.GL_TEXTURE_BIT | GL.GL_ENABLE_BIT | GL.GL_CURRENT_BIT);
		gl.glEnable(GL.GL_BLEND);
		gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
		gl.glDisable(javax.media.opengl.GL.GL_DEPTH_TEST);
		gl.glEnable(javax.media.opengl.GL.GL_CULL_FACE);
		gl.glCullFace(javax.media.opengl.GL.GL_BACK);
		gl.glDisable(javax.media.opengl.GL.GL_TEXTURE_2D);
		gl.glColor4d(1d, 1d, 1d, 0.2);
		gl.glPolygonMode(javax.media.opengl.GL.GL_FRONT,
				javax.media.opengl.GL.GL_LINE);

		if (showTriangles)
		{
			gl.glPushClientAttrib(GL.GL_CLIENT_VERTEX_ARRAY_BIT);
			gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

			gl.glVertexPointer(3, GL.GL_DOUBLE, 0, tile.ri.vertices);
			gl.glDrawElements(javax.media.opengl.GL.GL_TRIANGLE_STRIP, indices
					.limit(), javax.media.opengl.GL.GL_UNSIGNED_INT, indices);

			gl.glPopClientAttrib();
		}

		dc.getView().popReferenceCenter(dc);

⌨️ 快捷键说明

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