Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javafx shape3d纹理:Don';不要拉伸图像_Java_Javafx_Javafx 3d - Fatal编程技术网

javafx shape3d纹理:Don';不要拉伸图像

javafx shape3d纹理:Don';不要拉伸图像,java,javafx,javafx-3d,Java,Javafx,Javafx 3d,我现在正在使用javafx构建一个迷宫,我希望墙壁的纹理是无缝的(可以重复)。迷宫是随机生成的,所以我不知道任何墙的大小。我开始使用具有所需纹理的a,但它会扩展图像以填充整个墙(a),因此我的纹理完全拉伸。有没有办法强制材质根据需要复制纹理 代码如下: Image img = new Image(new FileInputStream("img.jpg"), 400, 400, true, false); Material mat = new PhongMaterial(Color.WHITE,

我现在正在使用javafx构建一个迷宫,我希望墙壁的纹理是无缝的(可以重复)。迷宫是随机生成的,所以我不知道任何墙的大小。我开始使用具有所需纹理的a,但它会扩展图像以填充整个墙(a),因此我的纹理完全拉伸。有没有办法强制材质根据需要复制纹理

代码如下:

Image img = new Image(new FileInputStream("img.jpg"), 400, 400, true, false);
Material mat = new PhongMaterial(Color.WHITE, img, null, null, null);
Box w = new Box(100,10,10);
w.setMaterial(mat);
像a这样的东西似乎是个好主意,但没有材料能接受它


提前感谢@fabian提到的任何帮助

不适合自定义纹理。默认情况下,设置为漫反射贴图的图像将应用于其六个面中的每一个面,并且,正如您已经发现的,这意味着它将拉伸图像以适应不同的面

使用FXyz,我们可以很容易地尝试碳纤维Kevlar。但很明显,我们必须为它选择一个尺寸。比如
100x30

虽然纹理非常适合尺寸为100x30的正面,但此图像会扭曲,以与其他面50x50和100x50的匹配方式相同

解决方案1

我们可以尝试生成自己的长方体,以便决定如何应用漫反射贴图

就顶点、面或法线而言,为长方体创建
三角形网格
很容易

棘手的部分是设置纹理坐标。在下面的代码片段中,我根据3D长方体的不同可能2D图像之一设置了它们:

public MeshView createCuboid(float w, float h, float d) {
    float hw = w / 2f;
    float hh = h / 2f;
    float hd = d / 2f;

    float points[] = {
             hw,  hh,  hd,
             hw,  hh, -hd,
             hw, -hh,  hd,
             hw, -hh, -hd,
            -hw,  hh,  hd,
            -hw,  hh, -hd,
            -hw, -hh,  hd,
            -hw, -hh, -hd};

    float L = 2 * w + 2 * d;
    float H = h + 2 * d;

    float tex[] = {
                  d / L,          0f,
            (d + w) / L,          0f,
                     0f,       d / H,
                  d / L,       d / H,
            (d + w) / L,       d / H,
        (2 * d + w) / L,       d / H,
                     1f,       d / H,
                     0f, (d + h) / H,
                  d / L, (d + h) / H,
            (d + w) / L, (d + h) / H,
         (2 *d + w) / L, (d + h) / H,
                     1f, (d + h) / H,
                  d / L,          1f,
            (d + w) / L,          1f};

    float normals[] = {
         1f,  0f,  0f,
        -1f,  0f,  0f,
         0f,  1f,  0f,
         0f, -1f,  0f,
         0f,  0f,  1f,
         0f,  0f, -1f,
    };

    int faces[] = {
            0, 0, 10, 2, 0,  5, 1, 0,  9,  
            2, 0,  5, 3, 0,  4, 1, 0,  9,  
            4, 1,  7, 5, 1,  8, 6, 1,  2,   
            6, 1,  2, 5, 1,  8, 7, 1,  3,  
            0, 2, 13, 1, 2,  9, 4, 2, 12,  
            4, 2, 12, 1, 2,  9, 5, 2,  8,  
            2, 3,  1, 6, 3,  0, 3, 3,  4,  
            3, 3,  4, 6, 3,  0, 7, 3,  3,  
            0, 4, 10, 4, 4, 11, 2, 4,  5,  
            2, 4,  5, 4, 4, 11, 6, 4,  6,  
            1, 5,  9, 3, 5,  4, 5, 5,  8,  
            5, 5,  8, 3, 5,  4, 7, 5,  3}; 

    TriangleMesh mesh = new TriangleMesh();
    mesh.setVertexFormat(VertexFormat.POINT_NORMAL_TEXCOORD);
    mesh.getPoints().addAll(points);
    mesh.getTexCoords().addAll(tex);
    mesh.getNormals().addAll(normals);
    mesh.getFaces().addAll(faces);

    return new MeshView(mesh);
}
现在我们可以生成图像,但使用净尺寸:

    @Override
public void start(Stage primaryStage) {
    MeshView box = createCuboid(100, 30, 50);
    PhongMaterial material = new PhongMaterial();
    Patterns pattern = new Patterns(300, 160);
    material.setDiffuseMap(pattern.createPattern(Patterns.CarbonPatterns.CARBON_KEVLAR, false));
    box.setMaterial(material);
    box.getTransforms().addAll(rotateX, rotateY);
    Scene scene = new Scene(new Group(box), 500, 400, true, SceneAntialiasing.BALANCED);

    primaryStage.setScene(scene);
    primaryStage.show();
}
请注意,图像不再失真

您可以调整其大小以获得更精细或更密集的图案(具有更大的图像图案)

请注意,您可以在FXyz中找到该长方体图元,以及许多其他三维图元


此外,如果图像是否拉伸取决于顶点的纹理坐标,则可以找到不同的纹理模式(密度贴图、图像、图案…

)。我怀疑是否可以为
调整此选项。您可能需要创建一个
三角形网格
,即每次需要重复纹理时插入新顶点…对于碳纤维凯夫拉之类的图案,为什么不使用仅为2x2正方形(图案的最小单位)的图像?
    @Override
public void start(Stage primaryStage) {
    MeshView box = createCuboid(100, 30, 50);
    PhongMaterial material = new PhongMaterial();
    Patterns pattern = new Patterns(300, 160);
    material.setDiffuseMap(pattern.createPattern(Patterns.CarbonPatterns.CARBON_KEVLAR, false));
    box.setMaterial(material);
    box.getTransforms().addAll(rotateX, rotateY);
    Scene scene = new Scene(new Group(box), 500, 400, true, SceneAntialiasing.BALANCED);

    primaryStage.setScene(scene);
    primaryStage.show();
}