Erasor

Ok so i followed http://www.riemers.net/eng/Tutorials/XNA/Csharp/series4.php

And now i want to find out ot to load a model (For example a human)

on to the terrain and able to walk with it, and having the camera behind the person.

So is there any sites that can teach me it

Or is there anyone here that an post the code

(p.s. I tryed to follow riemer's but i could'nt understand it)

And here's the code i got from following his tutorial:

(Yes- I know it's hard to read. But i could'nt get it be easier

Code Snippet

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.IO;

namespace Terrain
{
public class Game1 : Microsoft.Xna.Framework.Game
{
public struct VertexMultitextured
{
public Vector3 Position;
public Vector3 Normal;
public Vector4 TextureCoordinate;
public Vector4 TexWeights;

public static int SizeInBytes = (3 + 3 + 4 + 4) * 4;
public static VertexElement[] VertexElements = new VertexElement[]
{
new VertexElement( 0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0 ),
new VertexElement( 0, sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Normal, 0 ),
new VertexElement( 0, sizeof(float) * 6, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 0 ),
new VertexElement( 0, sizeof(float) * 10, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 1 ),
};
}

private GraphicsDeviceManager graphics;
private ContentManager content;
private GraphicsDevice device;
private Effect effect;
private VertexBuffer terrainVertexBuffer;
private IndexBuffer terrainIndexBuffer;
Texture2D heightMap;
private int WIDTH;
private int HEIGHT;
private float[,] heightData;
private Matrix viewMatrix;
private Matrix projectionMatrix;
private Vector3 cameraPosition = new Vector3(130, 50, 30);
private Vector3 cameraAngles = new Vector3(-MathHelper.Pi / 10.0f, 0, MathHelper.PiOver2);
private MouseState previousMouseState;
private Texture2D sandTexture;
private Texture2D grassTexture;
private Texture2D rockTexture;
private Texture2D snowTexture;
private Model skyDome;
private Texture2D skyDomeTexture;
private RenderTarget2D refractionRenderTarg;
private Texture2D refractionMap;
private RenderTarget2D reflectionRenderTarg;
private Texture2D reflectionMap;
private float waterHeight = 5.0f;
private Matrix reflectionViewMatrix;
private VertexPositionTexture[] waterVertices;
private Texture2D waterBumpMap;
private float elapsedTime;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
}

protected override void Initialize()
{
base.Initialize();
LoadHeightData();

SetUpTerrainVertices();
SetUpTerrainIndices();
SetInitialValues();
SetUpWaterVertices();
}

private void SetInitialValues()
{
Mouse.SetPosition(Window.ClientBounds.Width / 2, Window.ClientBounds.Height / 2);
previousMouseState = Mouse.GetState();

refractionRenderTarg = new RenderTarget2D(device, 512, 512, 1, SurfaceFormat.Color);
reflectionRenderTarg = new RenderTarget2D(device, 512, 512, 1, SurfaceFormat.Color);
}

private void SetUpXNADevice()
{
device = graphics.GraphicsDevice;

graphics.PreferredBackBufferWidth = 500;
graphics.PreferredBackBufferHeight = 500;
graphics.IsFullScreen = false;
graphics.ApplyChanges();
Window.Title = "Julian's Beste";


effect = content.Load<Effect>("Series4Effects");
}

private void SetUpTerrainVertices()
{
VertexMultitextured[] terrainVertices = new VertexMultitextured[WIDTH * HEIGHT];

for (int x = 0; x < WIDTH; x++)
for (int y = 0; y < HEIGHT; y++)
{
terrainVertices[x + y * WIDTH].Position = new Vector3(x, y, heightData[x, y]);
terrainVertices[x + y * WIDTH].Normal = new Vector3(0, 0, 1);
terrainVertices[x + y * WIDTH].TextureCoordinate.X = (float)x / 30.0f;
terrainVertices[x + y * WIDTH].TextureCoordinate.Y = (float)y / 30.0f;

terrainVertices[x + y * WIDTH].TexWeights.X = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 0) / 8.0f, 0, 1);
terrainVertices[x + y * WIDTH].TexWeights.Y = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 12) / 6.0f, 0, 1);
terrainVertices[x + y * WIDTH].TexWeights.Z = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 20) / 6.0f, 0, 1);
terrainVertices[x + y * WIDTH].TexWeights.W = MathHelper.Clamp(1.0f - Math.Abs(heightData[x, y] - 30) / 6.0f, 0, 1);

float totalWeight = terrainVertices[x + y * WIDTH].TexWeights.X;
totalWeight += terrainVertices[x + y * WIDTH].TexWeights.Y;
totalWeight += terrainVertices[x + y * WIDTH].TexWeights.Z;
totalWeight += terrainVertices[x + y * WIDTH].TexWeights.W;
terrainVertices[x + y * WIDTH].TexWeights.X /= totalWeight;
terrainVertices[x + y * WIDTH].TexWeights.Y /= totalWeight;
terrainVertices[x + y * WIDTH].TexWeights.Z /= totalWeight;
terrainVertices[x + y * WIDTH].TexWeights.W /= totalWeight;
}

for (int x = 1; x < WIDTH - 1; x++)
{
for (int y = 1; y < HEIGHT - 1; y++)
{
Vector3 normX = new Vector3((terrainVertices[x - 1 + y * WIDTH].Position.Z - terrainVertices[x + 1 + y * WIDTH].Position.Z) / 2, 0, 1);
Vector3 normY = new Vector3(0, (terrainVertices[x + (y - 1) * WIDTH].Position.Z - terrainVertices[x + (y + 1) * WIDTH].Position.Z) / 2, 1);
terrainVertices[x + y * WIDTH].Normal = normX + normY;
terrainVertices[x + y * WIDTH].Normal.Normalize();
}
}

terrainVertexBuffer = new VertexBuffer(device, VertexMultitextured.SizeInBytes * WIDTH * HEIGHT, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
terrainVertexBuffer.SetData(terrainVertices);
}

private void SetUpTerrainIndices()
{
int[] terrainIndices = new int[(WIDTH - 1) * (HEIGHT - 1) * 6];
for (int x = 0; x < WIDTH - 1; x++)
{
for (int y = 0; y < HEIGHT - 1; y++)
{
terrainIndices[(x + y * (WIDTH - 1)) * 6] = (x + 1) + (y + 1) * WIDTH;
terrainIndices[(x + y * (WIDTH - 1)) * 6 + 1] = (x + 1) + y * WIDTH;
terrainIndices[(x + y * (WIDTH - 1)) * 6 + 2] = x + y * WIDTH;

terrainIndices[(x + y * (WIDTH - 1)) * 6 + 3] = (x + 1) + (y + 1) * WIDTH;
terrainIndices[(x + y * (WIDTH - 1)) * 6 + 4] = x + y * WIDTH;
terrainIndices[(x + y * (WIDTH - 1)) * 6 + 5] = x + (y + 1) * WIDTH;
}
}

terrainIndexBuffer = new IndexBuffer(device, typeof(int), (WIDTH - 1) * (HEIGHT - 1) * 6, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
terrainIndexBuffer.SetData(terrainIndices);
}

private void LoadHeightData()
{
float minimumHeight = 255;
float maximumHeight = 0;

WIDTH = heightMap.Width;
HEIGHT = heightMap.Height;
Color[] heightMapColors = new Color[WIDTH * HEIGHT];
heightMap.GetData(heightMapColors);

heightData = new float[WIDTH, HEIGHT];
for (int x = 0; x < WIDTH; x++)
for (int y = 0; y < HEIGHT; y++)
{
heightData[x, y] = heightMapColors[x + y * WIDTH].R;
if (heightData[x, y] < minimumHeight) minimumHeight = heightData[x, y];
if (heightData[x, y] > maximumHeight) maximumHeight = heightData[x, y];
}

for (int x = 0; x < WIDTH; x++)
for (int y = 0; y < HEIGHT; y++)
heightData[x, y] = (heightData[x, y] - minimumHeight) / (maximumHeight - minimumHeight) * 30;
}

protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
SetUpXNADevice();


heightMap = content.Load<Texture2D>("heightmap");

sandTexture = content.Load<Texture2D>("sand");

grassTexture = content.Load<Texture2D>("grass");

rockTexture = content.Load<Texture2D>("rock");

snowTexture = content.Load<Texture2D>("snow");
LoadSkyDome();

waterBumpMap = content.Load<Texture2D>("waterbump");
}
}

private void SetUpWaterVertices()
{
waterVertices = new VertexPositionTexture[6];

waterVertices[0] = new VertexPositionTexture(new Vector3(0, 0, waterHeight), new Vector2(0, 1));
waterVertices[2] = new VertexPositionTexture(new Vector3(WIDTH, HEIGHT, waterHeight), new Vector2(1, 0));
waterVertices[1] = new VertexPositionTexture(new Vector3(0, HEIGHT, waterHeight), new Vector2(0, 0));

waterVertices[3] = new VertexPositionTexture(new Vector3(0, 0, waterHeight), new Vector2(0, 1));
waterVertices[5] = new VertexPositionTexture(new Vector3(WIDTH, 0, waterHeight), new Vector2(1, 1));
waterVertices[4] = new VertexPositionTexture(new Vector3(WIDTH, HEIGHT, waterHeight), new Vector2(1, 0));
}

private void LoadSkyDome()
{

skyDome = content.Load<Model>("dome");

foreach (ModelMesh mesh in skyDome.Meshes)
foreach (BasicEffect currenteffect in mesh.Effects)
skyDomeTexture = currenteffect.Texture;

foreach (ModelMesh modmesh in skyDome.Meshes)
foreach (ModelMeshPart modmeshpart in modmesh.MeshParts)
modmeshpart.Effect = effect.Clone(device);
}

protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent == true)
{
content.Unload();
}
}

protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);

ProcessInput((float)gameTime.ElapsedGameTime.Milliseconds / 30.0f);
UpdateCameraMatrices();
elapsedTime += (float)gameTime.ElapsedGameTime.Milliseconds / 100000.0f;

}

private void ProcessInput(float amountOfMovement)
{
Vector3 moveVector = new Vector3();

KeyboardState keys = Keyboard.GetState();
if (keys.IsKeyDown(Keys.Right))
moveVector.X += amountOfMovement;
if (keys.IsKeyDown(Keys.Left))
moveVector.X -= amountOfMovement;
if (keys.IsKeyDown(Keys.Down))
moveVector.Y -= amountOfMovement;
if (keys.IsKeyDown(Keys.Up))
moveVector.Y += amountOfMovement;

Matrix cameraRotation = Matrix.CreateRotationX(cameraAngles.X) * Matrix.CreateRotationZ(cameraAngles.Z);
cameraPosition += Vector3.Transform(moveVector, cameraRotation);

MouseState currentMouseState = Mouse.GetState();
if (currentMouseState.X != previousMouseState.X)
cameraAngles.Z -= amountOfMovement / 80.0f * (currentMouseState.X - previousMouseState.X);
if (currentMouseState.Y != previousMouseState.Y)
cameraAngles.X -= amountOfMovement / 80.0f * (currentMouseState.Y - previousMouseState.Y);
Mouse.SetPosition(Window.ClientBounds.Width / 2, Window.ClientBounds.Height / 2);
}

private void UpdateCameraMatrices()
{
Matrix cameraRotation = Matrix.CreateRotationX(cameraAngles.X) * Matrix.CreateRotationZ(cameraAngles.Z);

Vector3 targetPos = cameraPosition + Vector3.Transform(new Vector3(0, 1, 0), cameraRotation);
Vector3 upVector = Vector3.Transform(new Vector3(0, 0, 1), cameraRotation);

viewMatrix = Matrix.CreateLookAt(cameraPosition, targetPos, upVector);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)this.Window.ClientBounds.Width / (float)this.Window.ClientBounds.Height, 1.0f, 1000.0f);

float reflectionCamZCoord = -cameraPosition.Z + 2 * waterHeight;
Vector3 reflectionCamPosition = new Vector3(cameraPosition.X, cameraPosition.Y, reflectionCamZCoord);

float reflectionTargetZCoord = -targetPos.Z + 2 * waterHeight;
Vector3 reflectionCamTarget = new Vector3(targetPos.X, targetPos.Y, reflectionTargetZCoord);

Vector3 forwardVector = reflectionCamTarget - reflectionCamPosition;
Vector3 sideVector = Vector3.Transform(new Vector3(1, 0, 0), cameraRotation);
Vector3 reflectionCamUp = Vector3.Cross(sideVector, forwardVector);

reflectionViewMatrix = Matrix.CreateLookAt(reflectionCamPosition, reflectionCamTarget, reflectionCamUp);
}

private void DrawTerrain(Matrix currentViewMatrix)
{
effect.CurrentTechnique = effect.Techniques["MultiTextured"];
effect.Parameters["xSandTexture"].SetValue(sandTexture);
effect.Parameters["xGrassTexture"].SetValue(grassTexture);
effect.Parameters["xRockTexture"].SetValue(rockTexture);
effect.Parameters["xSnowTexture"].SetValue(snowTexture);

Matrix worldMatrix = Matrix.Identity;
effect.Parameters["xWorld"].SetValue(worldMatrix);
effect.Parameters["xView"].SetValue(currentViewMatrix);
effect.Parameters["xProjection"].SetValue(projectionMatrix);
effect.Parameters["xEnableLighting"].SetValue(true);
effect.Parameters["xLightDirection"].SetValue(new Vector3(-0.5f, -0.5f, -1));
effect.Parameters["xAmbient"].SetValue(0.2f);

effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();

device.Vertices[0].SetSource(terrainVertexBuffer, 0, VertexMultitextured.SizeInBytes);
device.Indices = terrainIndexBuffer;
device.VertexDeclaration = new VertexDeclaration(device, VertexMultitextured.VertexElements);

device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, WIDTH * HEIGHT, 0, (WIDTH - 1) * (HEIGHT - 1) * 2);

pass.End();
}
effect.End();
}

private void DrawSkyDome(Matrix currentViewMatrix)
{
foreach (ModelMesh modmesh in skyDome.Meshes)
{
foreach (Effect currenteffect in modmesh.Effects)
{
currenteffect.CurrentTechnique = effect.Techniques["Textured"];
Matrix worldMatrix = Matrix.CreateScale(750, 750, 750) * Matrix.CreateTranslation(cameraPosition - new Vector3(0, 0, 200));
currenteffect.Parameters["xWorld"].SetValue(worldMatrix);
currenteffect.Parameters["xView"].SetValue(currentViewMatrix);
currenteffect.Parameters["xProjection"].SetValue(projectionMatrix);
currenteffect.Parameters["xTexture"].SetValue(skyDomeTexture);
}
modmesh.Draw();
}
}

private void DrawRefractionMap()
{
Vector3 planeNormalDirection = new Vector3(0, 0, -1);
planeNormalDirection.Normalize();
Vector4 planeCoefficients = new Vector4(planeNormalDirection, waterHeight + 1.0f);

Matrix camMatrix = viewMatrix * projectionMatrix;
Matrix invCamMatrix = Matrix.Invert(camMatrix);
invCamMatrix = Matrix.Transpose(invCamMatrix);

planeCoefficients = Vector4.Transform(planeCoefficients, invCamMatrix);
Plane refractionClipPlane = new Plane(planeCoefficients);

device.ClipPlanes[0].Plane = refractionClipPlane;
device.ClipPlanes[0].IsEnabled = true;

device.SetRenderTarget(0, refractionRenderTarg);
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
DrawTerrain(viewMatrix);
device.ResolveRenderTarget(0);
refractionMap = refractionRenderTarg.GetTexture();
device.SetRenderTarget(0, null);

device.ClipPlanes[0].IsEnabled = false;
}

private void DrawReflectionMap()
{
Vector3 planeNormalDirection = new Vector3(0, 0, 1);
planeNormalDirection.Normalize();
Vector4 planeCoefficients = new Vector4(planeNormalDirection, -waterHeight + 1.0f);

Matrix camMatrix = reflectionViewMatrix * projectionMatrix;
Matrix invCamMatrix = Matrix.Invert(camMatrix);
invCamMatrix = Matrix.Transpose(invCamMatrix);

planeCoefficients = Vector4.Transform(planeCoefficients, invCamMatrix);
Plane reflectionClipPlane = new Plane(planeCoefficients);

device.ClipPlanes[0].Plane = reflectionClipPlane;
device.ClipPlanes[0].IsEnabled = true;

device.SetRenderTarget(0, reflectionRenderTarg);
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
DrawTerrain(reflectionViewMatrix);
DrawSkyDome(reflectionViewMatrix);
device.ResolveRenderTarget(0);
reflectionMap = reflectionRenderTarg.GetTexture();
device.SetRenderTarget(0, null);

device.ClipPlanes[0].IsEnabled = false;
}

private void DrawWater()
{
effect.CurrentTechnique = effect.Techniques["Water"];
Matrix worldMatrix = Matrix.Identity;
effect.Parameters["xWorld"].SetValue(worldMatrix);
effect.Parameters["xView"].SetValue(viewMatrix);
effect.Parameters["xReflectionView"].SetValue(reflectionViewMatrix);
effect.Parameters["xProjection"].SetValue(projectionMatrix);
effect.Parameters["xReflectionMap"].SetValue(reflectionMap);
effect.Parameters["xRefractionMap"].SetValue(refractionMap);
effect.Parameters["xWaterBumpMap"].SetValue(waterBumpMap);
effect.Parameters["xWaveLength"].SetValue(0.1f);
effect.Parameters["xWaveHeight"].SetValue(0.3f);
effect.Parameters["xCamPos"].SetValue(cameraPosition);
effect.Parameters["xTime"].SetValue(elapsedTime);
effect.Parameters["xWindForce"].SetValue(20.0f);
Matrix windDirection = Matrix.CreateRotationZ(MathHelper.PiOver2);
effect.Parameters["xWindDirection"].SetValue(windDirection);

effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.VertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
device.DrawUserPrimitives(PrimitiveType.TriangleList, waterVertices, 0, 2);
pass.End();
}
effect.End();
}

protected override void Draw(GameTime gameTime)
{
DrawRefractionMap();
DrawReflectionMap();
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkBlue, 1.0f, 0);
DrawTerrain(viewMatrix);
DrawSkyDome(viewMatrix);
DrawWater();
base.Draw(gameTime);
}
}
}



Re: XNA Game Studio Express Walking on a terrain

riemerg

So far for the copyright on my code Wink

You're asking quite a lot there.

I guess you already know how to load a model to the scene; if not check here.

If you want an animated model, check out the sample at the creators site.

If you want to position your model on the terrain, you need to know the height of the terrain at a certain point. You'll need bilinear interpolation for this, of which you can find the code in this thread in my forum.

Finally, I have covered a camera mode where the camera follows a model in this chapter on quaternions.

have fun Wink