モデルをレンダリングしたいのですが、特定の頂点(どのようにマークしますか?)が表示されている場合は、それらが存在する場所に2Dをレンダリングしたいと思います。
どうすればこれを行うことができますか?
モデルをレンダリングしたいのですが、特定の頂点(どのようにマークしますか?)が表示されている場合は、それらが存在する場所に2Dをレンダリングしたいと思います。
どうすればこれを行うことができますか?
まず、頂点の位置を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)の範囲にあるかどうかを確認するだけです。)
おそらくこれを行うための最良の方法は、を使用すること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を参照してください。
エンジンのオクルージョンカリング機能を見てください。XNAについては、ここでフレームワークガイド(サンプル付き)を参照できます。