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

因此,例如,如果我要尝试绘制以下内容:
(2,0,0)
(-1,0,1)
(0,1,1)
(1,1,1)
(1,4,0​​)

然后我会得到:

最佳答案

更新

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

原始答案

JMonkey中的线是使用自定义网格创建的,将顶点作为浮动对象的位置缓冲区,将索引(顶点与之相连的顶点)作为短裤的缓冲区,将其赋予自定义网格。这个答案是基于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,索引是从->到对,因此参数是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();似乎对于确保画线不是必需的;但是,如果没有它们,则该线可能会被错误地剔除(当它仍在屏幕上时,图形卡会认为它不是,并且“不必费心”渲染它)

09-27 08:33