我正在学习JavaFX 3D。到目前为止,我还没有找到一种方法来创建以下对象:
有人可以给我一个简短的代码示例吗?
任何帮助将不胜感激。 : - )
答案 0 :(得分:2)
我知道这是一个老问题,但我一直在努力解决类似的问题所以这里是我的截锥的解决方案:
public class Cone extends Group{
int rounds = 360;
int r1 = 100;
int r2 = 50;
int h = 100;
public Cone() {
Group cone = new Group();
PhongMaterial material = new PhongMaterial(Color.BLUE);
float[] points = new float[rounds *12];
float[] textCoords = {
0.5f, 0,
0, 1,
1, 1
};
int[] faces = new int[rounds *12];
for(int i= 0; i<rounds; i++){
int index = i*12;
//0
points[index] = (float)Math.cos(Math.toRadians(i))*r2;
points[index+1] = (float)Math.sin(Math.toRadians(i))*r2;
points[index+2] = h/2;
//1
points[index+3] = (float)Math.cos(Math.toRadians(i))*r1;
points[index+4] = (float)Math.sin(Math.toRadians(i))*r1;
points[index+5] = -h/2;
//2
points[index+6] = (float)Math.cos(Math.toRadians(i+1))*r1;
points[index+7] = (float)Math.sin(Math.toRadians(i+1))*r1;
points[index+8] = -h/2;
//3
points[index+9] = (float)Math.cos(Math.toRadians(i+1))*r2;
points[index+10] = (float)Math.sin(Math.toRadians(i+1))*r2;
points[index+11] = h/2;
}
for(int i = 0; i<rounds ; i++){
int index = i*12;
faces[index]=i*4;
faces[index+1]=0;
faces[index+2]=i*4+1;
faces[index+3]=1;
faces[index+4]=i*4+2;
faces[index+5]=2;
faces[index+6]=i*4;
faces[index+7]=0;
faces[index+8]=i*4+2;
faces[index+9]=1;
faces[index+10]=i*4+3;
faces[index+11]=2;
}
TriangleMesh mesh = new TriangleMesh();
mesh.getPoints().addAll(points);
mesh.getTexCoords().addAll(textCoords);
mesh.getFaces().addAll(faces);
Cylinder circle1 = new Cylinder(r1, 0.1);
circle1.setMaterial(material);
circle1.setTranslateZ( -h / 2);
circle1.setRotationAxis(Rotate.X_AXIS);
circle1.setRotate(90);
Cylinder circle2 = new Cylinder(r2, 0.1);
circle2.setMaterial(material);
circle2.setTranslateZ( h / 2);
circle2.setRotationAxis(Rotate.X_AXIS);
circle2.setRotate(90);
MeshView meshView = new MeshView();
meshView.setMesh(mesh);
meshView.setMaterial(material);
//meshView.setDrawMode(DrawMode.LINE);
cone.getChildren().addAll(meshView);
Rotate r1 = new Rotate(90, Rotate.X_AXIS);
cone.getTransforms().add(r1);
getChildren().addAll(cone);
}
希望这可以帮助将来的某个人!
答案 1 :(得分:0)
第一个 - 创建一个圆柱体,并使用两个不同的外观对象 - 一个用于圆柱体,侧面,一个用于两个底座。对于这两个基础,使用不可见的外观(渲染属性)。有关如何将不同外观设置为基础的信息,请设置线程: http://forum.java.sun.com/thread.jspa?threadID=663825&tstart=0
第二种 - 使用剪裁平面夹住圆筒的底部和顶部,你有一个空心圆柱。
这两种方法会给你一个空心圆柱体,内部完全是空的。
如果您正在寻找具有给定厚度的墙,则可在互联网上设置布尔操作集。创建一个大圆柱体,并减去一个较小的圆柱体。有关布尔运算集的信息,请设置此线程:http://forum.java.sun.com/thread.jspa?threadID=658612&tstart=0
最后,自己创建一个圆柱体几何体非常容易,并且可以通过循环轻松实现自动化。我将创建四个单独的几何图形:一个用于内部圆柱体,内部具有渲染面,一个用于外部圆柱体,外部具有渲染面,一个用于底部,一个圆盘在中间和底部表面具有孔渲染,一个用于顶部,另一个圆盘在中间有一个孔,顶部表面渲染。
使用三角形条带阵列可以很容易地完成所有操作。
答案 2 :(得分:0)
我开始使用此页面上其他答案中提供的代码,但我希望将其作为单个网格,两端没有圆柱体。我还计算出了更好的纹理坐标和法线。 (我使用Vecmath进行常规计算。应该将其更改为Apache Commons Math或更现代的方法...)
/**
* Create a cone shape. Origin is center of base (bottom circle). Height is along the Y axis
* @param m A given TirangleMesh
* @param res The resolution of the circles
* @param radius The base radius
* @param topRadius The top radius. If this is > 0 the cone is capped
* @param height The height of the cone along the Y axis
* @param texture The texture
*/
public static void createCone(TriangleMesh m, int res, float radius, float topRadius, float height, TextureMapping texture)
{
if (texture == null)
texture = defaultTextureMapping;
m.setVertexFormat(VertexFormat.POINT_NORMAL_TEXCOORD);
float[] v = new float[res * 6]; //vertices
float[] n = new float[(res+2)*3]; //face normals
float[] uv = new float[(res * 8) + 4]; //texture coordinates
int[] f = new int[18*(2*res-2)]; // faces ((divisions * 18) + ((divisions-2)*18))
float radPerDiv = ((float)Math.PI * 2f) / res;
int tv = res * 3; //top plane vertices start index
int tuv = (res+1) * 2; //top plane uv start index
int bcuv = tuv * 2;//(res * 4) + 4; //bottom cap uv start index
int tcuv = bcuv + (res * 2); //bottom cap uv start index
for(int i = 0; i < res; i++)
{
int vi = i*3;
float cos = (float) Math.cos(radPerDiv*(i));
float sin = (float) Math.sin(radPerDiv*(i));
//bottom plane vertices
v[vi] = cos * radius; //X
v[vi + 1] = 0; //Y
v[vi + 2] = sin * radius; //Z
//top plane vertices
v[tv + vi] = cos * topRadius; //X
v[tv + vi + 1] = height; //Y
v[tv + vi + 2] = sin * topRadius; //Z
int uvi = i*2;
//texture coordinate side down
uv[uvi] = 1f-((float)i/(float)res);
uv[uvi + 1] = 1f;
//texture coordinate side up
uv[tuv + uvi] = uv[uvi];
uv[tuv + uvi + 1] = 0;
//texture coordinate bottom cap
uv[bcuv + uvi] = (1f+cos)/2f;
uv[bcuv + uvi + 1] = (1f+sin)/2f;
//texture coordinate top cap
uv[tcuv + uvi] = (1f-cos)/2f;
uv[tcuv + uvi + 1] = (1f+sin)/2f;
//face normals
if(i>0)
{
Vector3f p0 = new Vector3f(v[vi - 3], v[vi - 2], v[vi - 1]);
Vector3f p1 = new Vector3f(v[vi], v[vi + 1], v[vi + 2]);
Vector3f p2 = new Vector3f(v[tv + vi], v[tv + vi + 1], v[tv + vi + 2]);
p1.sub(p0);
p2.sub(p0);
p0.cross(p2, p1);
p0.normalize();
n[vi - 3] = p0.x;
n[vi - 2] = p0.y;
n[vi - 1] = p0.z;
}
if(i==res-1)
{
Vector3f p0 = new Vector3f(v[vi], v[vi + 1], v[vi + 2]);
Vector3f p1 = new Vector3f(v[0], v[1], v[2]);
Vector3f p2 = new Vector3f(v[tv], v[tv + 1], v[tv + 2]);
p1.sub(p0);
p2.sub(p0);
p0.cross(p2, p1);
p0.normalize();
n[vi] = p0.x;
n[vi + 1] = p0.y;
n[vi + 2] = p0.z;
}
//faces around
int fi = i*18;
//first triangle of face
f[fi] = i; //vertex
f[fi+1] = i; //normal
f[fi+2] = i; //uv
f[fi+3] = res+i; //vertex
f[fi+4] = i; //normal
f[fi+5] = res+1+i; //uv
f[fi+6] = i+1; //vertex
f[fi+7] = i+1; //normal
f[fi+8] = i+1; //uv
//second triangle of face
f[fi+9] = i+1; //vertex
f[fi+10] = i+1; //normal
f[fi+11] = i+1; //uv
f[fi+12] = res+i; //vertex
f[fi+13] = i; //normal
f[fi+14] = res+1+i; //uv
f[fi+15] = res+i+1; //vertex
f[fi+16] = i+1; //normal
f[fi+17] = res+2+i; //uv
//wrap around, use the first vertices/normals
if(i==res-1)
{
f[fi+6] = 0; //vertex
f[fi+9] = 0; //vertex
f[fi+15] = res; //vertex
f[fi+7] = 0; //normal
f[fi+10] = 0; //normal
f[fi+16] = 0; //normal
}
//top and bottom caps
int fi2 = (i*9)+(res*18); //start index for bottom cap. Start after cone side is done
int fi3 = fi2 + (res*9) - 18; //fi2 + ((divisions - 2) * 9) //start index for top cap. Start after the bottom cap is done
int uv2 = (res*2)+2; //start index of bottom cap texture coordinate
int uv3 = (res*3)+2; //start index of top cap texture coordinate
if(i<res-2)
{
//bottom cap
f[fi2] = 0;
f[fi2+1] = res; //normal
f[fi2+2] = uv2; //uv
f[fi2+3] = i+1;
f[fi2+4] = res; //normal
f[fi2+5] = uv2 + i+1; //uv
f[fi2+6] = i+2;
f[fi2+7] = res; //normal
f[fi2+8] = uv2 + i+2; //uv
//top cap
f[fi3] = res;
f[fi3+1] = res + 1; //normal
f[fi3+2] = uv3; //uv
f[fi3+3] = res+i+2;
f[fi3+4] = res + 1; //normal
f[fi3+5] = uv3 + i+2; //uv
f[fi3+6] = res+i+1;
f[fi3+7] = res + 1; //normal
f[fi3+8] = uv3 + i+1; //uv
}
}
//smooth normals
float[] ns = new float[n.length];
Vector3f n0 = new Vector3f();
Vector3f n1 = new Vector3f();
for(int i = 0; i < res; i++)
{
int p0 = i*3;
int p1 = (i-1)*3;
if(i==0)
p1 = (res-1)*3;
n0.set(n[p0], n[p0+1], n[p0+2]);
n1.set(n[p1], n[p1+1], n[p1+2]);
n0.add(n1);
n0.normalize();
ns[p0] = n0.x;
ns[p0+1] = n0.y;
ns[p0+2] = n0.z;
}
int ni = res * 3;
ns[ni + 1] = -1; //bottom cap normal Y axis
ns[ni + 4] = 1; //top cap normal Y axis
uv[tuv-1] = 1; //bottom ring end uv coordinate
//set all data to mesh
m.getPoints().setAll(v);
m.getNormals().setAll(ns);
m.getTexCoords().setAll(uv);
m.getFaces().setAll(f);
}
编辑: 这是空心圆锥体(或圆柱体,将两个弧度都设置为相同值)的代码。在这里,我使用JavaFX向量代替Vecmath
/**
* Create a hollow cone shape. Origin is center of base (bottom circle). Height is along the Y axis
* @param m A given TirangleMesh
* @param res The resolution of the circles
* @param radius The base radius
* @param topRadius The top radius. If this is > 0 the cone is capped
* @param height The height of the cone along the Y axis
* @param thickness The thickness of the cone wall
* @param center If the origo shall be in the center, False
* @param texture The texture
*/
public static void createHollowCone(TriangleMesh m, int res, float radius, float topRadius, float height, float thickness, boolean center, TextureMapping texture)
{
if (texture == null)
texture = defaultTextureMapping;
m.setVertexFormat(VertexFormat.POINT_NORMAL_TEXCOORD);
float[] v = new float[res * 12]; //vertices
float[] n = new float[res*3]; //face normals (raw)
float[] uv = new float[(res * 24) + 8]; //texture coordinates
int[] f = new int[res*72]; // faces
float radPerDiv = ((float)Math.PI * 2f) / res;
float buvf = 1-(thickness/radius);
float tuvf = 1-(thickness/topRadius);
int otcvsi = res * 3; //outside top circle vertices start index
int ibcvsi = res * 6; //inside bottom circle vertices start index
int itcvsi = res * 9; //inside top circle vertices start index
int ifsi = res*18; //inside faces start index
int bfsi = res*36; //bottom faces start index
int tfsi = res*54; //bottom faces start index
int tuvsi = (res+1) * 2; //top plane uv start index
int bcuvsi = tuvsi * 2;//(res * 4) + 4; //bottom cap uv start index
int tcuvsi = bcuvsi + (res * 4); //bottom cap uv start index
int bcfuvsi = bcuvsi/2; //bottom cap faces uv start index
int tcfuvsi = tcuvsi/2; //top cap faces uv start index
for(int i = 0; i < res; i++)
{
int vi = i*3;
float cos = (float) Math.cos(radPerDiv*(i));
float sin = (float) Math.sin(radPerDiv*(i));
//outside bottom circle vertices
v[vi] = cos * radius; //X
v[vi + 1] = center?-height/2f:0; //Y
v[vi + 2] = sin * radius; //Z
//outside top circle vertices
v[otcvsi + vi] = cos * topRadius; //X
v[otcvsi + vi + 1] = center?height/2f:height; //Y
v[otcvsi + vi + 2] = sin * topRadius; //Z
//inside bottom circle vertices
v[ibcvsi + vi] = cos * (radius-thickness); //X
v[ibcvsi + vi + 1] = center?-height/2f:0; //Y
v[ibcvsi + vi + 2] = sin * (radius-thickness); //Z
//inside top circle vertices
v[itcvsi + vi] = cos * (topRadius-thickness); //X
v[itcvsi + vi + 1] = center?height/2f:height; //Y
v[itcvsi + vi + 2] = sin * (topRadius-thickness); //Z
int uvi = i*2;
//texture coordinate outer side down
uv[uvi] = 1f-((float)i/(float)res);
uv[uvi + 1] = 1f;
//texture coordinate outer side up
uv[tuvsi + uvi] = uv[uvi];
uv[tuvsi + uvi + 1] = 0;
//texture coordinate bottom
uv[bcuvsi + uvi] = (1f+cos)/2f;
uv[bcuvsi + uvi + 1] = (1f-sin)/2f;
uv[(res*2)+bcuvsi + uvi] = (1f+(cos*buvf))/2f;
uv[(res*2)+bcuvsi + uvi + 1] = (1f-(sin*buvf))/2f;
//texture coordinate top cap
uv[tcuvsi + uvi] = (1f+cos)/2f;
uv[tcuvsi + uvi + 1] = (1f+sin)/2f;
uv[(res*2)+tcuvsi + uvi] = (1f+(cos*tuvf))/2f;
uv[(res*2)+tcuvsi + uvi + 1] = (1f+(sin*tuvf))/2f;
//face normals
if(i>0)
{
Point3D p0 = new Point3D(v[vi - 3], v[vi - 2], v[vi - 1]);
Point3D p1 = new Point3D(v[vi], v[vi + 1], v[vi + 2]);
Point3D p2 = new Point3D(v[otcvsi + vi], v[otcvsi + vi + 1], v[otcvsi + vi + 2]);
p1 = p1.subtract(p0);
p2 = p2.subtract(p0);
p0 = p2.crossProduct(p1);
p0 = p0.normalize();
n[vi - 3] = (float)p0.getX();
n[vi - 2] = (float)p0.getY();
n[vi - 1] = (float)p0.getZ();
}
if(i==res-1)
{
Point3D p0 = new Point3D(v[vi], v[vi + 1], v[vi + 2]);
Point3D p1 = new Point3D(v[0], v[1], v[2]);
Point3D p2 = new Point3D(v[otcvsi], v[otcvsi + 1], v[otcvsi + 2]);
p1 = p1.subtract(p0);
p2 = p2.subtract(p0);
p0 = p2.crossProduct(p1);
p0 = p0.normalize();
n[vi] = (float)p0.getX();
n[vi + 1] = (float)p0.getY();
n[vi + 2] = (float)p0.getZ();
}
int fi = i*18;
//faces around outside
//first triangle of face
f[fi] = i; //vertex
f[fi+1] = i; //normal
f[fi+2] = i; //uv
f[fi+3] = res+i; //vertex
f[fi+4] = i; //normal
f[fi+5] = res+1+i; //uv
f[fi+6] = i+1; //vertex
f[fi+7] = i+1; //normal
f[fi+8] = i+1; //uv
//second triangle of face
f[fi+9] = i+1; //vertex
f[fi+10] = i+1; //normal
f[fi+11] = i+1; //uv
f[fi+12] = res+i; //vertex
f[fi+13] = i; //normal
f[fi+14] = res+1+i; //uv
f[fi+15] = res+i+1; //vertex
f[fi+16] = i+1; //normal
f[fi+17] = res+2+i; //uv
//faces around inside
//first triangle of face
f[ifsi+fi] = (res*2)+i; //vertex
f[ifsi+fi+1] = res+i; //normal
f[ifsi+fi+2] = res-i; //uv
f[ifsi+fi+3] = (res*2)+i+1; //vertex
f[ifsi+fi+4] = res+i+1; //normal
f[ifsi+fi+5] = res-1-i; //uv
f[ifsi+fi+6] = (res*3)+i; //vertex
f[ifsi+fi+7] = res+i; //normal
f[ifsi+fi+8] = res+res+1-i; //uv
//second triangle of face
f[ifsi+fi+9] = (res*2)+i+1; //vertex
f[ifsi+fi+10] = res+i+1; //normal
f[ifsi+fi+11] = res-1-i; //uv
f[ifsi+fi+12] = (res*3)+i+1; //vertex
f[ifsi+fi+13] = res+i+1; //normal
f[ifsi+fi+14] = res+res-i; //uv
f[ifsi+fi+15] = (res*3)+i; //vertex
f[ifsi+fi+16] = res+i; //normal
f[ifsi+fi+17] = res+res+1-i; //uv
//faces on bottom
//first triangle of face
f[bfsi+fi] = i; //vertex 0
f[bfsi+fi+1] = res*2; //normal
f[bfsi+fi+2] = bcfuvsi+i; //uv
f[bfsi+fi+3] = i+1; //vertex 1
f[bfsi+fi+4] = res*2; //normal
f[bfsi+fi+5] = bcfuvsi+i+1; //uv
f[bfsi+fi+6] = (res*2)+i+1; //vertex n+1
f[bfsi+fi+7] = res*2; //normal
f[bfsi+fi+8] = bcfuvsi+res+i+1; //uv
//second triangle of face
f[bfsi+fi+9] = (res*2)+i+1; //vertex n+1
f[bfsi+fi+10] = res*2; //normal
f[bfsi+fi+11] = bcfuvsi+res+i+1; //uv
f[bfsi+fi+12] = (res*2)+i; //vertex n
f[bfsi+fi+13] = res*2; //normal
f[bfsi+fi+14] = bcfuvsi+res+i; //uv
f[bfsi+fi+15] = i; //vertex 0
f[bfsi+fi+16] = res*2; //normal
f[bfsi+fi+17] = bcfuvsi+i; //uv
//faces on top
//first triangle of face
f[tfsi+fi] = res+i; //vertex 0
f[tfsi+fi+1] = res*2+1; //normal
f[tfsi+fi+2] = tcfuvsi+i; //uv
f[tfsi+fi+3] = (res*3)+i; //vertex n
f[tfsi+fi+4] = res*2+1; //normal
f[tfsi+fi+5] = tcfuvsi+res+i; //uv
f[tfsi+fi+6] = (res*3)+i+1; //vertex n+1
f[tfsi+fi+7] = res*2+1; //normal
f[tfsi+fi+8] = tcfuvsi+res+i+1; //uv
//second triangle of face
f[tfsi+fi+9] = (res*3)+i+1; //vertex n+1
f[tfsi+fi+10] = res*2+1; //normal
f[tfsi+fi+11] = tcfuvsi+res+i+1; //uv
f[tfsi+fi+12] = res+i+1; //vertex 1
f[tfsi+fi+13] = res*2+1; //normal
f[tfsi+fi+14] = tcfuvsi+i+1; //uv
f[tfsi+fi+15] = res+i; //vertex 0
f[tfsi+fi+16] = res*2+1; //normal
f[tfsi+fi+17] = tcfuvsi+i; //uv
//wrap around, use the first vertices/normals
if(i==res-1)
{
f[fi+6] = 0; //vertex
f[fi+9] = 0; //vertex
f[fi+15] = res; //vertex
f[ifsi+fi+3] = res*2; //vertex
f[ifsi+fi+9] = res*2; //vertex
f[ifsi+fi+12] = res*3; //vertex
f[bfsi+fi+3] = 0; //vertex
f[bfsi+fi+6] = res*2; //vertex
f[bfsi+fi+9] = res*2; //vertex
f[tfsi+fi+6] = res*3; //vertex
f[tfsi+fi+9] = res*3; //vertex
f[tfsi+fi+12] = res; //vertex
f[fi+7] = 0; //normal
f[fi+10] = 0; //normal
f[fi+16] = 0; //normal
f[ifsi+fi+4] = res; //normal
f[ifsi+fi+10] = res; //normal
f[ifsi+fi+13] = res; //normal
f[bfsi+fi+5] = bcfuvsi; //uv
f[bfsi+fi+8] = bcfuvsi+res; //uv
f[bfsi+fi+11] = bcfuvsi+res; //uv
f[tfsi+fi+8] = tcfuvsi+res; //uv
f[tfsi+fi+11] = tcfuvsi+res; //uv
f[tfsi+fi+14] = tcfuvsi; //uv
}
}
//smooth normals
float[] ns = new float[(n.length*2)+6];
int ni = res * 3;
for(int i = 0; i < res; i++)
{
int p0 = i*3;
int p1 = (i-1)*3;
if(i==0)
p1 = (res-1)*3;
Point3D n0 = new Point3D(n[p0], n[p0+1], n[p0+2]);
Point3D n1 = new Point3D(n[p1], n[p1+1], n[p1+2]);
n0 = n0.add(n1);
n0 = n0.normalize();
ns[p0] = (float)n0.getX();
ns[p0+1] = (float)n0.getY();
ns[p0+2] = (float)n0.getZ();
n0 = n0.multiply(-1);
ns[ni+p0] = (float)n0.getX();
ns[ni+p0+1] = (float)n0.getY();
ns[ni+p0+2] = (float)n0.getZ();
}
ni = res * 6;
ns[ni + 1] = -1; //bottom cap normal Y axis
ns[ni + 4] = 1; //top cap normal Y axis
uv[tuvsi-1] = 1; //bottom ring end uv coordinate
//set all data to mesh
m.getPoints().setAll(v);
m.getNormals().setAll(ns);
m.getTexCoords().setAll(uv);
m.getFaces().setAll(f);
}