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