7

モデルをレンダリングしたいのですが、特定の頂点(どのようにマークしますか?)が表示されている場合は、それらが存在する場所に2Dをレンダリングしたいと思います。

どうすればこれを行うことができますか?

4

3 に答える 3

7

まず、頂点の位置をVector4(透視投影では同次座標を使用する必要があります; set W = 1)として必要です。必要な頂点とその位置を取得する方法を知っていると仮定します。その位置はモデル空間になります。

次に、その点を投影空間に変換するだけです。つまり、World-View-Projectionマトリックスを掛けます。あれは:

Vector4 position = new Vector4(/* your position as a Vector3 */, 1);
IEffectMatrices e = /* a BasicEffect or whatever you are using to render with */
Matrix worldViewProjection = e.World * e.View * e.Projection;
Vector4 result = Vector4.Transform(position, worldViewProjection);
result /= result.W;

これで、結果は投影スペースになります。これは、画面の左下隅にある(-1、-1)と、右上隅にある(1,1)です。クライアント空間での位置を取得したい場合(これがSpriteBatch使用されます)、で使用される暗黙のView-Projection行列と一致する行列の逆行列を使用して単純に変換しSpriteBatchます。

Viewport vp = GraphicsDevice.Viewport;
Matrix invClient = Matrix.Invert(Matrix.CreateOrthographicOffCenter(0, vp.Width, vp.Height, 0, -1, 1));
Vector2 clientResult = Vector2.Transform(new Vector2(result.X, result.Y), invClient);

免責事項:私はこのコードのいずれもテストしていません。

(明らかに、特定の頂点が表示されているかどうかを確認するには、投影空間で(-1、-1)から(1,1)の範囲にあるかどうかを確認するだけです。)

于 2011-05-26T13:20:09.960 に答える
1

おそらくこれを行うための最良の方法は、を使用することBoundingFrustrumです。これは基本的に、プレーヤーのカメラの動作と同じように、特定の方向に広がる長方形のようなものです。次に、必要な特定のポイントがBoundingFrustrumに含まれているかどうかを確認し、含まれている場合は、オブジェクトをレンダリングします。

基本的に、それが作る形状は次のようになります。 BoundingFrustrumの形状

例:

// A view frustum almost always is initialized with the ViewMatrix * ProjectionMatrix
BoundingFrustum viewFrustum = new BoundingFrustum(ActivePlayer.ViewMatrix * ProjectionMatrix);

// Check every entity in the game to see if it collides with the frustum.
foreach (Entity sourceEntity in entityList)
{
    // Create a collision sphere at the entities location. Collision spheres have a
    // relative location to their entity and this translates them to a world location.
    BoundingSphere sourceSphere = new BoundingSphere(sourceEntity.Position,
                                  sourceEntity.Model.Meshes[0].BoundingSphere.Radius);

    // Checks if entity is in viewing range, if not it is not drawn
    if (viewFrustum.Intersects(sourceSphere))
        sourceEntity.Draw(gameTime);
}

この例は、実際にはゲーム内のすべてのオブジェクトをカリングするためのものですが、やりたいことを処理するように非常に簡単に変更できます。

ソースの例:http://nfostergames.com/Lessons/SimpleViewCulling.htm

世界座標を画面空間に取り込むには、Viewport.Projectを参照してください。

于 2011-05-26T13:19:43.653 に答える
1

エンジンのオクルージョンカリング機能を見てください。XNAについては、ここでフレームワークガイド(サンプル付き)を参照できます。

http://roecode.wordpress.com/2008/02/18/xna-framework-gameengine-development-part-13-occlusion-culling-and-frustum-culling/

于 2011-05-26T13:25:47.940 に答える