Javafx:将图像应用于 meshview 不起作用
Javafx: applying image to meshview not working
我正在尝试使用 phongmaterial 将图像应用到我的 meshview 立方体,但屏幕上只显示没有颜色的黑色立方体。它曾经与 Box 和立方体一起工作,但现在也不能与它们一起工作。
还有,谁能告诉我如何获取特定立方体的面?
这是我的代码:
Rotate rxBox = new Rotate(30, 0, 0, 0, Rotate.X_AXIS);
Rotate ryBox = new Rotate(50, 0, 0, 0, Rotate.Y_AXIS);
Rotate rzBox = new Rotate(30, 0, 0, 0, Rotate.Z_AXIS);
@Override
public void start(Stage primaryStage) {
float hw = 100/2f;
float hh = 100/2f;
float hd = 100/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 tex[] = {
100, 0,
200, 0,
0, 100,
100, 100,
200, 100,
300, 100,
400, 100,
0, 200,
100, 200,
200, 200,
300, 200,
400, 200,
100, 300,
200, 300};
int faces[] = {
0, 10, 2, 5, 1, 9,
2, 5, 3, 4, 1, 9,
4, 7, 5, 8, 6, 2,
6, 2, 5, 8, 7, 3,
0, 13, 1, 9, 4, 12,
4, 12, 1, 9, 5, 8,
2, 1, 6, 0, 3, 4,
3, 4, 6, 0, 7, 3,
0, 10, 4, 11, 2, 5,
2, 5, 4, 11, 6, 6,
1, 9, 3, 4, 5, 8,
5, 8, 3, 4, 7, 3};
int[] facesSmoothingGroups = {0,0,1,1,2,2,3,3,4,4,5,5};
// URL resource = Main.class.getResource("DFv8z.png");
Image diffuseMap = new Image(Main.class.getResource("PCmIW.png").toExternalForm());
TriangleMesh mesh = new TriangleMesh();
mesh.getPoints().addAll(points);
mesh.getTexCoords().addAll(tex);
mesh.getFaces().addAll(faces);
// mesh.getFaceSmoothingGroups().addAll(facesSmoothingGroups);
Material cubeMaterial = new PhongMaterial(Color.TRANSPARENT, diffuseMap, null, null, null);
MeshView m = new MeshView(mesh);
m.getTransforms().addAll(rxBox, ryBox, rzBox);
m.setMaterial(cubeMaterial);
final Group g = new Group(m);
g.setTranslateX(400/2);
g.setTranslateY(400/2);
//g.setTranslateZ(400/2);
g.setRotationAxis(Rotate.Y_AXIS);
g.setRotationAxis(Rotate.X_AXIS);
//g.setRotationAxis(Rotate.Z_AXIS);
Scene scene = new Scene(g, 400, 400, Color.SKYBLUE);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
@Override
public void handle(MouseEvent event) {
// TODO Auto-generated method stub
}
}
你走在正确的轨道上,但你需要:
- 使用归一化纹理坐标,介于 0.0f 和 1.0f 之间
- 不要将漫反射颜色设置为透明,只需设置漫反射贴图图像即可。
第一部分,只需定义网图的总长和总高:
float L = 400f;
float H = 300f;
然后归一化纹理坐标:
float tex[] = {
100f / L, 0f / H,
200f / L, 0f / H,
0f / L, 100f / H,
100f / L, 100f / H,
200f / L, 100f / H,
300f / L, 100f / H,
400f / L, 100f / H,
0f / L, 200f / H,
100f / L, 200f / H,
200f / L, 200f / H,
300f / L, 200f / H,
400f / L, 200f / H,
100f / L, 300f / H,
200f / L, 300f / H};
对于第二部分,只需使用 setter:
PhongMaterial cubeMaterial = new PhongMaterial();
cubeMaterial.setDiffuseMap(diffuseMap);
并且你有你的纹理立方体(启用平滑组):
编辑
为了找到顶面,在任何可能的旋转之后,如果您根据网络图像和定义面的顺序定义当前颜色和法线,这可以很容易地完成:
final String[] colors = {"Blue", "Red", "White", "Yellow", "Cyan", "Green"};
float normals[] = {
1f, 0f, 0f,
-1f, 0f, 0f,
0f, 1f, 0f,
0f, -1f, 0f,
0f, 0f, 1f,
0f, 0f, -1f,
};
然后,你要跟踪顶面,对应场景坐标中的法线{0, -1, 0}
。
所以基本上你需要在网格坐标中表达法线:
Point3D normal = m.sceneToLocal(0, -1, 0);
最后,您必须将此法线与 normals
中定义的任何法线相匹配。那个的索引会给你颜色:
private String getColor(MeshView m, float[] normals) {
Point3D normal = m.sceneToLocal(0, -1, 0);
for (int i = 0; i < normals.length; i += 3) {
if (normals[i] * normal.getX() + normals[i+1] * normal.getY() + normals[i+2] * normal.getZ() > 0.99) {
return colors[i / 3];
}
}
return "no color found";
}
我正在尝试使用 phongmaterial 将图像应用到我的 meshview 立方体,但屏幕上只显示没有颜色的黑色立方体。它曾经与 Box 和立方体一起工作,但现在也不能与它们一起工作。
还有,谁能告诉我如何获取特定立方体的面?
这是我的代码:
Rotate rxBox = new Rotate(30, 0, 0, 0, Rotate.X_AXIS);
Rotate ryBox = new Rotate(50, 0, 0, 0, Rotate.Y_AXIS);
Rotate rzBox = new Rotate(30, 0, 0, 0, Rotate.Z_AXIS);
@Override
public void start(Stage primaryStage) {
float hw = 100/2f;
float hh = 100/2f;
float hd = 100/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 tex[] = {
100, 0,
200, 0,
0, 100,
100, 100,
200, 100,
300, 100,
400, 100,
0, 200,
100, 200,
200, 200,
300, 200,
400, 200,
100, 300,
200, 300};
int faces[] = {
0, 10, 2, 5, 1, 9,
2, 5, 3, 4, 1, 9,
4, 7, 5, 8, 6, 2,
6, 2, 5, 8, 7, 3,
0, 13, 1, 9, 4, 12,
4, 12, 1, 9, 5, 8,
2, 1, 6, 0, 3, 4,
3, 4, 6, 0, 7, 3,
0, 10, 4, 11, 2, 5,
2, 5, 4, 11, 6, 6,
1, 9, 3, 4, 5, 8,
5, 8, 3, 4, 7, 3};
int[] facesSmoothingGroups = {0,0,1,1,2,2,3,3,4,4,5,5};
// URL resource = Main.class.getResource("DFv8z.png");
Image diffuseMap = new Image(Main.class.getResource("PCmIW.png").toExternalForm());
TriangleMesh mesh = new TriangleMesh();
mesh.getPoints().addAll(points);
mesh.getTexCoords().addAll(tex);
mesh.getFaces().addAll(faces);
// mesh.getFaceSmoothingGroups().addAll(facesSmoothingGroups);
Material cubeMaterial = new PhongMaterial(Color.TRANSPARENT, diffuseMap, null, null, null);
MeshView m = new MeshView(mesh);
m.getTransforms().addAll(rxBox, ryBox, rzBox);
m.setMaterial(cubeMaterial);
final Group g = new Group(m);
g.setTranslateX(400/2);
g.setTranslateY(400/2);
//g.setTranslateZ(400/2);
g.setRotationAxis(Rotate.Y_AXIS);
g.setRotationAxis(Rotate.X_AXIS);
//g.setRotationAxis(Rotate.Z_AXIS);
Scene scene = new Scene(g, 400, 400, Color.SKYBLUE);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
@Override
public void handle(MouseEvent event) {
// TODO Auto-generated method stub
}
}
你走在正确的轨道上,但你需要:
- 使用归一化纹理坐标,介于 0.0f 和 1.0f 之间
- 不要将漫反射颜色设置为透明,只需设置漫反射贴图图像即可。
第一部分,只需定义网图的总长和总高:
float L = 400f;
float H = 300f;
然后归一化纹理坐标:
float tex[] = {
100f / L, 0f / H,
200f / L, 0f / H,
0f / L, 100f / H,
100f / L, 100f / H,
200f / L, 100f / H,
300f / L, 100f / H,
400f / L, 100f / H,
0f / L, 200f / H,
100f / L, 200f / H,
200f / L, 200f / H,
300f / L, 200f / H,
400f / L, 200f / H,
100f / L, 300f / H,
200f / L, 300f / H};
对于第二部分,只需使用 setter:
PhongMaterial cubeMaterial = new PhongMaterial();
cubeMaterial.setDiffuseMap(diffuseMap);
并且你有你的纹理立方体(启用平滑组):
编辑
为了找到顶面,在任何可能的旋转之后,如果您根据网络图像和定义面的顺序定义当前颜色和法线,这可以很容易地完成:
final String[] colors = {"Blue", "Red", "White", "Yellow", "Cyan", "Green"};
float normals[] = {
1f, 0f, 0f,
-1f, 0f, 0f,
0f, 1f, 0f,
0f, -1f, 0f,
0f, 0f, 1f,
0f, 0f, -1f,
};
然后,你要跟踪顶面,对应场景坐标中的法线{0, -1, 0}
。
所以基本上你需要在网格坐标中表达法线:
Point3D normal = m.sceneToLocal(0, -1, 0);
最后,您必须将此法线与 normals
中定义的任何法线相匹配。那个的索引会给你颜色:
private String getColor(MeshView m, float[] normals) {
Point3D normal = m.sceneToLocal(0, -1, 0);
for (int i = 0; i < normals.length; i += 3) {
if (normals[i] * normal.getX() + normals[i+1] * normal.getY() + normals[i+2] * normal.getZ() > 0.99) {
return colors[i / 3];
}
}
return "no color found";
}