Java版WorldWind中加入会运动模型

洪鸿
2023-12-01

在worldwind sdk中的gov.nasa.worldwind.geom,这个包是存放一些几何模型的。

我使用的是球类Sphere,它是使用OpenGL画出来的。

参考这个类进行了一定的修改成为PlaneRender.java  代码如下:


import gov.nasa.worldwind.View;
import gov.nasa.worldwind.geom.Extent;
import gov.nasa.worldwind.geom.Frustum;
import gov.nasa.worldwind.geom.Intersection;
import gov.nasa.worldwind.geom.Line;
import gov.nasa.worldwind.geom.Plane;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.render.*;
import gov.nasa.worldwind.util.Logging;
import java.awt.Color;

public final class PlaneRender implements Extent, Renderable
{
    private Vec4 center;
    private  double radius;  
    
    private boolean sphereFilled = false;
    private Color sphereColor = Color.RED;  
    private int numDivisions = 8; // number of horizontal and verticle divisions in the sphere

    boolean plotFixedAxis = false;
    
    // improve performance keep from creating a new one all the time
    javax.media.opengl.glu.GLUquadric quadric;
    


    /**
     * Creates a new <code>Sphere</code> from a given center and radius. <code>radius</code> must be positive (that is,
     * greater than zero), and <code>center</code> may not be null.
     *
     * @param center the center of the new sphere
     * @param radius the radius of the new sphere
     * @param isfilled if the sphere is filled (else wireframe)
     * @throws IllegalArgumentException if <code>center</code> is null or if <code>radius</code> is non-positive
     */
    public PlaneRender(Vec4 center, double radius, boolean isfilled)
    {
        if (center == null)
        {
            String message = Logging.getMessage("nullValue.CenterIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        if (radius <= 0)
        {
            String message = Logging.getMessage("Geom.Sphere.RadiusIsZeroOrNegative", radius);
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        this.center = center;
        this.radius = radius;
        this.sphereFilled = isfilled;
    }
    


    /**
     * Obtains the center of this <code>Sphere</code>.
     *
     * @return the <code>Vec4</code> situated at the center of this <code>Sphere</code>
     */
    public final Vec4 getCenter()
    {
        return this.center;
    }



    /**
     * Causes this <code>Sphere</code> to render itself using the <code>DrawContext</code> provided. <code>dc</code> may
     * not be null.
     *
     * @param dc the <code>DrawContext</code> to be used
     * @throws IllegalArgumentException if <code>dc</code> is null
     */
    public void render(DrawContext dc)
    {
      
        if (dc == null)
        {
            String msg = Logging.getMessage("nullValue.DrawContextIsNull");
            Logging.logger().severe(msg);
            throw new IllegalArgumentException(msg);
        }

        javax.media.opengl.GL gl = dc.getGL();
         

        gl.glPushAttrib(javax.media.opengl.GL.GL_TEXTURE_BIT | javax.media.opengl.GL.GL_ENABLE_BIT
            | javax.media.opengl.GL.GL_CURRENT_BIT);
        gl.glDisable(javax.media.opengl.GL.GL_TEXTURE_2D);
        
        gl.glColor3d( sphereColor.getRed()/255.0 , sphereColor.getGreen()/255.0 , sphereColor.getBlue()/255.0 ); // COLOR 

        gl.glMatrixMode(javax.media.opengl.GL.GL_MODELVIEW);
        gl.glPushMatrix();
     
       // gl.glTranslated(this.center.x, this.center.y, this.center.z);
        gl.glTranslated(5046634.313882601, 2081316.7191214513, 4414638.612102969);
        if(quadric == null)
        {
            quadric = dc.getGLU().gluNewQuadric();
        }
             
        
        if(sphereFilled)
        {
            dc.getGLU().gluQuadricDrawStyle(quadric, javax.media.opengl.glu.GLU.GLU_FILL);
        }
        else // lines
        {
            dc.getGLU().gluQuadricDrawStyle(quadric, javax.media.opengl.glu.GLU.GLU_LINE);
        }
        

        dc.getGLU().gluSphere(quadric, this.radius, numDivisions, numDivisions);
        
        // Draw in axis
        if(plotFixedAxis)
        {
            gl.glLineWidth(3.0f);
            gl.glColor3d(1, 0, 0); // COLOR 
            gl.glBegin(gl.GL_LINES);
                gl.glVertex3d(radius * 3, 0, 0);
                gl.glVertex3d(0, 0, 0);
            gl.glEnd();
            // Draw in axis
            gl.glColor3d(0, 1, 0); // COLOR 
            gl.glBegin(gl.GL_LINES);
                gl.glVertex3d(0, radius * 3, 0);
                gl.glVertex3d(0, 0, 0);
            gl.glEnd();
            // Draw in axis
            gl.glColor3d(0, 0, 1); // COLOR 
            gl.glBegin(gl.GL_LINES);
                gl.glVertex3d(0, 0, radius * 3);
                gl.glVertex3d(0, 0, 0);
            gl.glEnd();
        }
        
        gl.glPopMatrix();
        dc.getGLU().gluDeleteQuadric(quadric);

        gl.glPopAttrib();
    

    }

    
    @Override
    public String toString()
    {
        return "Sphere: center = " + this.center.toString() + " radius = " + Double.toString(this.radius);
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        final PlaneRender sphere = (PlaneRender) o;

        if (Double.compare(sphere.radius, radius) != 0)
            return false;
        if (!center.equals(sphere.center))
            return false;

        return true;
    }

    @Override
    public int hashCode()
    {
        int result;
        long temp;
        result = center.hashCode();
        temp = radius != +0.0d ? Double.doubleToLongBits(radius) : 0L;
        result = 29 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }



    public boolean isSphereFilled()
    {
        return sphereFilled;
    }

    public void setSphereFilled(boolean sphereFilled)
    {
        this.sphereFilled = sphereFilled;
    }

    public Color getColor()
    {
        return sphereColor;
    }

    public void setColor(Color sphereColor)
    {
        this.sphereColor = sphereColor;
    }

    public int getNumDivisions()
    {
        return numDivisions;
    }

    public void setNumDivisions(int numDivisions)
    {
        this.numDivisions = numDivisions;
    }

    public void setCenter(Vec4 center)
    {
        this.center = center;
    }
    
    public void setCenter(double x, double y, double z)
    {
        this.center = new Vec4(x,y,z,0.0);
    }

	public double getEffectiveRadius(Plane arg0) {
		// TODO Auto-generated method stub
		return 0;
	}

	public double getProjectedArea(View arg0) {
		// TODO Auto-generated method stub
		return radius;
	}

	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public Intersection[] intersect(Line arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean intersects(Frustum arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean intersects(Line arg0) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean intersects(Plane arg0) {
		// TODO Auto-generated method stub
		return false;
	}
}
这个类里主要用到的是setCenter()方法。

测试中使用的是最简单的一个例子HelloWorldWind类。代码如下


import java.awt.Color;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Sphere;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.layers.CompassLayer;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.layers.LayerList;
import gov.nasa.worldwind.layers.RenderableLayer;


public class HelloWorldWind
{

    private static class AppFrame extends javax.swing.JFrame
    {
        public AppFrame()
        {
        	RenderableLayer rayLayer = new RenderableLayer();
            double sphereRadius = 100000;
            PlaneRender sphere = new PlaneRender(new Vec4(0,0,0,0), sphereRadius, true);
            sphere.setColor(Color.RED);
            rayLayer.addRenderable(sphere);

            
            WorldWindowGLCanvas wwd = new WorldWindowGLCanvas();
            wwd.setPreferredSize(new java.awt.Dimension(1000, 800));
            this.getContentPane().add(wwd, java.awt.BorderLayout.CENTER);
            this.pack();

            wwd.setModel(new BasicModel());
            
            wwd.getModel().getLayers().add(rayLayer);                       
           
        }
    }

    public static void main(String[] args)
    {
        if (Configuration.isMacOS())
        {
            System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Hello World Wind");
        }

        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                new AppFrame().setVisible(true);
            }
        });
    }
}
注意:在我在PlaneRender类里面设置了一个固定位置
        gl.glTranslated(5046634.313882601, 2081316.7191214513, 4414638.612102969);

里面参数是大地坐标。

所以出现在球上面的是一个不动的小圆球,想要移动这个球就要不断地用到 PlaneRender类里面的setCenter()方法了。




 类似资料: