//--------------------------------------------------------------------------------------------------------------------------------------------------- // // Copyright (C)2007 DarkWynter Studios. All rights reserved. // //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkWynter.Stream { #region Using Statements using System; using System.Collections; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; #endregion /// /// Gpu-based AI-Vision processing class /// public class AIVision { private Viewport AI_Vision_Viewport; private int AI_ViewportSize = 256; private Viewport AI_Vision_FinalViewport; private int AI_FinalViewportSize = 5; private int AI_Vision_Vertices = 32; private int VISION_VERTEX_COUNT; private int OUTPUT_VERTEX_COUNT; // Vertex Buffer private VertexDeclaration vertexDeclaration; // Vertex Declaration private VertexBuffer vertexBuffer; private VertexPositionTexture[] vertices; private RenderTarget2D renderTarget1; private RenderTarget2D renderTarget2; private List foundPlayers; /// /// Delegate type /// /// AI's current position public delegate void AIVisionDelegate(Vector3 aiCurrentPosition); /// /// Delegate used to point to objectlibrary.DrawAIVision() /// public AIVisionDelegate DrawObjLibAIVision; //private Mass mass; /// /// Constructor /// public AIVision() { // Set up the Spatial viewport AI_Vision_Viewport.X = 0; AI_Vision_Viewport.Y = 0; AI_Vision_Viewport.Width = AI_ViewportSize; AI_Vision_Viewport.Height = AI_ViewportSize; AI_Vision_Viewport.MinDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MinDepth; AI_Vision_Viewport.MaxDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MaxDepth; AI_Vision_FinalViewport.X = 0; AI_Vision_FinalViewport.Y = 0; AI_Vision_FinalViewport.Width = AI_FinalViewportSize; AI_Vision_FinalViewport.Height = AI_FinalViewportSize; AI_Vision_FinalViewport.MinDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MinDepth; AI_Vision_FinalViewport.MaxDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MaxDepth; foundPlayers = new List(); CreatePoints(); } private void CreatePoints() { GraphicsDevice gd = Statics_Stream.RenderSettings.graphics.GraphicsDevice; VISION_VERTEX_COUNT = AI_Vision_Vertices * AI_Vision_Vertices; OUTPUT_VERTEX_COUNT = AI_FinalViewportSize * AI_FinalViewportSize; vertices = new VertexPositionTexture[VISION_VERTEX_COUNT]; vertexDeclaration = new VertexDeclaration(gd, VertexPositionTexture.VertexElements); vertexBuffer = new VertexBuffer(gd, VertexPositionTexture.SizeInBytes * VISION_VERTEX_COUNT, BufferUsage.WriteOnly); renderTarget1 = new RenderTarget2D(gd, AI_ViewportSize, AI_ViewportSize, 1, SurfaceFormat.Vector4); renderTarget2 = new RenderTarget2D(gd, AI_FinalViewportSize, AI_FinalViewportSize, 1, SurfaceFormat.Vector4); // Row by row, create a point for each pixel between 0-1 int index = 0; float pixelLength = AI_Vision_Vertices - 1.0f; for (int j = 0; j <= pixelLength; j++) { for (int i = 0; i <= pixelLength; i++) { Vector3 pPos = new Vector3(((float)i / pixelLength), ((float)j / pixelLength), 0.0f); Vector3 nPos = new Vector3(((float)i / pixelLength), ((float)j / pixelLength), 1.0f); Vector2 tPos = new Vector2(((float)i / pixelLength), ((float)j / pixelLength)); vertices[index] = new VertexPositionTexture(pPos, tPos); index++; } } // Set the data vertexBuffer.SetData(vertices); } /// /// Returns a list of points at which opponent players have been found /// /// AI's current position /// AI's normal vector /// AI's up vector /// Vector3 list of visible opponent players public List GetVisiblePlayers(Vector3 currentPosition, Vector3 normalVector, Vector3 upVector) { //return new List(); // Set up Graphics Device GraphicsDevice gd = Statics_Stream.RenderSettings.graphics.GraphicsDevice; gd.Viewport = AI_Vision_Viewport; gd.RenderState.DepthBufferEnable = true; gd.VertexDeclaration = vertexDeclaration; // Setup view and projection matrixes Matrix view = Matrix.CreateLookAt(currentPosition, currentPosition + normalVector, upVector); Matrix view1 = view; // Calculate the player's Projection Matrix Matrix proj = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4, AI_Vision_Viewport.Width / AI_Vision_Viewport.Height, 0.3f, 10000f); Matrix proj1 = proj; ShaderParameters.DrawFX.ViewProj.SetValue(view * proj); ShaderParameters.DrawFX.EyePostion.SetValue(Matrix.Invert(view)); // Set and clear RTT texture gd.SetRenderTarget(0, renderTarget1); gd.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.TransparentBlack, 1.0f, 0); // Draw Humans //objectLibrary.DrawAIVision(view, proj, new Vector2(currentPosition.X, currentPosition.Z)); DrawObjLibAIVision(currentPosition); // Gets the Rendered Texture and stores it in the RenderTarget variable gd.SetRenderTarget(0, null); Texture2D tempTex = renderTarget1.GetTexture(); ShaderParameters.AIVisionFX.aiVisionTexture.SetValue(tempTex); gd.Viewport = AI_Vision_FinalViewport; gd.RenderState.DepthBufferEnable = false; // Set Points Vertex Buffer gd.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionTexture.SizeInBytes); ShaderParameters.AIVisionFX.inverseViewProj.SetValue(Matrix.Invert(view * proj)); // Now on to scanning the texture gd.SetRenderTarget(0, renderTarget2); gd.Clear(ClearOptions.Target, Color.TransparentBlack, 1.0f, 0); Matrix world = //Matrix.CreateScale(2.0f) * // Matrix.CreateRotationY((float)Math.PI / 6.0f) * Matrix.CreateTranslation(new Vector3(0.0f, 0.5f, 0.0f)); // Setup view and projection matrixes view = Matrix.CreateLookAt(new Vector3(0.5f, 0.5f, 1.0f), new Vector3(0.5f, 0.5f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); proj = Matrix.CreateOrthographic(2.0f, 2.0f, 0, 5); ShaderParameters.AIVisionFX.ViewProj.SetValue(view * proj); ShaderParameters.AIVisionFX.effect.CurrentTechnique = ShaderParameters.AIVisionFX.effect.Techniques["AI_Vision_TextureScan"]; ShaderParameters.AIVisionFX.effect.Begin(); foreach (EffectPass pass in ShaderParameters.AIVisionFX.effect.CurrentTechnique.Passes) { pass.Begin(); gd.VertexDeclaration = vertexDeclaration; gd.DrawPrimitives(PrimitiveType.PointList, 0, VISION_VERTEX_COUNT); pass.End(); } ShaderParameters.AIVisionFX.effect.End(); //gd.ResolveRenderTarget(0); gd.SetRenderTarget(0, null); tempTex = renderTarget2.GetTexture(); Vector4[] ai_Output = new Vector4[OUTPUT_VERTEX_COUNT]; tempTex.GetData(ai_Output); foundPlayers.Clear(); for (int i = 0; i < OUTPUT_VERTEX_COUNT; i++) { if (ai_Output[i].W != 0.0f) { // The AI has seen somebody Vector3 playerPosition = gd.Viewport.Unproject(new Vector3(ai_Output[i].X, ai_Output[i].Y, ai_Output[i].Z), proj1, view1, Matrix.Identity); foundPlayers.Add(playerPosition); } } return foundPlayers; } } }