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