c# xna 3d coordinate-systems

c# - Obtenga coordenadas de espacio de pantalla de verticies específicas de un modelo 3D cuando sea visible



xna coordinate-systems (3)

Me gustaría representar un modelo, entonces, si las verticidades (¿cómo las puedo marcar?) Están visibles, quiero representar algo 2D donde están.

¿Cómo voy a hacer esto?



Probablemente la mejor manera de hacerlo es con un BoundingFrustrum . Básicamente es como un rectángulo que se expande en una dirección determinada, similar a la forma en que funciona la cámara de un jugador. Luego, puede verificar si el punto dado que desea está contenido en BoundingFrustrum y, si lo está, representar su objeto.

Básicamente, la forma que tiene se ve así:

Ejemplo:

// 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); }

El ejemplo es en realidad para eliminar todos los objetos en el juego, pero se puede modificar con bastante facilidad para manejar lo que quieres hacer.

Fuente de ejemplo: http://nfostergames.com/Lessons/SimpleViewCulling.htm

Para obtener sus coordenadas mundiales en el espacio de la pantalla, eche un vistazo a Viewport.Project .


En primer lugar, necesita su posición de vértice como Vector4 (las proyecciones en perspectiva requieren el uso de coordenadas homogéneas; establezca W = 1 ). Asumiré que sabes qué vértice quieres y cómo obtener su posición. Su posición estará en el espacio modelo.

Ahora simplemente transforma ese punto en espacio de proyección. Es decir, multiplíquelo por su matriz World-View-Projection. Es decir:

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;

Ahora su resultado estará en el espacio de proyección, que es (-1, -1) en la esquina inferior izquierda de la pantalla, y (1,1) en la esquina superior derecha. Si desea obtener su posición en el espacio del cliente (que es lo que SpriteBatch usa), simplemente SpriteBatch usando la inversa de una matriz que coincida con la matriz implícita de Vista-Proyección utilizada por 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);

Descargo de responsabilidad: no he probado nada de este código.

(Obviamente, para verificar si un vértice particular es visible o no, simplemente verifique si está en el rango (-1, -1) a (1,1) en el espacio de proyección).