4.8.9. Complete source code
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using BetaCell.Debug;
using BetaCell.Util.GlobalInfo.Content;
using BetaCell.Environment.Camera;
using BetaCell.Util.GlobalInfo;
using BetaCell.Environment.Animation;
using BetaCell.Environment.Mesh;
using BetaCell.Environment.Light;
using BetaCell.Environment.Mesh.Content;
using BetaCell.Environment;
using BetaCell.Environment.Mesh.Visitors;
using BetaCell.Dynamic.Skinned;
using BetaCell.Environment.Mesh.Collision;
using BetaCell.Util;
using BetaCell.Util.RenderStates;
using BetaCell.Environment.Texture.Feeder;
namespace Starter
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
//Game attributes
GraphicsDeviceManager
graphics;
GraphicsDevice device;
ContentManager content;
BCFirstPersonHumanCamera
camera;
//end game attributes
//This tutorial's attributes
BCMesh evilMesh;
BCAnimationSetBase
animationSet;
BCAnimationBase idle;
BCAnimationBase run;
BCAnimationBase idleToRun;
BCAnimationBase runToIdle;
BCAnimationController
controller;
BCAddSequenceListener
animationSequence;
//----------------------------
//Animation Control
Attributes
//----------------------------
double timeToChange = 5;
double lastTime = 0;
bool isIdle = true;
//---------------------------
//Animated collision model
//---------------------------
BCCollisionModel
evilCollisionModel;
bool showFace = false;
Vector3[]
currentCollisionFace = new Vector3[3];
BCCursor cursor;
RenderTarget2D pip;
BCTextureDrawer
textureDrawer;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
content = new ContentManager(Services);
#if(XBOX360)
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
#else
graphics.PreferredBackBufferWidth = 852;
graphics.PreferredBackBufferHeight = 480;
#endif
}
protected override void
Initialize()
{
//base initialization
device = graphics.GraphicsDevice;
BCLogger.instance.init(device, content);
BCInitializationManager.initialize(content);
OnActivated(null, null);
//-----
//MESHES
//-----
evilMesh =
BCMeshReader.readMesh("Content/gameAssets/evilAnimatedTexturedB", null,
device, content);
//-----
//Light Effect
//-----
BCBasicLight light = new BCBasicLight();
light.range = 3000;
light.transform = Matrix.CreateTranslation(-1f, -1f, -1f);
light.cubAtten = 0;
light.constAtten = 1;
light.linAtten = 0;
light.useShadows = false;
BCDynamicEffectVisitor lightSetter = new BCDynamicEffectVisitor(
light.getFunction("Shader.Light.Classic.PixelDirectionLight"), light, 1
);
evilMesh.visit(lightSetter);
//---------
//ANIMATION
//---------
animationSet =
content.Load<BCAnimationSetBase>("Content/gameAssets/evilAnimatedTexturedBAnim");
animationSet.animations.TryGetValue("Idle", out idle);
animationSet.animations.TryGetValue("Run", out run);
animationSet.animations.TryGetValue("IdleToRun", out idleToRun);
animationSet.animations.TryGetValue("RunToIdle", out runToIdle);
controller = new BCAnimationController(evilMesh.skeleton.boneCount);
evilMesh.controller = controller;
BCSkinnedMeshFeeder skinnedFeeder = new BCSkinnedMeshFeeder();
BCDynamicEffectVisitor skinnedSetter = new BCDynamicEffectVisitor(
skinnedFeeder.getFunction("Actuator.Skinned.SkinnedMesh"),
skinnedFeeder, 0
);
evilMesh.visit(skinnedSetter);
animationSequence = new BCAddSequenceListener();
animationSequence.setNextAnimation(null, idle);
controller.addSingle(idle, animationSequence, 0);
//Prepare boundings of the mesh for drawing
BCDrawableBoundingPrepareVisitor boundingPrepare =
new BCDrawableBoundingPrepareVisitor(device, Color.Red);
evilMesh.visit(boundingPrepare);
//Collision model
evilCollisionModel = new BCCollisionModel(evilMesh);
//Cursor
cursor = new BCCursor(
device,
content.Load<Texture2D>("Content/gameAssets/cursor")
);
cursor.position = new Vector2(device.Viewport.Width / 2,
device.Viewport.Height / 2);
//Texture Drawer
textureDrawer = new BCTextureDrawer(device, BCSampler.DEFAULT);
base.Initialize();
}
protected override void
OnActivated(object sender, EventArgs args)
{
buildViewMatrix();
base.OnActivated(sender, args);
}
void buildViewMatrix()
{
Vector3 pos = new Vector3(6f, 2, 6f);
Vector3 look = new Vector3(-7, -3.0f, -7);
look.Normalize();
camera = new BCFirstPersonHumanCamera(look, pos,
MathHelper.PiOver4,
(float)this.Window.ClientBounds.Width /
(float)this.Window.ClientBounds.Height,
1f, 200);
//Picture in Picture initialization
pip
= new RenderTarget2D(
device,
(int)(this.Window.ClientBounds.Width / 2),
(int)(this.Window.ClientBounds.Height / 2),
1,
SurfaceFormat.Color
);
BCGlobalInfo.instance.setMatrix(
BCGlobalInfo.VIEW_INDEX,
camera.getViewMatrix(-1)
);
BCGlobalInfo.instance.setMatrix(
BCGlobalInfo.PROJECTION_INDEX,
camera.getProjectionMatrix(-1)
);
}
protected override void
Update(GameTime gameTime)
{
double time = gameTime.TotalGameTime.TotalSeconds;
if
(time - lastTime > timeToChange)
{
lastTime = time;
if (isIdle)
{
if (animationSequence.setNextAnimation(idleToRun, run))
{
isIdle = false;
}
}
else
{
if (animationSequence.setNextAnimation(runToIdle, idle))
{
isIdle = true;
}
}
}
controller.update(time);
moveCamera(gameTime);
//Collision
Ray
currentRay = new Ray(camera.getPosition(), camera.look);
float? distance = evilMesh.bounding.Intersects(currentRay);
if
(distance != null && distance > 0)
{
List<Vector3> intersectedFaces = new List<Vector3>();
List<float> distances = new List<float>();
BCPooledLinkedList<BCBonePose> currentPoses =
controller.popBonePoses();
Matrix[] currentPosesTranforms =
controller.popFinalMatrices(currentPoses);
evilCollisionModel.animate(currentPosesTranforms,
evilMesh.getTransform());
controller.pushFinalMatrices(currentPosesTranforms);
controller.pushBonePoses(currentPoses);
evilCollisionModel.intersects(currentRay, intersectedFaces, distances);
showFace = BCCollisionModel.getClosestFace(
currentRay,
intersectedFaces,
distances,
currentCollisionFace
);
}
}
private void
moveCamera(GameTime gameTime)
{
float df = 0;
float ds = 0;
float dy = 0;
float pitch = 0;
float angleY = 0;
float speed = 5f;
#if (XBOX360)
GamePadState gamepad = GamePad.GetState(PlayerIndex.One);
df =
gamepad.ThumbSticks.Left.Y;
ds =
gamepad.ThumbSticks.Left.X;
pitch = - gamepad.ThumbSticks.Right.Y * 0.05f;
angleY = gamepad.ThumbSticks.Right.X * 0.05f;
if
(gamepad.IsButtonDown(Buttons.RightShoulder))
{
dy += 0.25f;
}
if
(gamepad.IsButtonDown(Buttons.LeftShoulder))
{
dy -= 0.25f;
}
speed = new Vector3(df, ds, dy).Length()*10;
#else
KeyboardState keys = Keyboard.GetState();
MouseState mouse = Mouse.GetState();
if
(keys.IsKeyDown(Keys.W))
{
df += 1;
}
if
(keys.IsKeyDown(Keys.S))
{
df -= 1;
}
if
(keys.IsKeyDown(Keys.D))
{
ds += 1;
}
if
(keys.IsKeyDown(Keys.A))
{
ds -= 1;
}
if
(keys.IsKeyDown(Keys.Q))
{
dy += 1;
}
if
(keys.IsKeyDown(Keys.E))
{
dy -= 1;
}
speed = 5f;
if
(keys.IsKeyDown(Keys.LeftControl))
{
speed = 10f;
}
angleY = ((float)this.Window.ClientBounds.Width / 2.0f -
(float)mouse.X) * -0.05f;
pitch = ((float)this.Window.ClientBounds.Height / 2.0f -
(float)mouse.Y) * -0.05f;
Mouse.SetPosition(this.Window.ClientBounds.Width / 2,
this.Window.ClientBounds.Height / 2);
#endif
camera.update(df, dy, ds, pitch, angleY, speed,
(float)gameTime.ElapsedGameTime.TotalSeconds);
BCGlobalInfo.instance.setMatrix(BCGlobalInfo.VIEW_INDEX,
camera.getViewMatrix(-1));
}
protected override void
Draw(GameTime gameTime)
{
//---------------------
//Draw on Texture
//---------------------
device.SetRenderTarget(0, pip);
graphics.GraphicsDevice.Clear(ClearOptions.Target |
ClearOptions.DepthBuffer | ClearOptions.Stencil,
Color.Black, 1.0f, 0);
BCDrawUtil.drawBoundings(evilMesh, device, gameTime);
BCWireFrameRenderStrategy drawWire = new BCWireFrameRenderStrategy();
BCDrawOverGeometryRenderStrategy drawOver = new
BCDrawOverGeometryRenderStrategy(15);
drawWire.push(device);
drawOver.push(device);
BCDrawUtil.drawCollisionModel(device, evilMesh.transform,
Color.LightGreen, evilCollisionModel);
drawOver.pop(device);
drawWire.pop(device);
if
(showFace)
{
drawOver.push(device);
BCDrawUtil.drawTriangle(
device,
currentCollisionFace[0],
currentCollisionFace[1],
currentCollisionFace[2],
Color.Yellow
);
drawOver.pop(device);
}
device.SetRenderTarget(0, null);
Texture2D pipTex = pip.GetTexture();
//---------------------
//Draw on Back Buffer
//---------------------
graphics.GraphicsDevice.Clear(ClearOptions.Target |
ClearOptions.DepthBuffer, Color.White, 1.0f, 0);
evilMesh.Draw(gameTime);
cursor.draw(gameTime);
textureDrawer.drawTexture(
pipTex,
new Vector2(0.5f, -0.5f),
new Vector2(0.5f, 0.5f)
);
BCLogger.instance.printFPS(gameTime);
BCLogger.instance.flush();
base.Draw(gameTime);
}
}
}