如何在JMonkey Engine库中绘制直线

时间:2013-07-02 11:46:58

标签: java line jmonkeyengine

我正在尝试使用JMonkey Engine 3D图形库在我指定的3D顶点之间绘制直线。 JMonkey当然是为导入模型而优化的,但我知道它也可用于“内部”创建自定义形状。

因此,例如,如果我想尝试绘制:
(2,0,0)
(-1,0,1)
(0,1,1)
(1,1,1)
(1,4,0​​)

然后我会得到:

JMonkey straight lines

1 个答案:

答案 0 :(得分:6)

<强>更新

在最新版本的Jmonkey中,存在一个Line类,这使得这个过程变得更加简单。这是详细的here

原始回答

JMonkey中的线是使用自定义网格创建的,您将顶点作为浮点数的位置缓冲区和索引(顶点连接到哪个)作为short的缓冲区。这个答案很容易基于a forum thread on mesh buffersthe JMonkey advanced graphics wiki page

示例程序如下

import com.jme3.app.SimpleApplication;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Box;
import com.jme3.util.BufferUtils;

public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {

        Vector3f[] lineVerticies=new Vector3f[5];

        lineVerticies[0]=new Vector3f(2,0,0);
        lineVerticies[1]=new Vector3f(-1,0,1);
        lineVerticies[2]=new Vector3f(0,1,1);
        lineVerticies[3]=new Vector3f(1,1,1);
        lineVerticies[4]=new Vector3f(1,4,0);

        plotLine(lineVerticies,ColorRGBA.Blue);
    }

    public void plotLine(Vector3f[] lineVerticies, ColorRGBA lineColor){
        Mesh m = new Mesh();
        m.setMode(Mesh.Mode.Lines);


        m.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(lineVerticies));

        short[] indexes=new short[2*lineVerticies.length]; //Indexes are in pairs, from a vertex and to a vertex

        for(short i=0;i<lineVerticies.length-1;i++){
            indexes[2*i]=i;
            indexes[2*i+1]=(short)(i+1);
        }

        m.setBuffer(VertexBuffer.Type.Index, 2, indexes);

        m.updateBound();
        m.updateCounts();

        Geometry geo=new Geometry("line",m);
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", lineColor);
        geo.setMaterial(mat);

        rootNode.attachChild(geo);
    }


    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
}

在此程序中,网格类型设置为

m.setMode(Mesh.Mode.Lines);

这表明网格将期望成对的索引指示哪些顶点连接到哪些(通常使用的其他选项包括m.setMode(Mesh.Mode.Triangles);,在这种情况下,它会期望三个索引的集合指示哪些顶点构成三角形)

在最基本的状态下,顶点缓冲区需要x1,y1,z1,x2,y2,z2,x3,......在一个顶点结束而另一个顶点开始的位置之间没有分界线。所以下面会将3个顶点输入缓冲区; (1.1,1.2,1.3),(2.1,2.2,2.3)和(3.1,3.2,3.3)

m.setBuffer(VertexBuffer.Type.Position, 3, new float[]{1.1, 1.2, 1.3, 2.1, 2.2, 2.3, 3.1, 3.2, 3.3});

然后索引缓冲区将连接0 - > 1 1 - > 2

 m.setBuffer(VertexBuffer.Type.Index, 2, new short[]{0, 1, 1, 2});

请注意,每个缓冲区的第二个参数表示有多少条目对应于单个“操作”,例如顶点为3D,因此参数为3,索引位于 - &gt;对,因此参数为2。

但是有一些实用方法可以使这个使用起来更加愉快,而不是输入x1,y1,z1,x2,y2,z2,x3,... BufferUtils.createFloatBuffer()方法允许你使用数组Vector3f代替,所以

m.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(lineVerticies));

其中lineVerticies的类型为Vector3f[]。然而值得注意的是,这样做有一个性能损失,如果你可以直接创建float [],它将避免不必要的转换(对于大网格尤其重要)。

m.updateBound();m.updateCounts();似乎不是确保划线的必要条件;但是如果没有它们,线路可能会被错误地剔除(当它仍然在屏幕上时,显卡可以认为它不是并且“没有费心”来渲染它)