Saturday, May 22, 2010

Meta Description and Keywords Tags for Blogger

Meta Tags For Blogger / Blogspot has a good explanation on how to insert the meta tags in your blog.

Duplicate Meta Description and Titles Issues In Blogger assumes that you already have a meta tag inserted and explains how to prevent duplicates, so that search engines (like Google) will update the indexed site more frequently.

Monday, May 17, 2010

Save XNA mesh with Managed DirectX

There are two options you can choose:

1. You can run the code with the OptimizeInPlace() line as it is and the mesh will be saved with the texture name in the material property. The mesh will not be valid if you load it in XNA. To correct this, open the mesh file (*.x) with Deep Exploration and save it again as a mesh file (*.x) and it will work with your XNA program. Be careful when you choose the "Save As..." options in Deep Exploration.

2. You can comment out the OptimizeInPlace() and the mesh will be saved without the texture name.

// Disable the loader lock MDA.
// Debug/Exceptions (ctrl-D, E), Open the Managed Debugging Assistants tree node and uncheck Loader Lock.
// This setting is per solution so it will only affect this solution.
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

public class MeshManager
{
Device device = null;

public MeshManager()
{
PresentParameters presentParams = new PresentParameters();

presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;

System.Windows.Forms.Form renderWindow = new System.Windows.Forms.Form();

device = new Device(0, DeviceType.Hardware, renderWindow, CreateFlags.SoftwareVertexProcessing, presentParams);
}

public void SaveMesh(Microsoft.Xna.Framework.Graphics.VertexPositionNormalTexture[] verticesXna, short[] indicesXna,
int numVertices, int numFaces, string meshFilename, string textureFilename)
{
CustomVertex.PositionNormalTextured[] vertices = new CustomVertex.PositionNormalTextured[numVertices];

for (int i = 0; i < numVertices; ++i)
{
vertices[i].Position = new Vector3(verticesXna[i].Position.X, verticesXna[i].Position.Y, -verticesXna[i].Position.Z);
vertices[i].Normal = new Vector3(verticesXna[i].Normal.X, verticesXna[i].Normal.Y, -verticesXna[i].Normal.Z);
vertices[i].Tu = verticesXna[i].TextureCoordinate.X;
vertices[i].Tv = verticesXna[i].TextureCoordinate.Y;
}

short[] indices = new short[numFaces * 3];

for (int i = 0; i < numFaces * 3; i += 3)
{
indices[i + 0] = indicesXna[i + 0];
indices[i + 1] = indicesXna[i + 1];
indices[i + 2] = indicesXna[i + 2];
}

Mesh mesh = new Mesh(numFaces, numVertices, MeshFlags.Managed, CustomVertex.PositionNormalTextured.Format, device);

mesh.SetVertexBufferData(vertices, LockFlags.None);
mesh.SetIndexBufferData(indices, LockFlags.None);

int[] adjac = new int[mesh.NumberFaces * 3];
mesh.GenerateAdjacency(0.05f, adjac);
// Comment the next line to save a valid mesh. Material will not be saved.
mesh.OptimizeInPlace(MeshFlags.OptimizeVertexCache, adjac);

int subs = mesh.GetAttributeTable().Length;
ExtendedMaterial[] extmat = new ExtendedMaterial[subs];

Material material = new Material();
material.AmbientColor = new ColorValue(1.0f, 1.0f, 1.0f);
material.DiffuseColor = new ColorValue(1.0f, 1.0f, 1.0f);
material.EmissiveColor = new ColorValue(0.1f, 0.1f, 0.1f);
material.SpecularColor = new ColorValue(0.1f, 0.1f, 0.1f);
material.SpecularSharpness = 64.0f;

for (int i = 0; i < subs; i++)
{
extmat[i] = new ExtendedMaterial();
extmat[i].Material3D = material;
extmat[i].TextureFilename = textureFilename;
}

mesh.Save(meshFilename, adjac, extmat, XFileFormat.Text);
}
}

XNA Split screen on 4 Viewports


private Viewport[] _viewports = new Viewport[5];

private void SetupViewports()
{
int HalfWidth = this._GraphicsDeviceManager.PreferredBackBufferWidth / 2;
int HalfHeight = this._GraphicsDeviceManager.PreferredBackBufferHeight / 2;

// full screen viewport for full screen text:
_viewports[0] = new Viewport();
_viewports[0].X = 0;
_viewports[0].Y = 0;
_viewports[0].Width = 2 * HalfWidth;
_viewports[0].Height = 2 * HalfHeight;

// 1/4 screen viewports:
_viewports[1] = new Viewport();
_viewports[1].X = 0;
_viewports[1].Y = 0;
_viewports[1].Width = HalfWidth;
_viewports[1].Height = HalfHeight;

_viewports[2] = new Viewport();
_viewports[2].X = HalfWidth;
_viewports[2].Y = 0;
_viewports[2].Width = HalfWidth;
_viewports[2].Height = HalfHeight;

_viewports[3] = new Viewport();
_viewports[3].X = 0;
_viewports[3].Y = HalfHeight;
_viewports[3].Width = HalfWidth;
_viewports[3].Height = HalfHeight;

_viewports[4] = new Viewport();
_viewports[4].X = HalfWidth;
_viewports[4].Y = HalfHeight;
_viewports[4].Width = HalfWidth;
_viewports[4].Height = HalfHeight;
}

public void DrawScene()
{
for (int i = 0; i < 4; ++i)
{
_GraphicsDevice.Viewport = _viewports[i + 1];
// TODO: set view and projection matrix
// TODO: draw viewport
}

_GraphicsDevice.Viewport = _viewports[0];
// TODO: set view and projection matrix
// TODO: draw full screen text
}

Sunday, May 16, 2010

C# Object Serialization to XML file


public class XmlSerializationManager
{
public static void SaveObjectToXmlFile(String path, Object _object, Type _type)
{
FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write);

XmlSerializer serializer = new XmlSerializer(_type);
serializer.Serialize(stream, _object);

stream.Close();
}

public static void SaveObjectToXmlFile(String path, Object _object, Type _type, Type[] extraTypes)
{
FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write);

XmlSerializer serializer = new XmlSerializer(_type, extraTypes);
serializer.Serialize(stream, _object);

stream.Close();
}

public static Object LoadObjectFromXmlFile(String path, Type _type)
{
if (!File.Exists(path))
{
return null;
}

FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read);

if (stream.Length == 0)
{
return null;
}

XmlSerializer serializer = new XmlSerializer(_type);
Object _object = serializer.Deserialize(stream);

stream.Close();

return _object;
}

public static Object LoadObjectFromXmlFile(String path, Type _type, Type[] extraTypes)
{
if (!File.Exists(path))
{
return null;
}

FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read);

if (stream.Length == 0)
{
return null;
}

XmlSerializer serializer = new XmlSerializer(_type, extraTypes);
Object _object = serializer.Deserialize(stream);

stream.Close();

return _object;
}
}

C# Logger - Write strings to log file


public class Logger
{
public static bool _doLog = true;

public static void Log(String filename, String Message)
{
if (!_doLog)
return;

if (File.Exists(filename))
{
using (StreamWriter sw = File.AppendText(filename))
{
sw.WriteLine(String.Format("{0} : {1}", DateTime.Now, Message));
sw.Close();
}
}
else
{
using (StreamWriter sw = File.CreateText(filename))
{
sw.WriteLine(String.Format("{0} : {1}", DateTime.Now, Message));
sw.Close();
}
}
}
}

Saturday, May 15, 2010

XNA Set Graphics Mode


public bool SetGraphicsMode(int Width, int Height, bool isFullScreen)
{
// If we aren't using a full screen mode, the height and width of the window can
// be set to anything equal to or smaller than the actual screen size.
if (isFullScreen == false)
{
if ((Width <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width)
&& (Height <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height))
{
_GraphicsDeviceManager.PreferredBackBufferWidth = Width;
_GraphicsDeviceManager.PreferredBackBufferHeight = Height;
_GraphicsDeviceManager.IsFullScreen = isFullScreen;
_GraphicsDeviceManager.ApplyChanges();

return true;
}
}
else
{
// If we are using full screen mode, we should check to make sure that the display
// adapter can handle the video mode we are trying to set. To do this, we will
// iterate thorugh the display modes supported by the adapter and check them against
// the mode we want to set.
foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
{
// Check the width and height of each mode against the passed values
if ((dm.Width == Width) && (dm.Height == Height))
{
// The mode is supported, so set the buffer formats, apply changes and return
_GraphicsDeviceManager.PreferredBackBufferWidth = Width;
_GraphicsDeviceManager.PreferredBackBufferHeight = Height;
_GraphicsDeviceManager.IsFullScreen = isFullScreen;
_GraphicsDeviceManager.ApplyChanges();

return true;
}
}
}
return false;
}

XNA Get Model vertices for BoundingBox

Friday, May 14, 2010

XNA Pick model triangle with ray

You can find GetMouseCursorRay and RayIntersectTriangle on this blog.

public bool PickedTriangle(Ray cursorRay, ref Vector3 intersection, ref float distance, ref int[] triangle)
{
float pickDist = 0.0f; // distance from ray origin to intersection
float pickU = 0.0f; // barycentric coordinate of intersection
float pickV = 0.0f; // barycentric coordinate of intersection

for (int i = 0; i < (this._IndicesCount / 3); ++i)
{
// changed from left handed (DirectX) to right handed (XNA)
Vector3 tri0 = this._transformedVertices[this._Indices[3 * i + 0]];
Vector3 tri1 = this._transformedVertices[this._Indices[3 * i + 2]];
Vector3 tri2 = this._transformedVertices[this._Indices[3 * i + 1]];

// Check if the pick ray passes through this point
if (RayIntersectTriangle(cursorRay.Position, cursorRay.Direction, tri0, tri1, tri2, ref pickDist, ref pickU, ref pickV))
{
if (pickDist > 0.0f)
{
intersection = pickU * tri1 + pickV * tri2 + (1 - pickU - pickV) * tri0;
distance = pickDist;

triangle[0] = 3 * i + 0;
triangle[1] = 3 * i + 2;
triangle[2] = 3 * i + 1;

return true;
}
}
}

return false;
}

XNA Get mouse cursor ray


public Ray GetMouseCursorRay(MouseState _CurrentMouseState, Matrix _projectionMatrix, Matrix _viewMatrix)
{
// Create 2 positions in screenspace using the cursor position.
// 0 is as close as possible to the camera, 1 is as far away as possible.
Vector3 nearSource = new Vector3(_CurrentMouseState.X, _CurrentMouseState.Y, 0.0f);
Vector3 farSource = new Vector3(_CurrentMouseState.X, _CurrentMouseState.Y, 1.0f);

// Use Viewport. Unproject to tell what those two screen space positions would be in world space.
// We'll need the projection matrix and view matrix, which we have saved as member variables.
// We also need a world matrix, which can just be identity.
Vector3 nearPoint = _GraphicsDevice.Viewport.Unproject(nearSource, _projectionMatrix, _viewMatrix, Matrix.Identity);
Vector3 farPoint = _GraphicsDevice.Viewport.Unproject(farSource, _projectionMatrix, _viewMatrix, Matrix.Identity);

// Find the direction vector that goes from the nearPoint to the farPoint and normalize it...
Vector3 direction = farPoint - nearPoint;
direction.Normalize();

// ... and then create a new ray using nearPoint as the source.
return new Ray(nearPoint, direction);
}

XNA Ray Intersect Triangle

private bool RayIntersectTriangle(Vector3 rayPosition, Vector3 rayDirection, Vector3 tri0, Vector3 tri1, Vector3 tri2, 
 ref float pickDistance, ref float barycentricU, ref float barycentricV)
{
 // Find vectors for two edges sharing vert0
 Vector3 edge1 = tri1 - tri0;
 Vector3 edge2 = tri2 - tri0;

 // Begin calculating determinant - also used to calculate barycentricU parameter
 Vector3 pvec = Vector3.Cross(rayDirection, edge2);

 // If determinant is near zero, ray lies in plane of triangle
 float det = Vector3.Dot(edge1, pvec);
 if (det < 0.0001f)
  return false;

 // Calculate distance from vert0 to ray origin
 Vector3 tvec = rayPosition - tri0;

 // Calculate barycentricU parameter and test bounds
 barycentricU = Vector3.Dot(tvec, pvec);
 if (barycentricU < 0.0f || barycentricU > det)
  return false;

 // Prepare to test barycentricV parameter
 Vector3 qvec = Vector3.Cross(tvec, edge1);

 // Calculate barycentricV parameter and test bounds
 barycentricV = Vector3.Dot(rayDirection, qvec);
 if (barycentricV < 0.0f || barycentricU + barycentricV > det)
  return false;

 // Calculate pickDistance, scale parameters, ray intersects triangle
 pickDistance = Vector3.Dot(edge2, qvec);
 float fInvDet = 1.0f / det;
 pickDistance *= fInvDet;
 barycentricU *= fInvDet;
 barycentricV *= fInvDet;

 return true;
}

Thursday, May 13, 2010

XNA Restore SpriteBatch changes on GraphicsDevice

Restore SpriteBatch changes of RenderState and SamplerStates on GraphicsDevice to default:

public void SetGraphicsDeviceStates()
{
// SpriteBatch changes:
//_graphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
//_graphicsDevice.RenderState.DepthBufferEnable = false;
//_graphicsDevice.RenderState.AlphaBlendEnable = true;
//_graphicsDevice.RenderState.AlphaBlendOperation = BlendFunction.Add;
//_graphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
//_graphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
//_graphicsDevice.RenderState.SeparateAlphaBlendEnabled = false;
//_graphicsDevice.RenderState.AlphaTestEnable = true;
//_graphicsDevice.RenderState.AlphaFunction = CompareFunction.Greater;
//_graphicsDevice.RenderState.ReferenceAlpha = 0;
//_graphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Clamp;
//_graphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Clamp;
//_graphicsDevice.SamplerStates[0].MagFilter = TextureFilter.Linear;
//_graphicsDevice.SamplerStates[0].MinFilter = TextureFilter.Linear;
//_graphicsDevice.SamplerStates[0].MipFilter = TextureFilter.Linear;
//_graphicsDevice.SamplerStates[0].MipMapLevelOfDetailBias = 0.0f;
//_graphicsDevice.SamplerStates[0].MaxMipLevel = 0;

// Correct SpriteBatch changes:
_graphicsDevice.RenderState.DepthBufferEnable = true;
_graphicsDevice.RenderState.AlphaBlendEnable = false;

_graphicsDevice.RenderState.SourceBlend = Blend.One;
_graphicsDevice.RenderState.DestinationBlend = Blend.Zero;

_graphicsDevice.RenderState.AlphaTestEnable = false;
_graphicsDevice.RenderState.AlphaFunction = CompareFunction.Always;

_graphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap;
_graphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap;
_graphicsDevice.SamplerStates[0].MagFilter = TextureFilter.Point;
_graphicsDevice.SamplerStates[0].MinFilter = TextureFilter.Point;
_graphicsDevice.SamplerStates[0].MipFilter = TextureFilter.None;
}

XNA bool IsSpecialKey(Keys key)


public bool IsSpecialKey(Keys key)
{
// All keys except A-Z, 0-9 and `-\[];',./= (and space) are special keys.
// With shift pressed this also results in this keys:
// ~_|{}:"<>? !@#$%^&*().

int keyNum = (int)key;

if ((keyNum >= (int)Keys.A && keyNum <= (int)Keys.Z) ||
(keyNum >= (int)Keys.D0 && keyNum <= (int)Keys.D9) ||
key == Keys.Space || // well, space ^^
key == Keys.OemTilde || // `~
key == Keys.OemMinus || // -_
key == Keys.OemPipe || // \|
key == Keys.OemOpenBrackets || // [{
key == Keys.OemCloseBrackets || // ]}
key == Keys.OemQuotes || // '"
key == Keys.OemQuestion || // /?
key == Keys.OemPlus) // =+
{
return false;
}

return true;
}

Wednesday, May 12, 2010

XNA Camera Direction from Orientation


_cameraDirection = new Vector3((float)Math.Sin(_cameraAngle.Y) * (float)Math.Cos(_cameraAngle.X),
-(float)Math.Sin(_cameraAngle.X),
(float)Math.Cos(_cameraAngle.Y) * (float)Math.Cos(_cameraAngle.X));

Forward vector from euler angles:

public Vector3 _Forward
{
get
{
return new Vector3((float)Math.Sin(_orientation.Y) * (float)Math.Cos(_orientation.X),
-(float)Math.Sin(_orientation.X),
(float)Math.Cos(_orientation.Y) * (float)Math.Cos(_orientation.X));
}
}

Visual Studio Find and Replace

Look at these file types:

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Find\Filter

Tuesday, May 11, 2010

Reposition a console window in C++


void RePositionWindow(int x, int y)
{
HWND windowHandle = GetConsoleWindow();
RECT rect;
GetWindowRect(windowHandle, &rect);
MoveWindow(windowHandle, x, y, rect.right - rect.left, rect.bottom - rect.top, true);
}

C++ version of C# Random.Next(int minValue, int maxValue);


int Random(int min, int max)
{
return (int)((double)rand() / ((double)RAND_MAX + 1.0) * (double)(max - min) + (double)min);
}

XNA Random Point On Plane

This method generates random points in a circle with a specified radius. The circle lies on a plane defined with a position and a normal. The generated points have an uniform distribution.

Random _random = new Random();

private Vector3 RandomPointOnPlane(Vector3 position, Vector3 normal, float radius)
{
Vector3 random = new Vector3();
Vector3 randomPoint;

do
{
random.X = 2.0f * (float)_random.NextDouble() - 1.0f;
random.Y = 2.0f * (float)_random.NextDouble() - 1.0f;
random.Z = 2.0f * (float)_random.NextDouble() - 1.0f;
Vector3.Cross(ref random, ref normal, out randomPoint);
} while (randomPoint == Vector3.Zero);

randomPoint.Normalize();
randomPoint *= radius * (float)Math.Sqrt(_random.NextDouble());
randomPoint += position;

return randomPoint;
}

Code syntax highlighting

Awesome code syntax highlighting made easy has instructions on how to use SyntaxHighlighter on Blogger.

Monday, May 10, 2010

XNA Random Point In Circle

The function creates a random point in a circle on the XZ plane.

Random _random = new Random();

private Vector3 RandomPointInCircle(Vector3 position, float radius)
{
float randomRadius = radius * (float)Math.Sqrt(_random.NextDouble());

double randomAngle = _random.NextDouble() * MathHelper.TwoPi;

float x = randomRadius * (float)Math.Cos(randomAngle);
float z = randomRadius * (float)Math.Sin(randomAngle);

return new Vector3(position.X + x, position.Y, position.Z + z);
}