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

📄 rectangularnormaltessellator.java

📁 world wind java sdk 源码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

		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 + -