//--------------------------------------------------------------------------------------------------------------------------------------------------- // // Copyright (C)2007 DarkWynter Studios. All rights reserved. // //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkMatterEngine.GameObjects { #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 using Globals; using ObjectLibrary; using Physics; 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 Effect aiVisionEffect; private List foundPlayers; private Mass mass; public AIVision(Mass AIMass) { mass = AIMass; // 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.graphics.GraphicsDevice.Viewport.MinDepth; AI_Vision_Viewport.MaxDepth = Statics.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.graphics.GraphicsDevice.Viewport.MinDepth; AI_Vision_FinalViewport.MaxDepth = Statics.graphics.GraphicsDevice.Viewport.MaxDepth; foundPlayers = new List(); CreatePoints(); } private void CreatePoints() { aiVisionEffect = Statics.content.Load("__Engine/ObjectLibrary/GameObjects/AIVision"); GraphicsDevice gd = Statics.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, ResourceUsage.None, ResourceManagementMode.Automatic); 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); } public List GetVisiblePlayers(ObjectLibrary objectLibrary) { // Set up Graphics Device GraphicsDevice gd = Statics.graphics.GraphicsDevice; gd.Viewport = AI_Vision_Viewport; gd.RenderState.DepthBufferEnable = true; gd.VertexDeclaration = vertexDeclaration; // Setup view and projection matrixes Matrix view = Matrix.CreateLookAt(mass.currentPosition, mass.currentPosition + mass.normalVector, mass.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.ViewProj.SetValue(view * proj); ShaderParameters.numberOfPlayers.SetValue(Statics.SystemSettings.TOTAL_PLAYERS); // Set and clear RTT texture gd.SetRenderTarget(0, renderTarget1); gd.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.TransparentBlack, 1.0f, 0); // Draw Humans for (int i = 0; i < objectLibrary.humans.Count; i++) { if (objectLibrary.humans[i].IsAlive()) { objectLibrary.humans[i].DrawAIVision(view, proj, (i + 1) / 14.0f); } } objectLibrary.terrain.DrawAIVision(new Vector2(mass.currentPosition.X / Statics.terrainScaleFactor, mass.currentPosition.Z / Statics.terrainScaleFactor)); // Gets the Rendered Texture and stores it in the RenderTarget variable gd.ResolveRenderTarget(0); Texture2D tempTex = renderTarget1.GetTexture(); aiVisionEffect.Parameters["aiVisionTexture"].SetValue(tempTex); gd.Viewport = AI_Vision_FinalViewport; gd.RenderState.DepthBufferEnable = false; // Set Points Vertex Buffer gd.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionTexture.SizeInBytes); aiVisionEffect.Parameters["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); aiVisionEffect.Parameters["ViewProj"].SetValue(view * proj); aiVisionEffect.CurrentTechnique = aiVisionEffect.Techniques["AI_Vision_TextureScan"]; aiVisionEffect.Begin(); foreach (EffectPass pass in aiVisionEffect.CurrentTechnique.Passes) { pass.Begin(); gd.VertexDeclaration = vertexDeclaration; gd.DrawPrimitives(PrimitiveType.PointList, 0, VISION_VERTEX_COUNT); pass.End(); } aiVisionEffect.End(); gd.ResolveRenderTarget(0); 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); } } gd.SetRenderTarget(0, null); return foundPlayers; } } }