Search code examples
javatexturesjava-3d

Java3D 1.5.1 - How to place different textures on Box parts?


I am trying to place different textures on sides of a Box, but without any success.

Here is my code:

BufferedImage texture1 =  ...; // brown image
BufferedImage texture2 =  ...; // green image

Box box = new Box(1f, 1f, 1f, Box.GENERATE_TEXTURE_COORDS, new Appearance());

TextureAttributes ta = new TextureAttributes();
ta.setTextureMode(TextureAttributes.MODULATE);

Appearance app = new Appearance();
app.setTexCoordGeneration(new TexCoordGeneration(TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2));
app.setTexture(new TextureLoader(texture1).getTexture());
app.setTextureAttributes(ta);
box.setAppearance(Box.TOP, app);

Appearance app2 = new Appearance();
app2.setTexCoordGeneration(new TexCoordGeneration(TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2));
app2.setTexture(new TextureLoader(texture2).getTexture());
app2.setTextureAttributes(ta);
box.setAppearance(Box.RIGHT, app2);

Result:

Generated box

Well, it places the images on both sides, but as you can see, they are blured.

I thought it could be caused by wrong TexCoordGeneration applied to the appearance of sides. But I am also not sure if I create the Box instance with correct parameters.

How should I fix this?

Thank you very much for answers!


Solution

  • OK I fixed that by generating my own TexCoordGeneration object with Vector4f objects.

    Code:

    app.setTexCoordGeneration(this.generateTexCoord(box.getShape(Box.TOP)));
    

    and the method generateTexCoord():

    private TexCoordGeneration generateTexCoord(Shape3D shape) {
        BoundingBox bb = new BoundingBox(shape.getBounds());
        Point3d lower = new Point3d();
        Point3d upper = new Point3d();
        bb.getLower(lower);
        bb.getUpper(upper);
    
        double width = upper.x - lower.x;
        double height = upper.y - lower.y;
        double deep = upper.z - lower.z;
        Vector4f planeX = new Vector4f((float)(1.0/width), 0.0f, 0.0f, (float)(-lower.x/width));
        Vector4f planeY = new Vector4f(0.0f, (float)(1.0/height), 0.0f, (float)(-lower.y/height));
        Vector4f planeZ = new Vector4f(0.0f, 0.0f, (float)(1.0/deep), (float)(-lower.z/deep));
    
        TexCoordGeneration tcg = new TexCoordGeneration(TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2);
        if(width == 0) { // RIGHT, LEFT: YZ
            tcg.setPlaneS(planeZ);
            tcg.setPlaneT(planeY);
        } else if(height == 0) { // TOP, BOTTOM: XZ
            tcg.setPlaneS(planeX);
            tcg.setPlaneT(planeZ);
        } else { // FRONT, BACK: XY
            tcg.setPlaneS(planeX);
            tcg.setPlaneT(planeY);
        }
        return tcg;
    }
    

    Hope that helped someone with same problem. :)