1

renderscript で円柱を作ろうとしています。これは私が試したコードです:

public Mesh cylinder(){
    float radius=1.25f, halfLength=5;
    int slices=16;

    Mesh.TriangleMeshBuilder mbo= new TriangleMeshBuilder(mRSGL,3, Mesh.TriangleMeshBuilder.TEXTURE_0);
    for(int i=0; i<slices; i++) {
    float theta = (float) (((float)i)*2.0*Math.PI);
    float nextTheta = (float) (((float)i+1)*2.0*Math.PI);

        /*vertex at middle of end*/
    mbo.addVertex(0.0f, halfLength, 0.0f);

        /*vertices at edges of circle*/
    mbo.addVertex((float)(radius*Math.cos(theta)), halfLength, (float)(radius*Math.sin(theta)));
        mbo.addVertex((float)(radius*Math.cos(nextTheta)), halfLength, (float)(radius*Math.sin(nextTheta)));

        /* the same vertices at the bottom of the cylinder*/

    mbo.addVertex((float)(radius*Math.cos(nextTheta)), -halfLength, (float)(radius*Math.sin(nextTheta)));
    mbo.addVertex((float)(radius*Math.cos(theta)), halfLength, (float)(radius*Math.sin(theta)));
    mbo.addVertex(0.0f, -halfLength, 0.0f);

    mbo.addTriangle(0, 1, 2);
    mbo.addTriangle(3, 4, 5);


}
    return mbo.create(true);

}

しかし、このコードでは長さ 5 の長方形が得られます。どこが間違っているのでしょうか?

4

1 に答える 1

2

ここで実際にいくつかの問題があります。まず、角度は常に 2pi の倍数に等しくなります。角度を計算するときは、セクター数で割る必要があります。さらに、このステップでは不要な明示的な型変換があります。Java が整数から倍精度への変換を処理します。

次に、同じ 2 つの三角形を常にメッシュに追加し、円柱の側面には三角形を追加せず、2 つの端面だけを追加します。addTriangle() を呼び出すときのループでは、addTriangle(n, n+1, n+2) などのインデックスを使用する必要があります。

最後に、4 番目の頂点を作成したときにマイナス記号が欠けていたため、実際には -halfLength ではなく、halfLength でした。

これを試して:

public Mesh cylinder(){
    float radius=1.25f, halfLength=5;
    int slices=16;

    Mesh.TriangleMeshBuilder mbo= new TriangleMeshBuilder(mRSGL,3, Mesh.TriangleMeshBuilder.TEXTURE_0);

    /*vertex at middle of end*/
    mbo.addVertex(0.0f, halfLength, 0.0f);
    mbo.addVertex(0.0f, -halfLength, 0.0f);

    for(int i=0; i<slices; i++) {
         float theta = (float) (i*2.0*Math.PI / slices);
         float nextTheta = (float) ((i+1)*2.0*Math.PI / slices);

         /*vertices at edges of circle*/
         mbo.addVertex((float)(radius*Math.cos(theta)), halfLength, (float)(radius*Math.sin(theta)));
         mbo.addVertex((float)(radius*Math.cos(nextTheta)), halfLength, (float)(radius*Math.sin(nextTheta)));

         /* the same vertices at the bottom of the cylinder*/
         mbo.addVertex((float)(radius*Math.cos(nextTheta)), -halfLength, (float)(radius*Math.sin(nextTheta)));
         mbo.addVertex((float)(radius*Math.cos(theta)), -halfLength, (float)(radius*Math.sin(theta)));

         /*Add the faces for the ends, ordered for back face culling*/
         mbo.addTriangle(4*i+3, 4*i+2, 0); 
         //The offsets here are to adjust for the first two indices being the center points. The sector number (i) is multiplied by 4 because the way you are building this mesh, there are 4 vertices added with each sector
         mbo.addTriangle(4*i+5, 4*i+4, 1);
         /*Add the faces for the side*/
         mbo.addTriangle(4*i+2, 4*i+4, 4*i+5); 
         mbo.addTriangle(4*i+4, 4*i+2, 4*i+3);
    }
return mbo.create(true);

}

また、円の中心の頂点を 1 回だけ作成してメモリを節約する、わずかな最適化も追加しました。ここでのインデックスの順序は、背面カリング用です。正面にしたい場合は裏返してください。最終的により効率的な方法が必要になる場合は、割り当てビルダーで trifans と tristrips を使用できますが、この複雑なメッシュの場合は、三角形メッシュの使いやすさがメリットになります。このコードを自分のシステムで実行して、動作することを確認しました。

于 2012-05-24T14:50:01.047 に答える