Commit initial
135
Game/Camera.cs
Executable file
@ -0,0 +1,135 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class Camera : GameComponent {
|
||||||
|
public Matrix LookAtMatrix {
|
||||||
|
get {return Matrix.CreateLookAt(Pos, Eye + Pos, Up);}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix ProjectionMatrix {
|
||||||
|
get {return Matrix.CreatePerspectiveFieldOfView(
|
||||||
|
MathHelper.ToRadians(Fov),
|
||||||
|
Game.GraphicsDevice.Viewport.AspectRatio,
|
||||||
|
NearDist,
|
||||||
|
FarDist
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Fov {get; set;}
|
||||||
|
public float NearDist {get; set;}
|
||||||
|
public float FarDist {get; set;}
|
||||||
|
|
||||||
|
public Vector3 Pos {get; set;}
|
||||||
|
public Vector3 Eye {get; set;}
|
||||||
|
public Vector3 Up {get; set;}
|
||||||
|
|
||||||
|
private float m_tangage;
|
||||||
|
public float Tangage {
|
||||||
|
get {return m_tangage;}
|
||||||
|
set {
|
||||||
|
m_tangage = value;
|
||||||
|
Eye = GetEyeFromAngle(Lacet, Tangage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float m_lacet;
|
||||||
|
public float Lacet {
|
||||||
|
get {return m_lacet;}
|
||||||
|
set {
|
||||||
|
m_lacet = value;
|
||||||
|
Eye = GetEyeFromAngle(Lacet, Tangage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float m_roulis;
|
||||||
|
public float Roulis {
|
||||||
|
get {return m_roulis;}
|
||||||
|
set {
|
||||||
|
m_roulis = value;
|
||||||
|
// TODO : compute up vector
|
||||||
|
Up = new Vector3(0, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Camera(Game game, Vector3 pos, Vector3 eye, Vector3 up, float fov, float near, float far)
|
||||||
|
: base(game) {
|
||||||
|
Pos = pos;
|
||||||
|
Eye = eye;
|
||||||
|
Up = up;
|
||||||
|
Fov = fov;
|
||||||
|
NearDist = near;
|
||||||
|
FarDist = far;
|
||||||
|
UpdateOrder = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Camera(Game game, Vector3 pos, float lacet, float tangage, float roulis, float fov, float near, float far)
|
||||||
|
: base(game) {
|
||||||
|
Pos = pos;
|
||||||
|
Lacet = lacet;
|
||||||
|
Tangage = tangage;
|
||||||
|
Roulis = roulis;
|
||||||
|
Fov = fov;
|
||||||
|
NearDist = near;
|
||||||
|
FarDist = far;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveForward(float step) {
|
||||||
|
Pos = Eye * step + Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveBackward(float step) {
|
||||||
|
Pos = Eye * step * -1.0f + Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveLeft(float step) {
|
||||||
|
Pos = GetEyeFromAngle(Lacet + 90.0f, 0) * step + Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveRight(float step) {
|
||||||
|
Pos = GetEyeFromAngle(Lacet + 90.0f, 0) * step * -1.0f + Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveUp(float step) {
|
||||||
|
Pos = Up * step + Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MoveDown(float step) {
|
||||||
|
Pos = Up * step * -1.0f + Pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Rotate(float lacet, float tangage, float roulis) {
|
||||||
|
Lacet = (Lacet + lacet) % 360.0f;
|
||||||
|
Tangage = (Tangage + tangage) % 360.0f;
|
||||||
|
Roulis = (Roulis + roulis) % 360.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 GetEyeFromAngle(float lacet, float tangage) {
|
||||||
|
float lacet_rad = MathHelper.ToRadians(lacet);
|
||||||
|
float tangage_rad = MathHelper.ToRadians(tangage);
|
||||||
|
|
||||||
|
Vector3 eye = new Vector3(
|
||||||
|
(float) (Math.Cos(tangage_rad) * Math.Cos(lacet_rad)),
|
||||||
|
(float) (Math.Cos(tangage_rad) * Math.Sin(lacet_rad)),
|
||||||
|
(float) (Math.Sin(tangage_rad))
|
||||||
|
);
|
||||||
|
|
||||||
|
return Vector3.Normalize(eye);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 Unproject(int x, int y) {
|
||||||
|
Vector3 nearSource = new Vector3(x, y, 0);
|
||||||
|
Vector3 farSource = new Vector3(x, y, 1);
|
||||||
|
|
||||||
|
Matrix world = Matrix.Identity;
|
||||||
|
Matrix proj = ProjectionMatrix;
|
||||||
|
Matrix view = LookAtMatrix;
|
||||||
|
|
||||||
|
Vector3 nearPoint = Game.GraphicsDevice.Viewport.Unproject(nearSource, proj, view, world);
|
||||||
|
Vector3 farPoint = Game.GraphicsDevice.Viewport.Unproject(farSource, proj, view, world);
|
||||||
|
|
||||||
|
return farPoint - nearPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
Game/CollisionStrategy.cs
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public interface CollisionStrategy {
|
||||||
|
void Update(InterruptorObject obj, GameTime gameTime);
|
||||||
|
void Collision(InterruptorObject hostObj, DynamicObject obj);
|
||||||
|
}
|
||||||
|
}
|
39
Game/Cursor.cs
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class Cursor : DrawableGameComponent {
|
||||||
|
public Point Pos {get; set;}
|
||||||
|
public Point Size {get; set;}
|
||||||
|
public Texture2D Texture {get; set;}
|
||||||
|
public HandsState Hand {get; private set;}
|
||||||
|
private SpriteBatch m_cursor;
|
||||||
|
|
||||||
|
public Cursor(KinPortal.Game game, SpriteBatch sprite,string filepath, Point size, HandsState hand)
|
||||||
|
: base(game) {
|
||||||
|
Pos = new Point(0, 0);
|
||||||
|
Size = size;
|
||||||
|
Texture = Game.Content.Load<Texture2D>(filepath);
|
||||||
|
Hand = hand;
|
||||||
|
m_cursor = sprite;
|
||||||
|
UpdateOrder = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(GameTime gameTime) {
|
||||||
|
KinPortal.Game game = (KinPortal.Game) Game;
|
||||||
|
Pos = Hand.Pos;
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(GameTime gameTime) {
|
||||||
|
Rectangle place = new Rectangle(Pos.X - Size.X / 2, Pos.Y - Size.Y / 2, Size.X, Size.Y);
|
||||||
|
|
||||||
|
m_cursor.Begin();
|
||||||
|
m_cursor.Draw(Texture, place, Color.White);
|
||||||
|
m_cursor.End();
|
||||||
|
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
Game/DrawPortalStrategy.cs
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class DrawPortalStrategy : TargetingStrategy {
|
||||||
|
private TimeSpan m_leftLoadTime;
|
||||||
|
private TimeSpan m_rightLoadTime;
|
||||||
|
|
||||||
|
private bool m_leftActive = false;
|
||||||
|
private HandsProjection m_leftProj;
|
||||||
|
private bool m_rightActive = false;
|
||||||
|
private HandsProjection m_rightProj;
|
||||||
|
|
||||||
|
|
||||||
|
public void Update(DynamicObject obj, GameTime gameTime) {
|
||||||
|
KinPortal.Game game = (KinPortal.Game) obj.Game;
|
||||||
|
|
||||||
|
if(m_leftActive && game.HandsTracker.LeftHand.IsClosed) {
|
||||||
|
m_leftLoadTime += gameTime.ElapsedGameTime;
|
||||||
|
if(m_leftLoadTime.Milliseconds >= 300.0) {
|
||||||
|
obj.Scene.PortalManager.CreatePortal(m_leftProj.HitPoint + (m_leftProj.HitNormal * 0.01f), Geometry.GetRelativeRotation(Vector3.Right, m_leftProj.HitNormal), PortalManager.PortalType.RED);
|
||||||
|
m_leftActive = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_leftActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_rightActive && game.HandsTracker.RightHand.IsClosed) {
|
||||||
|
m_rightLoadTime += gameTime.ElapsedGameTime;
|
||||||
|
if(m_rightLoadTime.Milliseconds >= 300.0) {
|
||||||
|
obj.Scene.PortalManager.CreatePortal(m_rightProj.HitPoint + (m_rightProj.HitNormal * 0.01f), Geometry.GetRelativeRotation(Vector3.Right, m_rightProj.HitNormal), PortalManager.PortalType.BLUE);
|
||||||
|
m_rightActive = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_rightActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Target(DynamicObject obj, HandsProjection leftHand, HandsProjection rightHand) {
|
||||||
|
KinPortal.Game game = (KinPortal.Game) obj.Game;
|
||||||
|
Vector3 orgNormal = Vector3.Right;
|
||||||
|
|
||||||
|
if(leftHand.IsProjected && game.HandsTracker.LeftHand.IsClosed == true && game.HandsTracker.LeftHand.PrevIsClosed == false) {
|
||||||
|
m_leftActive = true;
|
||||||
|
m_leftProj = leftHand;
|
||||||
|
m_leftLoadTime = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rightHand.IsProjected && game.HandsTracker.RightHand.IsClosed == true && game.HandsTracker.RightHand.PrevIsClosed == false) {
|
||||||
|
m_rightActive = true;
|
||||||
|
m_rightProj = rightHand;
|
||||||
|
m_rightLoadTime = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
Game/DynamicObject.cs
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Jitter.Dynamics;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class DynamicObject : Object {
|
||||||
|
public RigidBody PhysicModel {get; private set;}
|
||||||
|
public TargetingStrategy TargetingStrategy {get; set;}
|
||||||
|
|
||||||
|
public override Vector3 Pos {
|
||||||
|
get {
|
||||||
|
return Geometry.GetXnaVector(PhysicModel.Position);
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
PhysicModel.Position = Geometry.GetJitterVector(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Quaternion Rot {
|
||||||
|
get {
|
||||||
|
return Quaternion.CreateFromRotationMatrix(Geometry.GetXnaMatrix(PhysicModel.Orientation));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
PhysicModel.Orientation = Geometry.GetJitterMatrix(Matrix.CreateFromQuaternion(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStatic {
|
||||||
|
get {
|
||||||
|
return PhysicModel.IsStatic;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
PhysicModel.IsStatic = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicObject(string filepath, Vector3 pos, Quaternion rot, Scene scene, ShapeType shapeType, bool isStatic, TargetingStrategy strategy)
|
||||||
|
: base(filepath, scene) {
|
||||||
|
PhysicModel = new RigidBody(ShapeFactory.CreateShape(Model, shapeType));
|
||||||
|
Pos = pos;
|
||||||
|
Rot = rot;
|
||||||
|
TargetingStrategy = strategy;
|
||||||
|
IsStatic = isStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicObject(string filepath, Scene scene, ShapeType shapeType)
|
||||||
|
: this(filepath, Vector3.Zero, Quaternion.Identity, scene, shapeType, false, new NoTargetingStrategy()) {}
|
||||||
|
|
||||||
|
public void Target(HandsProjection leftHand, HandsProjection rightHand) {
|
||||||
|
TargetingStrategy.Target(this, leftHand, rightHand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(GameTime gameTime) {
|
||||||
|
TargetingStrategy.Update(this, gameTime);
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
164
Game/Game.cs
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
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.Media;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class Game : Microsoft.Xna.Framework.Game {
|
||||||
|
private GraphicsDeviceManager Graphics {get; set;}
|
||||||
|
private Cursor m_leftCursor;
|
||||||
|
private Cursor m_rightCursor;
|
||||||
|
|
||||||
|
public Scene Scene {get; private set;}
|
||||||
|
public HandsTracker HandsTracker {get; private set;}
|
||||||
|
|
||||||
|
public Game() {
|
||||||
|
Graphics = new GraphicsDeviceManager(this);
|
||||||
|
Content.RootDirectory = "Resources";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Initialize() {
|
||||||
|
Window.AllowUserResizing = true;
|
||||||
|
Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged);
|
||||||
|
Graphics.PreferredBackBufferWidth = 900;
|
||||||
|
Graphics.PreferredBackBufferHeight = 512;
|
||||||
|
Graphics.ApplyChanges();
|
||||||
|
|
||||||
|
HandsTracker = new HandsTracker(900, 512);
|
||||||
|
//HandsTracker.Run();
|
||||||
|
|
||||||
|
Scene = new Scene(this, new Camera(this, new Vector3(-15, -15, 15), 45, -30, 0, 70, 0.1f, 1000));
|
||||||
|
this.Components.Add(Scene);
|
||||||
|
base.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadContent() {
|
||||||
|
Scene.AddComponent(new DynamicObject(
|
||||||
|
"models\\cube",
|
||||||
|
new Vector3(0, 0, 5f), Quaternion.Identity,
|
||||||
|
Scene, ShapeType.BOX, false, new GrabStrategy()
|
||||||
|
));
|
||||||
|
Scene.AddComponent(new DynamicObject(
|
||||||
|
"models\\monkey",
|
||||||
|
new Vector3(0, 4, 5f), Quaternion.Identity,
|
||||||
|
Scene, ShapeType.SPHERE, false, new GrabStrategy()
|
||||||
|
));
|
||||||
|
Scene.AddComponent(new DynamicObject(
|
||||||
|
"models\\cube",
|
||||||
|
new Vector3(3, 0, 5f), Quaternion.Identity,
|
||||||
|
Scene, ShapeType.BOX, false, new GrabStrategy()
|
||||||
|
));
|
||||||
|
Scene.AddComponent(new DynamicObject(
|
||||||
|
"models\\monkey",
|
||||||
|
new Vector3(0, -4, 5f), Quaternion.Identity,
|
||||||
|
Scene, ShapeType.SPHERE, false, new GrabStrategy()
|
||||||
|
));
|
||||||
|
Scene.AddComponent(new DynamicObject(
|
||||||
|
"models\\sphere",
|
||||||
|
new Vector3(-3, 0, 5f), Quaternion.Identity,
|
||||||
|
Scene, ShapeType.SPHERE, false, new GrabStrategy()
|
||||||
|
));
|
||||||
|
Scene.AddComponent(new DynamicObject("models\\level",
|
||||||
|
new Vector3(0, 0, 0), Quaternion.Identity, Scene, ShapeType.TRIANGULATE, true, new DrawPortalStrategy()
|
||||||
|
));
|
||||||
|
Scene.AddComponent(new InterruptorObject(
|
||||||
|
"models\\target",
|
||||||
|
new Vector3(19.8f, 0, 10f), Quaternion.CreateFromYawPitchRoll(0, 0, MathHelper.ToRadians(180)),
|
||||||
|
Scene, ShapeType.TRIANGULATE, true, new NoTargetingStrategy(), new TargetCollisionStrategy()
|
||||||
|
));
|
||||||
|
|
||||||
|
m_leftCursor = new Cursor(this, new SpriteBatch(GraphicsDevice), "textures\\tex_cursor_red", new Point(48, 48), HandsTracker.LeftHand);
|
||||||
|
this.Components.Add(m_leftCursor);
|
||||||
|
m_rightCursor = new Cursor(this, new SpriteBatch(GraphicsDevice), "textures\\tex_cursor_blue", new Point(48, 48), HandsTracker.RightHand);
|
||||||
|
this.Components.Add(m_rightCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UnloadContent() {}
|
||||||
|
|
||||||
|
protected override void Update(GameTime gameTime) {
|
||||||
|
/* Quit Game */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Escape)) {
|
||||||
|
Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move Forward */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Z)) {
|
||||||
|
Scene.Camera.MoveForward(0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move Backware */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.S)) {
|
||||||
|
Scene.Camera.MoveBackward(0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move Left */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Q)) {
|
||||||
|
Scene.Camera.MoveLeft(0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move Right */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.D)) {
|
||||||
|
Scene.Camera.MoveRight(0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move Up */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Space)) {
|
||||||
|
Scene.Camera.MoveUp(0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move Down */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.LeftShift)) {
|
||||||
|
Scene.Camera.MoveDown(0.08f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate Up */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Up)) {
|
||||||
|
Scene.Camera.Rotate(0, 1.8f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate Down */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Down)) {
|
||||||
|
Scene.Camera.Rotate(0, -1.8f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate Left */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Left)) {
|
||||||
|
Scene.Camera.Rotate(1.8f, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rotate Right */
|
||||||
|
if(Keyboard.GetState().IsKeyDown(Keys.Right)) {
|
||||||
|
Scene.Camera.Rotate(-1.8f, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseState ms = Mouse.GetState();
|
||||||
|
HandsTracker.LeftHand.Pos = new Point(ms.X, ms.Y);
|
||||||
|
HandsTracker.RightHand.Pos = new Point(ms.X, ms.Y);
|
||||||
|
HandsTracker.LeftHand.PrevIsClosed = HandsTracker.LeftHand.IsClosed;
|
||||||
|
HandsTracker.LeftHand.IsClosed = (ms.LeftButton == ButtonState.Pressed);
|
||||||
|
HandsTracker.RightHand.PrevIsClosed = HandsTracker.RightHand.IsClosed;
|
||||||
|
HandsTracker.RightHand.IsClosed = (ms.RightButton == ButtonState.Pressed);
|
||||||
|
HandsTracker.LeftHand.Depth = (double) ms.ScrollWheelValue / 1000.0f;
|
||||||
|
HandsTracker.RightHand.Depth = (double) ms.ScrollWheelValue / 1000.0f;
|
||||||
|
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(GameTime gameTime) {
|
||||||
|
GraphicsDevice.Clear(Color.SkyBlue);
|
||||||
|
Scene.Draw(gameTime);
|
||||||
|
m_leftCursor.Draw(gameTime);
|
||||||
|
m_rightCursor.Draw(gameTime);
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Window_ClientSizeChanged(object sender, EventArgs e) {
|
||||||
|
HandsTracker.InteractionRegionWidth = GraphicsDevice.Viewport.Width;
|
||||||
|
HandsTracker.InteractionRegionHeight = GraphicsDevice.Viewport.Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
152
Game/Game.csproj
Executable file
@ -0,0 +1,152 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectGuid>{FAA2E885-42FD-49FD-8678-925331BBE9C8}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>KinPortal</RootNamespace>
|
||||||
|
<AssemblyName>KinPortal</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
||||||
|
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
|
||||||
|
<XnaPlatform>Windows</XnaPlatform>
|
||||||
|
<XnaProfile>Reach</XnaProfile>
|
||||||
|
<XnaCrossPlatformGroupID>400c0308-ad81-481b-9a51-0bf95f95bd5b</XnaCrossPlatformGroupID>
|
||||||
|
<XnaOutputType>Game</XnaOutputType>
|
||||||
|
<ApplicationIcon>
|
||||||
|
</ApplicationIcon>
|
||||||
|
<Thumbnail>
|
||||||
|
</Thumbnail>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<PublishUrl>publier\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\x86\Debug</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoStdLib>true</NoStdLib>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<XnaCompressContent>false</XnaCompressContent>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\x86\Release</OutputPath>
|
||||||
|
<DefineConstants>TRACE;WINDOWS</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoStdLib>true</NoStdLib>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<XnaCompressContent>true</XnaCompressContent>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Jitter">
|
||||||
|
<HintPath>..\Jitter\Jitter\bin\Release\Jitter.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Kinect, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.Kinect.Toolkit">
|
||||||
|
<HintPath>..\..\..\..\..\..\Program Files\Microsoft SDKs\Kinect\Developer Toolkit v1.8.0\Assemblies\Microsoft.Kinect.Toolkit.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Kinect.Toolkit.Interaction">
|
||||||
|
<HintPath>..\..\..\..\..\..\Program Files\Microsoft SDKs\Kinect\Developer Toolkit v1.8.0\Assemblies\Microsoft.Kinect.Toolkit.Interaction.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.GamerServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
|
||||||
|
<Reference Include="mscorlib" />
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Net" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Camera.cs" />
|
||||||
|
<Compile Include="CollisionStrategy.cs" />
|
||||||
|
<Compile Include="Cursor.cs" />
|
||||||
|
<Compile Include="DrawPortalStrategy.cs" />
|
||||||
|
<Compile Include="Geometry.cs" />
|
||||||
|
<Compile Include="GrapStrategy.cs" />
|
||||||
|
<Compile Include="HandsProjection.cs" />
|
||||||
|
<Compile Include="HandsState.cs" />
|
||||||
|
<Compile Include="HandsTracker.cs" />
|
||||||
|
<Compile Include="InterruptorObject.cs" />
|
||||||
|
<Compile Include="NoCollisionStrategy.cs" />
|
||||||
|
<Compile Include="NoTargetingStrategy.cs" />
|
||||||
|
<Compile Include="Object.cs" />
|
||||||
|
<Compile Include="Portal.cs" />
|
||||||
|
<Compile Include="PortalCollisionStrategy.cs" />
|
||||||
|
<Compile Include="PortalManager.cs" />
|
||||||
|
<Compile Include="ShapeFactory.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Game.cs" />
|
||||||
|
<Compile Include="Scene.cs" />
|
||||||
|
<Compile Include="DynamicObject.cs" />
|
||||||
|
<Compile Include="SimpleObject.cs" />
|
||||||
|
<Compile Include="TargetCollisionStrategy.cs" />
|
||||||
|
<Compile Include="TargetingStrategy.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Resources\Resources.contentproj">
|
||||||
|
<Name>Resources</Name>
|
||||||
|
<XnaReferenceType>Content</XnaReferenceType>
|
||||||
|
<Project>{75D6A435-2F46-4192-B2B7-37A17468C066}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4 Client Profile %28x86 et x64%29</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Windows Installer 4.5</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
|
||||||
|
<!--
|
||||||
|
To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
161
Game/Geometry.cs
Executable file
@ -0,0 +1,161 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Jitter.LinearMath;
|
||||||
|
using Jitter.Collision;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class Geometry {
|
||||||
|
public List<Vector3> Vertices {get; private set;}
|
||||||
|
public List<ushort> Indices {get; private set;}
|
||||||
|
|
||||||
|
public BoundingBox Box {
|
||||||
|
get {
|
||||||
|
return BoundingBox.CreateFromPoints(Vertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoundingSphere Sphere {
|
||||||
|
get {
|
||||||
|
return BoundingSphere.CreateFromPoints(Vertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JVector> JVertices {
|
||||||
|
get {
|
||||||
|
List<JVector> vertices = new List<JVector>();
|
||||||
|
foreach(Vector3 vert in Vertices) {
|
||||||
|
vertices.Add(GetJitterVector(vert));
|
||||||
|
}
|
||||||
|
return vertices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TriangleVertexIndices> JTriangles {
|
||||||
|
get {
|
||||||
|
List<TriangleVertexIndices> triangles = new List<TriangleVertexIndices>();
|
||||||
|
for(int i = 0; i < Indices.Count / 3; i++) {
|
||||||
|
triangles.Add(new TriangleVertexIndices(
|
||||||
|
Indices[i * 3 + 0],
|
||||||
|
Indices[i * 3 + 1],
|
||||||
|
Indices[i * 3 + 2]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return triangles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Geometry(Model model) {
|
||||||
|
Vertices = new List<Vector3>();
|
||||||
|
Indices = new List<ushort>();
|
||||||
|
|
||||||
|
Matrix[] bones = new Matrix[model.Bones.Count];
|
||||||
|
model.CopyAbsoluteBoneTransformsTo(bones);
|
||||||
|
foreach (ModelMesh mm in model.Meshes) {
|
||||||
|
Matrix bone = bones[mm.ParentBone.Index];
|
||||||
|
foreach (ModelMeshPart mmp in mm.MeshParts) {
|
||||||
|
int offset = Vertices.Count;
|
||||||
|
Vector3[] verts = new Vector3[mmp.NumVertices];
|
||||||
|
mmp.VertexBuffer.GetData<Vector3>(mmp.VertexOffset * mmp.VertexBuffer.VertexDeclaration.VertexStride,
|
||||||
|
verts, 0, mmp.NumVertices, mmp.VertexBuffer.VertexDeclaration.VertexStride);
|
||||||
|
Vector3.Transform(verts, ref bone, verts);
|
||||||
|
Vertices.AddRange(verts);
|
||||||
|
|
||||||
|
ushort[] indices = new ushort[mmp.PrimitiveCount * 3];
|
||||||
|
mmp.IndexBuffer.GetData<ushort>(mmp.StartIndex * 2, indices, 0, mmp.PrimitiveCount * 3);
|
||||||
|
TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
|
||||||
|
for (int i = 0; i != indices.Length; i++) {
|
||||||
|
indices[i] += (ushort) offset;
|
||||||
|
}
|
||||||
|
Indices.AddRange(indices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Matrix GetXnaMatrix(JMatrix jmat) {
|
||||||
|
return new Matrix(
|
||||||
|
jmat.M11, jmat.M12, jmat.M13, 0.0f,
|
||||||
|
jmat.M21, jmat.M22, jmat.M23, 0.0f,
|
||||||
|
jmat.M31, jmat.M32, jmat.M33, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JMatrix GetJitterMatrix(Matrix xmat) {
|
||||||
|
return new JMatrix(
|
||||||
|
xmat.M11, xmat.M12, xmat.M13,
|
||||||
|
xmat.M21, xmat.M22, xmat.M23,
|
||||||
|
xmat.M31, xmat.M32, xmat.M33
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 GetXnaVector(JVector jvec) {
|
||||||
|
return new Vector3(jvec.X, jvec.Y, jvec.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JVector GetJitterVector(Vector3 xvec) {
|
||||||
|
return new JVector(xvec.X, xvec.Y, xvec.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Quaternion GetRelativeRotation(Vector3 u, Vector3 v) {
|
||||||
|
Quaternion rot;
|
||||||
|
if(u == v) {
|
||||||
|
rot = Quaternion.Identity;
|
||||||
|
} else if(u == (-v)) {
|
||||||
|
rot = Quaternion.CreateFromAxisAngle(GetOrthogonalVector(u), (float) Math.PI);
|
||||||
|
} else {
|
||||||
|
rot = Quaternion.CreateFromAxisAngle(Vector3.Cross(u, v), (float) Math.Acos(Vector3.Dot(u, v)));
|
||||||
|
}
|
||||||
|
return rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 GetRotationAxis(Quaternion rot) {
|
||||||
|
Vector3 axis = new Vector3(rot.X, rot.Y, rot.Z);
|
||||||
|
Vector3 naxis = Vector3.Normalize(axis);
|
||||||
|
return naxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 GetOrthogonalVector(Vector3 vec) {
|
||||||
|
Vector3 v;
|
||||||
|
if(vec.X != 0) {
|
||||||
|
v = new Vector3((-(vec.Y)-(vec.Z))/vec.X, 1, 0);
|
||||||
|
} else if(vec.Y != 0) {
|
||||||
|
v = new Vector3(1, (-(vec.Z)-(vec.X))/vec.Y, 0);
|
||||||
|
} else if(vec.Z != 0) {
|
||||||
|
v = new Vector3(1, 0, (-(vec.X)-(vec.Y))/vec.Z);
|
||||||
|
} else {
|
||||||
|
v = Vector3.Zero;
|
||||||
|
}
|
||||||
|
return Vector3.Normalize(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static void GetJitterModelTriangles(Model model, List<JVector> vertices, List<TriangleVertexIndices> triangles) {
|
||||||
|
Matrix[] bones = new Matrix[model.Bones.Count];
|
||||||
|
model.CopyAbsoluteBoneTransformsTo(bones);
|
||||||
|
foreach (ModelMesh mm in model.Meshes) {
|
||||||
|
Matrix bone = bones[mm.ParentBone.Index];
|
||||||
|
foreach (ModelMeshPart mmp in mm.MeshParts) {
|
||||||
|
int offset = vertices.Count;
|
||||||
|
Vector3[] verts = new Vector3[mmp.NumVertices];
|
||||||
|
mmp.VertexBuffer.GetData<Vector3>(mmp.VertexOffset * mmp.VertexBuffer.VertexDeclaration.VertexStride,
|
||||||
|
verts, 0, mmp.NumVertices, mmp.VertexBuffer.VertexDeclaration.VertexStride);
|
||||||
|
foreach(Vector3 vert in verts) {
|
||||||
|
vertices.Add(GetJitterVector(Vector3.Transform(vert, bone)));
|
||||||
|
}
|
||||||
|
|
||||||
|
short[] indices = new short[mmp.PrimitiveCount * 3];
|
||||||
|
mmp.IndexBuffer.GetData<short>(mmp.StartIndex * 2, indices, 0, mmp.PrimitiveCount * 3);
|
||||||
|
TriangleVertexIndices[] tvi = new TriangleVertexIndices[mmp.PrimitiveCount];
|
||||||
|
for (int i = 0; i != tvi.Length; ++i) {
|
||||||
|
tvi[i].I0 = indices[i * 3 + 0] + offset;
|
||||||
|
tvi[i].I1 = indices[i * 3 + 1] + offset;
|
||||||
|
tvi[i].I2 = indices[i * 3 + 2] + offset;
|
||||||
|
}
|
||||||
|
triangles.AddRange(tvi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
102
Game/GrapStrategy.cs
Executable file
@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Jitter.Collision;
|
||||||
|
using Jitter.Dynamics.Constraints.SingleBody;
|
||||||
|
using Jitter.LinearMath;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class GrabStrategy : TargetingStrategy {
|
||||||
|
private PointOnPoint m_leftGrabConstraint = null;
|
||||||
|
private PointOnPoint m_rightGrabConstraint = null;
|
||||||
|
private float m_leftHitDistance;
|
||||||
|
private float m_rightHitDistance;
|
||||||
|
private float m_leftHandHitDepth;
|
||||||
|
private float m_rightHandHitDepth;
|
||||||
|
|
||||||
|
public void Update(DynamicObject obj, GameTime gameTime) {
|
||||||
|
KinPortal.Game game = (KinPortal.Game) obj.Game;
|
||||||
|
|
||||||
|
if(game.HandsTracker.LeftHand.IsClosed) {
|
||||||
|
Vector3 ray = obj.Scene.Camera.Unproject(game.HandsTracker.LeftHand.Pos.X, game.HandsTracker.LeftHand.Pos.Y);
|
||||||
|
ray.Normalize();
|
||||||
|
if(m_leftGrabConstraint != null) {
|
||||||
|
float hitDistance = m_leftHitDistance * (1.0f + (float) game.HandsTracker.LeftHand.Depth - m_leftHandHitDepth);
|
||||||
|
m_leftGrabConstraint.Anchor = Geometry.GetJitterVector(obj.Scene.Camera.Pos + ray * hitDistance);
|
||||||
|
obj.PhysicModel.IsActive = true;
|
||||||
|
obj.PhysicModel.LinearVelocity *= 0.98f;
|
||||||
|
obj.PhysicModel.AngularVelocity *= 0.98f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(m_leftGrabConstraint != null) {
|
||||||
|
obj.Scene.PhysicWorld.RemoveConstraint(m_leftGrabConstraint);
|
||||||
|
m_leftGrabConstraint = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(game.HandsTracker.RightHand.IsClosed) {
|
||||||
|
Vector3 ray = obj.Scene.Camera.Unproject(game.HandsTracker.RightHand.Pos.X, game.HandsTracker.RightHand.Pos.Y);
|
||||||
|
ray.Normalize();
|
||||||
|
if(m_rightGrabConstraint != null) {
|
||||||
|
float hitDistance = m_rightHitDistance * (1.0f + (float) game.HandsTracker.RightHand.Depth - m_rightHandHitDepth);
|
||||||
|
m_rightGrabConstraint.Anchor = Geometry.GetJitterVector(obj.Scene.Camera.Pos + ray * hitDistance);
|
||||||
|
obj.PhysicModel.IsActive = true;
|
||||||
|
obj.PhysicModel.LinearVelocity *= 0.98f;
|
||||||
|
obj.PhysicModel.AngularVelocity *= 0.98f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(m_rightGrabConstraint != null) {
|
||||||
|
obj.Scene.PhysicWorld.RemoveConstraint(m_rightGrabConstraint);
|
||||||
|
m_rightGrabConstraint = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Target(DynamicObject obj, HandsProjection leftHand, HandsProjection rightHand) {
|
||||||
|
KinPortal.Game game = (KinPortal.Game) obj.Game;
|
||||||
|
|
||||||
|
if(leftHand.IsProjected && game.HandsTracker.LeftHand.IsClosed && !game.HandsTracker.LeftHand.PrevIsClosed) {
|
||||||
|
if(m_leftGrabConstraint != null) {
|
||||||
|
obj.Scene.PhysicWorld.RemoveConstraint(m_leftGrabConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_rightGrabConstraint != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JVector lanchor = Geometry.GetJitterVector(leftHand.HitPoint - obj.Pos);
|
||||||
|
lanchor = JVector.Transform(lanchor, JMatrix.Transpose(obj.PhysicModel.Orientation));
|
||||||
|
|
||||||
|
m_leftGrabConstraint = new PointOnPoint(obj.PhysicModel, lanchor);
|
||||||
|
m_leftGrabConstraint.Softness = 0.004f;
|
||||||
|
m_leftGrabConstraint.BiasFactor = 0.1f;
|
||||||
|
|
||||||
|
obj.Scene.PhysicWorld.AddConstraint(m_leftGrabConstraint);
|
||||||
|
m_leftHitDistance = (leftHand.HitPoint - obj.Scene.Camera.Pos).Length();
|
||||||
|
m_leftGrabConstraint.Anchor = Geometry.GetJitterVector(leftHand.HitPoint);
|
||||||
|
m_leftHandHitDepth = (float) game.HandsTracker.LeftHand.Depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rightHand.IsProjected && game.HandsTracker.RightHand.IsClosed && !game.HandsTracker.RightHand.PrevIsClosed) {
|
||||||
|
if(m_rightGrabConstraint != null) {
|
||||||
|
obj.Scene.PhysicWorld.RemoveConstraint(m_rightGrabConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_leftGrabConstraint != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JVector lanchor = Geometry.GetJitterVector(rightHand.HitPoint - obj.Pos);
|
||||||
|
lanchor = JVector.Transform(lanchor, JMatrix.Transpose(obj.PhysicModel.Orientation));
|
||||||
|
|
||||||
|
m_rightGrabConstraint = new PointOnPoint(obj.PhysicModel, lanchor);
|
||||||
|
m_rightGrabConstraint.Softness = 0.004f;
|
||||||
|
m_rightGrabConstraint.BiasFactor = 0.1f;
|
||||||
|
|
||||||
|
obj.Scene.PhysicWorld.AddConstraint(m_rightGrabConstraint);
|
||||||
|
m_rightHitDistance = (rightHand.HitPoint - obj.Scene.Camera.Pos).Length();
|
||||||
|
m_rightGrabConstraint.Anchor = Geometry.GetJitterVector(rightHand.HitPoint);
|
||||||
|
m_rightHandHitDepth = (float) game.HandsTracker.RightHand.Depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Game/HandsProjection.cs
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public struct HandsProjection {
|
||||||
|
public bool IsProjected;
|
||||||
|
public Vector3 HitPoint;
|
||||||
|
public Vector3 HitNormal;
|
||||||
|
|
||||||
|
public HandsProjection(bool isProjected, Vector3 hitPoint, Vector3 hitNormal) {
|
||||||
|
IsProjected = isProjected;
|
||||||
|
HitPoint = hitPoint;
|
||||||
|
HitNormal = hitNormal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
Game/HandsState.cs
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class HandsState {
|
||||||
|
public Point Pos {get; set;}
|
||||||
|
public double Depth {get; set;}
|
||||||
|
public bool PrevIsClosed {get; set;}
|
||||||
|
public bool IsClosed {get; set;}
|
||||||
|
|
||||||
|
public HandsState() {
|
||||||
|
Pos = Point.Zero;
|
||||||
|
IsClosed = false;
|
||||||
|
PrevIsClosed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
234
Game/HandsTracker.cs
Executable file
@ -0,0 +1,234 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Kinect;
|
||||||
|
using Microsoft.Kinect.Toolkit;
|
||||||
|
using Microsoft.Kinect.Toolkit.Interaction;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class HandsTracker : IInteractionClient {
|
||||||
|
public double InteractionRegionWidth {get; set;}
|
||||||
|
public double InteractionRegionHeight {get; set;}
|
||||||
|
private const int InvalidTrackingId = 0;
|
||||||
|
private readonly KinectSensorChooser sensorChooser = new KinectSensorChooser();
|
||||||
|
private readonly HashSet<int> trackedUsers = new HashSet<int>();
|
||||||
|
|
||||||
|
private InteractionStream interactionStream;
|
||||||
|
private KinectSensor kinectSensor;
|
||||||
|
private Skeleton[] skeletons;
|
||||||
|
private UserInfo[] userInfos;
|
||||||
|
|
||||||
|
public HandsState LeftHand {get; private set;}
|
||||||
|
public HandsState RightHand {get; private set;}
|
||||||
|
|
||||||
|
public HandsTracker(double screenWidth, double screenHeight) {
|
||||||
|
InteractionRegionWidth = screenWidth;
|
||||||
|
InteractionRegionHeight = screenHeight;
|
||||||
|
LeftHand = new HandsState();
|
||||||
|
RightHand = new HandsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run() {
|
||||||
|
this.sensorChooser.KinectChanged += this.OnSensorChanged;
|
||||||
|
this.sensorChooser.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region PressAndGripAdjustment
|
||||||
|
public InteractionInfo GetInteractionInfoAtLocation(int skeletonTrackingId, InteractionHandType handType, double x, double y) {
|
||||||
|
return new InteractionInfo();
|
||||||
|
}
|
||||||
|
#endregion PressAndGripAdjustment
|
||||||
|
|
||||||
|
|
||||||
|
#region Configuration
|
||||||
|
private void InitializeInteractions(KinectSensor sensor) {
|
||||||
|
this.skeletons = new Skeleton[sensor.SkeletonStream.FrameSkeletonArrayLength];
|
||||||
|
this.userInfos = new UserInfo[InteractionFrame.UserInfoArrayLength];
|
||||||
|
|
||||||
|
sensor.DepthFrameReady += this.SensorDepthFrameReady;
|
||||||
|
sensor.SkeletonFrameReady += this.SensorSkeletonFrameReady;
|
||||||
|
|
||||||
|
this.interactionStream = new InteractionStream(sensor, this);
|
||||||
|
this.interactionStream.InteractionFrameReady += this.InteractionFrameReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UninitializeInteractions(KinectSensor sensor) {
|
||||||
|
sensor.DepthFrameReady -= this.SensorDepthFrameReady;
|
||||||
|
sensor.SkeletonFrameReady -= this.SensorSkeletonFrameReady;
|
||||||
|
|
||||||
|
this.skeletons = null;
|
||||||
|
this.userInfos = null;
|
||||||
|
|
||||||
|
this.interactionStream.InteractionFrameReady -= this.InteractionFrameReady;
|
||||||
|
this.interactionStream.Dispose();
|
||||||
|
this.interactionStream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSensorChanged(object sender, KinectChangedEventArgs args) {
|
||||||
|
if (args.OldSensor != null) {
|
||||||
|
this.UninitializeInteractions(args.OldSensor);
|
||||||
|
try {
|
||||||
|
args.OldSensor.SkeletonStream.AppChoosesSkeletons = false;
|
||||||
|
args.OldSensor.DepthStream.Range = DepthRange.Default;
|
||||||
|
args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
|
||||||
|
args.OldSensor.DepthStream.Disable();
|
||||||
|
args.OldSensor.SkeletonStream.Disable();
|
||||||
|
} catch (InvalidOperationException) {
|
||||||
|
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
|
||||||
|
// E.g.: sensor might be abruptly unplugged.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.kinectSensor = null;
|
||||||
|
|
||||||
|
if (args.NewSensor != null) {
|
||||||
|
try {
|
||||||
|
// InteractionStream needs 640x480 depth data stream
|
||||||
|
args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
|
||||||
|
args.NewSensor.SkeletonStream.Enable();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Interactions work better in near range
|
||||||
|
args.NewSensor.DepthStream.Range = DepthRange.Near;
|
||||||
|
args.NewSensor.SkeletonStream.EnableTrackingInNearRange = true;
|
||||||
|
} catch (InvalidOperationException) {
|
||||||
|
// Non Kinect for Windows devices do not support Near mode, so reset back to default mode.
|
||||||
|
args.NewSensor.DepthStream.Range = DepthRange.Default;
|
||||||
|
args.NewSensor.SkeletonStream.EnableTrackingInNearRange = false;
|
||||||
|
}
|
||||||
|
} catch (InvalidOperationException) {
|
||||||
|
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
|
||||||
|
// E.g.: sensor might be abruptly unplugged.
|
||||||
|
}
|
||||||
|
|
||||||
|
this.kinectSensor = args.NewSensor;
|
||||||
|
|
||||||
|
this.InitializeInteractions(args.NewSensor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Configuration
|
||||||
|
|
||||||
|
#region Processing
|
||||||
|
private void SensorDepthFrameReady(object sender, DepthImageFrameReadyEventArgs depthImageFrameReadyEventArgs) {
|
||||||
|
if (this.kinectSensor != sender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (DepthImageFrame depthFrame = depthImageFrameReadyEventArgs.OpenDepthImageFrame()) {
|
||||||
|
if (null != depthFrame) {
|
||||||
|
try {
|
||||||
|
// Hand data to Interaction framework to be processed
|
||||||
|
this.interactionStream.ProcessDepth(depthFrame.GetRawPixelData(), depthFrame.Timestamp);
|
||||||
|
} catch (InvalidOperationException) {
|
||||||
|
// DepthFrame functions may throw when the sensor gets
|
||||||
|
// into a bad state. Ignore the frame in that case.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs) {
|
||||||
|
if (this.kinectSensor != sender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame()) {
|
||||||
|
if (null != skeletonFrame) {
|
||||||
|
try {
|
||||||
|
skeletonFrame.CopySkeletonDataTo(this.skeletons);
|
||||||
|
var accelerometerReading = this.kinectSensor.AccelerometerGetCurrentReading();
|
||||||
|
this.interactionStream.ProcessSkeleton(this.skeletons, accelerometerReading, skeletonFrame.Timestamp);
|
||||||
|
} catch (InvalidOperationException) {
|
||||||
|
// SkeletonFrame functions may throw when the sensor gets
|
||||||
|
// into a bad state. Ignore the frame in that case.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InteractionFrameReady(object sender, InteractionFrameReadyEventArgs e) {
|
||||||
|
// Check for a null userInfos since we may still get posted events
|
||||||
|
// from the stream after we have unregistered our event handler and
|
||||||
|
// deleted our buffers.
|
||||||
|
if (this.userInfos == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo[] localUserInfos = null;
|
||||||
|
long timestamp = 0;
|
||||||
|
|
||||||
|
using (InteractionFrame interactionFrame = e.OpenInteractionFrame()) {
|
||||||
|
if (interactionFrame != null) {
|
||||||
|
interactionFrame.CopyInteractionDataTo(this.userInfos);
|
||||||
|
timestamp = interactionFrame.Timestamp;
|
||||||
|
localUserInfos = this.userInfos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localUserInfos != null) {
|
||||||
|
var currentUserSet = new HashSet<int>();
|
||||||
|
var usersToRemove = new HashSet<int>();
|
||||||
|
|
||||||
|
foreach (var info in localUserInfos) {
|
||||||
|
if (info.SkeletonTrackingId == InvalidTrackingId) {
|
||||||
|
// Only look at user information corresponding to valid users
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (!this.trackedUsers.Contains(info.SkeletonTrackingId)) {
|
||||||
|
Console.WriteLine("New user '{0}' entered scene at time {1}", info.SkeletonTrackingId, timestamp);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
currentUserSet.Add(info.SkeletonTrackingId);
|
||||||
|
this.trackedUsers.Add(info.SkeletonTrackingId);
|
||||||
|
|
||||||
|
// Perform hit testing and look for Grip and GripRelease events
|
||||||
|
foreach (var handPointer in info.HandPointers) {
|
||||||
|
if (handPointer.HandType.ToString() == "Right") {
|
||||||
|
RightHand.Pos = new Point(
|
||||||
|
(int) ((handPointer.X / 2) * InteractionRegionWidth),
|
||||||
|
(int) ((handPointer.Y / 2) * InteractionRegionHeight)
|
||||||
|
);
|
||||||
|
RightHand.Depth = handPointer.RawZ;
|
||||||
|
RightHand.PrevIsClosed = RightHand.IsClosed;
|
||||||
|
|
||||||
|
if(handPointer.HandEventType != InteractionHandEventType.None) {
|
||||||
|
if (handPointer.HandEventType.ToString() == "Grip")
|
||||||
|
RightHand.IsClosed = true;
|
||||||
|
else
|
||||||
|
RightHand.IsClosed = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LeftHand.Pos = new Point(
|
||||||
|
(int) ((handPointer.X / 2) * InteractionRegionWidth),
|
||||||
|
(int) ((handPointer.Y / 2) * InteractionRegionHeight)
|
||||||
|
);
|
||||||
|
LeftHand.Depth = handPointer.RawZ;
|
||||||
|
LeftHand.PrevIsClosed = LeftHand.IsClosed;
|
||||||
|
|
||||||
|
if (handPointer.HandEventType != InteractionHandEventType.None) {
|
||||||
|
if (handPointer.HandEventType.ToString() == "Grip")
|
||||||
|
LeftHand.IsClosed = true;
|
||||||
|
else
|
||||||
|
LeftHand.IsClosed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var id in this.trackedUsers) {
|
||||||
|
if (!currentUserSet.Contains(id)) {
|
||||||
|
usersToRemove.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var id in usersToRemove) {
|
||||||
|
this.trackedUsers.Remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Processing
|
||||||
|
}
|
||||||
|
}
|
26
Game/InterruptorObject.cs
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class InterruptorObject : DynamicObject {
|
||||||
|
public CollisionStrategy CollisionStrategy {get; private set;}
|
||||||
|
|
||||||
|
public InterruptorObject(string filepath, Vector3 pos, Quaternion rot, Scene scene, ShapeType shapeType, bool isStatic, TargetingStrategy tstrategy, CollisionStrategy cstrategy)
|
||||||
|
: base(filepath, pos, rot, scene, shapeType, isStatic, tstrategy) {
|
||||||
|
CollisionStrategy = cstrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InterruptorObject(string filepath, Scene scene, ShapeType shapeType)
|
||||||
|
: this(filepath, Vector3.Zero, Quaternion.Identity, scene, shapeType, false, new NoTargetingStrategy(), new NoCollisionStrategy()) {}
|
||||||
|
|
||||||
|
public void Collision(DynamicObject obj) {
|
||||||
|
CollisionStrategy.Collision(this, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(GameTime gameTime) {
|
||||||
|
CollisionStrategy.Update(this, gameTime);
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
Game/NoCollisionStrategy.cs
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class NoCollisionStrategy : CollisionStrategy {
|
||||||
|
public void Update(InterruptorObject obj, GameTime gameTime) {
|
||||||
|
// NO OP
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Collision(InterruptorObject hostObj, DynamicObject obj) {
|
||||||
|
// NO OP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
Game/NoTargetingStrategy.cs
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class NoTargetingStrategy : TargetingStrategy {
|
||||||
|
public void Update(DynamicObject obj, GameTime gameTime) {
|
||||||
|
// NO OP
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Target(DynamicObject obj, HandsProjection leftHand, HandsProjection rightHand) {
|
||||||
|
// NO OP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
Game/Object.cs
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public abstract class Object : DrawableGameComponent {
|
||||||
|
public string FilePath {get; private set;}
|
||||||
|
public Scene Scene {get; private set;}
|
||||||
|
public Model Model {get; private set;}
|
||||||
|
|
||||||
|
private Matrix[] m_world;
|
||||||
|
|
||||||
|
public abstract Vector3 Pos {get; set;}
|
||||||
|
public abstract Quaternion Rot {get; set;}
|
||||||
|
|
||||||
|
public bool EnableLighting {get; set;}
|
||||||
|
|
||||||
|
public Object(string filepath, Scene scene)
|
||||||
|
: base(scene.Game) {
|
||||||
|
FilePath = filepath;
|
||||||
|
Scene = scene;
|
||||||
|
Model = Game.Content.Load<Model>(FilePath);
|
||||||
|
|
||||||
|
m_world = new Matrix[Model.Bones.Count];
|
||||||
|
Model.CopyAbsoluteBoneTransformsTo(m_world);
|
||||||
|
EnableLighting = true;
|
||||||
|
UpdateOrder = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(GameTime gameTime) {
|
||||||
|
BlendState bs = new BlendState();
|
||||||
|
bs.AlphaBlendFunction = BlendFunction.Add;
|
||||||
|
bs.AlphaSourceBlend = Blend.SourceAlpha;
|
||||||
|
bs.ColorSourceBlend = Blend.SourceAlpha;
|
||||||
|
bs.AlphaDestinationBlend = Blend.InverseSourceAlpha;
|
||||||
|
bs.ColorDestinationBlend = Blend.InverseSourceAlpha;
|
||||||
|
Game.GraphicsDevice.BlendState = bs;
|
||||||
|
Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
Game.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
|
||||||
|
|
||||||
|
foreach(ModelMesh mesh in Model.Meshes) {
|
||||||
|
foreach(BasicEffect effect in mesh.Effects) {
|
||||||
|
if(EnableLighting) {
|
||||||
|
effect.EnableDefaultLighting();
|
||||||
|
effect.PreferPerPixelLighting = true;
|
||||||
|
} else {
|
||||||
|
effect.LightingEnabled = false;
|
||||||
|
}
|
||||||
|
effect.World = m_world[mesh.ParentBone.Index] *
|
||||||
|
Matrix.CreateFromQuaternion(Rot) * Matrix.CreateTranslation(Pos);
|
||||||
|
effect.View = Scene.Camera.LookAtMatrix;
|
||||||
|
effect.Projection = Scene.Camera.ProjectionMatrix;
|
||||||
|
}
|
||||||
|
mesh.Draw();
|
||||||
|
}
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
Game/Portal.cs
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class Portal : InterruptorObject {
|
||||||
|
public Vector3 Normal {
|
||||||
|
get {
|
||||||
|
return Vector3.Transform(new Vector3(1, 0, 0), Rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 Up {
|
||||||
|
get {
|
||||||
|
return Vector3.Transform(new Vector3(0, 0, 1), Rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Portal(string filepath, Vector3 pos, Quaternion rot, Scene scene)
|
||||||
|
: base(filepath, pos, rot, scene, ShapeType.TRIANGULATE, true, new NoTargetingStrategy(), new PortalCollisionStrategy()) {}
|
||||||
|
|
||||||
|
public Portal(string filepath, Scene scene)
|
||||||
|
: this(filepath, Vector3.Zero, Quaternion.Identity, scene) {}
|
||||||
|
}
|
||||||
|
}
|
54
Game/PortalCollisionStrategy.cs
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Jitter.LinearMath;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class PortalCollisionStrategy : CollisionStrategy {
|
||||||
|
public void Update(InterruptorObject obj, GameTime gameTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Collision(InterruptorObject hostObj, DynamicObject obj) {
|
||||||
|
Portal inPortal = null;
|
||||||
|
Portal outPortal = null;
|
||||||
|
|
||||||
|
if(obj.IsStatic == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hostObj == hostObj.Scene.PortalManager.BluePortal) {
|
||||||
|
inPortal = (Portal) hostObj;
|
||||||
|
outPortal = hostObj.Scene.PortalManager.RedPortal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hostObj == hostObj.Scene.PortalManager.RedPortal) {
|
||||||
|
inPortal = (Portal) hostObj;
|
||||||
|
outPortal = hostObj.Scene.PortalManager.BluePortal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inPortal != null && outPortal != null) {
|
||||||
|
Vector3 relPos = obj.Pos - inPortal.Pos;
|
||||||
|
if(Vector3.Dot(Vector3.Normalize(relPos), inPortal.Normal) < 0.35f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 axis;
|
||||||
|
Quaternion rot;
|
||||||
|
if(inPortal.Rot == outPortal.Rot) {
|
||||||
|
rot = Quaternion.Identity;
|
||||||
|
axis = outPortal.Up;
|
||||||
|
} else {
|
||||||
|
rot = outPortal.Rot * Quaternion.Conjugate(inPortal.Rot);
|
||||||
|
//axis = Geometry.GetRotationAxis(rot);
|
||||||
|
axis = outPortal.Up;
|
||||||
|
}
|
||||||
|
obj.Pos = outPortal.Pos + Vector3.Transform(relPos, rot) * 1.2f;
|
||||||
|
Quaternion rot2 = rot * Quaternion.CreateFromAxisAngle(axis, (float) Math.PI);
|
||||||
|
obj.Rot = obj.Rot * rot2;
|
||||||
|
Vector3 vel = Geometry.GetXnaVector(obj.PhysicModel.LinearVelocity);
|
||||||
|
obj.PhysicModel.LinearVelocity = Geometry.GetJitterVector(Vector3.Transform(-vel, rot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
Game/PortalManager.cs
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class PortalManager {
|
||||||
|
public enum PortalType {RED, BLUE};
|
||||||
|
|
||||||
|
public Scene Scene {get; private set;}
|
||||||
|
public Portal BluePortal {get; private set;}
|
||||||
|
public Portal RedPortal {get; private set;}
|
||||||
|
|
||||||
|
public PortalManager(Scene scene) {
|
||||||
|
BluePortal = null;
|
||||||
|
RedPortal = null;
|
||||||
|
Scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreatePortal(Vector3 pos, Quaternion rot, PortalType type) {
|
||||||
|
if(type == PortalType.RED) {
|
||||||
|
if(RedPortal == null) {
|
||||||
|
RedPortal = new Portal("models\\portal_red", Vector3.Zero, Quaternion.Identity, Scene);
|
||||||
|
Scene.AddComponent(RedPortal);
|
||||||
|
}
|
||||||
|
RedPortal.Pos = pos;
|
||||||
|
RedPortal.Rot = rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == PortalType.BLUE) {
|
||||||
|
if(BluePortal == null) {
|
||||||
|
BluePortal = new Portal("models\\portal_blue", Vector3.Zero, Quaternion.Identity, Scene);
|
||||||
|
Scene.AddComponent(BluePortal);
|
||||||
|
}
|
||||||
|
BluePortal.Pos = pos;
|
||||||
|
BluePortal.Rot = rot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Game/Program.cs
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Kinect.Toolkit.Interaction;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
#if WINDOWS || XBOX
|
||||||
|
static class Program {
|
||||||
|
static void Main(string[] args) {
|
||||||
|
using (Game game = new Game()) {
|
||||||
|
game.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
34
Game/Properties/AssemblyInfo.cs
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("WindowsGame1")]
|
||||||
|
[assembly: AssemblyProduct("WindowsGame1")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type. Only Windows
|
||||||
|
// assemblies support COM.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// On Windows, the following GUID is for the ID of the typelib if this
|
||||||
|
// project is exposed to COM. On other platforms, it unique identifies the
|
||||||
|
// title storage container when deploying this assembly to the device.
|
||||||
|
[assembly: Guid("0de3b11f-46e3-4b73-994f-c11a55bf2224")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
161
Game/Scene.cs
Executable file
@ -0,0 +1,161 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Jitter;
|
||||||
|
using Jitter.LinearMath;
|
||||||
|
using Jitter.Collision;
|
||||||
|
using Jitter.Dynamics;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class Scene : DrawableGameComponent {
|
||||||
|
private Camera m_camera = null;
|
||||||
|
public Camera Camera {
|
||||||
|
get {
|
||||||
|
return m_camera;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if(m_camera != null) {
|
||||||
|
Game.Components.Remove(m_camera);
|
||||||
|
}
|
||||||
|
m_camera = value;
|
||||||
|
Game.Components.Add(m_camera);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DrawableGameComponent> Components {get; private set;}
|
||||||
|
public World PhysicWorld {get; private set;}
|
||||||
|
public PortalManager PortalManager {get; private set;}
|
||||||
|
|
||||||
|
public Scene(KinPortal.Game game, Camera camera)
|
||||||
|
: base(game) {
|
||||||
|
Camera = camera;
|
||||||
|
Components = new List<DrawableGameComponent>();
|
||||||
|
PhysicWorld = new World(new CollisionSystemSAP());
|
||||||
|
PhysicWorld.Gravity = new JVector(0, 0, -9.81f);
|
||||||
|
PortalManager = new PortalManager(this);
|
||||||
|
PhysicWorld.CollisionSystem.CollisionDetected += this.CollisionEvent;
|
||||||
|
UpdateOrder = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddComponent(DrawableGameComponent obj) {
|
||||||
|
Components.Add(obj);
|
||||||
|
Game.Components.Add(obj);
|
||||||
|
if(obj is DynamicObject) {
|
||||||
|
PhysicWorld.AddBody(((DynamicObject) obj).PhysicModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveComponent(DrawableGameComponent obj) {
|
||||||
|
Components.Remove(obj);
|
||||||
|
Game.Components.Remove(obj);
|
||||||
|
if(obj is DynamicObject) {
|
||||||
|
PhysicWorld.RemoveBody(((DynamicObject) obj).PhysicModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool RaycastCallback(RigidBody body, JVector normal, float fraction) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(GameTime gameTime) {
|
||||||
|
float phyStep = gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
|
||||||
|
PhysicWorld.Step(phyStep, true);
|
||||||
|
|
||||||
|
KinPortal.Game game = (KinPortal.Game) Game;
|
||||||
|
|
||||||
|
JVector ray;
|
||||||
|
float fraction;
|
||||||
|
JVector normal;
|
||||||
|
HandsProjection leftHand = new HandsProjection();
|
||||||
|
HandsProjection rightHand = new HandsProjection();
|
||||||
|
JVector camPos = Geometry.GetJitterVector(Camera.Pos);
|
||||||
|
RigidBody leftBody = null, rightBody = null;
|
||||||
|
|
||||||
|
/* Left Hand projection */
|
||||||
|
ray = Geometry.GetJitterVector(Camera.Unproject(game.HandsTracker.LeftHand.Pos.X, game.HandsTracker.LeftHand.Pos.Y));
|
||||||
|
ray = JVector.Normalize(ray) * 100.0f;
|
||||||
|
|
||||||
|
if(PhysicWorld.CollisionSystem.Raycast(camPos, ray, RaycastCallback, out leftBody, out normal, out fraction)) {
|
||||||
|
leftHand.HitPoint = Geometry.GetXnaVector(camPos + fraction * ray);
|
||||||
|
leftHand.HitNormal = Geometry.GetXnaVector(JVector.Normalize(normal));
|
||||||
|
leftHand.IsProjected = true;
|
||||||
|
} else {
|
||||||
|
leftHand.IsProjected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right Hand projection */
|
||||||
|
ray = Geometry.GetJitterVector(Camera.Unproject(game.HandsTracker.RightHand.Pos.X, game.HandsTracker.RightHand.Pos.Y));
|
||||||
|
ray = JVector.Normalize(ray) * 100.0f;
|
||||||
|
|
||||||
|
if(PhysicWorld.CollisionSystem.Raycast(camPos, ray, RaycastCallback, out rightBody, out normal, out fraction)) {
|
||||||
|
rightHand.HitPoint = Geometry.GetXnaVector(camPos + fraction * ray);
|
||||||
|
rightHand.HitNormal = Geometry.GetXnaVector(JVector.Normalize(normal));
|
||||||
|
rightHand.IsProjected = true;
|
||||||
|
} else {
|
||||||
|
rightHand.IsProjected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicObject leftObj = null, rightObj = null;
|
||||||
|
|
||||||
|
foreach(DrawableGameComponent obj in Components) {
|
||||||
|
if(obj is DynamicObject) {
|
||||||
|
DynamicObject dobj = (DynamicObject) obj;
|
||||||
|
if(dobj.PhysicModel == leftBody) {
|
||||||
|
leftObj = dobj;
|
||||||
|
}
|
||||||
|
if(dobj.PhysicModel == rightBody) {
|
||||||
|
rightObj = dobj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(leftObj == rightObj && leftObj != null) {
|
||||||
|
leftObj.Target(leftHand, rightHand);
|
||||||
|
} else {
|
||||||
|
if(leftObj != null) {
|
||||||
|
leftObj.Target(leftHand, new HandsProjection(false, Vector3.Zero, Vector3.Zero));
|
||||||
|
}
|
||||||
|
if(rightObj != null) {
|
||||||
|
rightObj.Target(new HandsProjection(false, Vector3.Zero, Vector3.Zero), rightHand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CollisionEvent(RigidBody body1, RigidBody body2, JVector point1, JVector point2, JVector normal, float penetration) {
|
||||||
|
DynamicObject dobj1 = null;
|
||||||
|
DynamicObject dobj2 = null;
|
||||||
|
|
||||||
|
foreach(DrawableGameComponent obj in Components) {
|
||||||
|
if(obj is DynamicObject) {
|
||||||
|
DynamicObject dobj = (DynamicObject) obj;
|
||||||
|
if(dobj.PhysicModel == body1) {
|
||||||
|
dobj1 = dobj;
|
||||||
|
}
|
||||||
|
if(dobj.PhysicModel == body2) {
|
||||||
|
dobj2 = dobj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dobj1 == null || dobj2 == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dobj1 is InterruptorObject) {
|
||||||
|
((InterruptorObject) dobj1).Collision(dobj2);
|
||||||
|
}
|
||||||
|
if(dobj2 is InterruptorObject) {
|
||||||
|
((InterruptorObject) dobj2).Collision(dobj1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(GameTime gameTime) {
|
||||||
|
foreach(DrawableGameComponent obj in Components) {
|
||||||
|
obj.Draw(gameTime);
|
||||||
|
}
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
Game/ShapeFactory.cs
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Jitter.LinearMath;
|
||||||
|
using Jitter.Collision;
|
||||||
|
using Jitter.Collision.Shapes;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public enum ShapeType {BOX, SPHERE, TRIANGULATE}
|
||||||
|
|
||||||
|
public static class ShapeFactory {
|
||||||
|
public static Shape CreateShape(Model mdl, ShapeType type) {
|
||||||
|
Geometry geo = new Geometry(mdl);
|
||||||
|
|
||||||
|
if(type == ShapeType.BOX) {
|
||||||
|
BoundingBox box = geo.Box;
|
||||||
|
JVector vsize = Geometry.GetJitterVector(box.Max - box.Min);
|
||||||
|
return new BoxShape(vsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == ShapeType.SPHERE) {
|
||||||
|
return new SphereShape(geo.Sphere.Radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == ShapeType.TRIANGULATE) {
|
||||||
|
return new TriangleMeshShape(new Octree(geo.JVertices, geo.JTriangles));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
Game/SimpleObject.cs
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class SimpleObject : Object {
|
||||||
|
public override Vector3 Pos {get; set;}
|
||||||
|
public override Quaternion Rot {get; set;}
|
||||||
|
|
||||||
|
public SimpleObject(string filepath, Vector3 pos, Quaternion rot, Scene scene)
|
||||||
|
: base(filepath, scene) {
|
||||||
|
Pos = pos;
|
||||||
|
Rot = rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleObject(string filepath, Scene scene)
|
||||||
|
: this(filepath, Vector3.Zero, Quaternion.Identity, scene) {}
|
||||||
|
}
|
||||||
|
}
|
39
Game/TargetCollisionStrategy.cs
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal {
|
||||||
|
public class TargetCollisionStrategy : CollisionStrategy {
|
||||||
|
private TimeSpan m_reloadTime;
|
||||||
|
private bool m_lock = false;
|
||||||
|
|
||||||
|
|
||||||
|
public void Update(InterruptorObject obj, GameTime gameTime) {
|
||||||
|
if(m_lock) {
|
||||||
|
m_reloadTime += gameTime.ElapsedGameTime;
|
||||||
|
if(m_reloadTime.Milliseconds >= 300.0) {
|
||||||
|
m_lock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Collision(InterruptorObject hostObj, DynamicObject obj) {
|
||||||
|
if(obj.IsStatic == true || m_lock) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicObject o = new DynamicObject(
|
||||||
|
"models\\monkey",
|
||||||
|
new Vector3(0, 0, 8.0f), Quaternion.Identity,
|
||||||
|
hostObj.Scene, ShapeType.SPHERE, false, new GrabStrategy()
|
||||||
|
);
|
||||||
|
|
||||||
|
//o.PhysicModel.AffectedByGravity = false;
|
||||||
|
|
||||||
|
hostObj.Scene.AddComponent(o);
|
||||||
|
|
||||||
|
m_lock = true;
|
||||||
|
m_reloadTime = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Game/TargetingStrategy.cs
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
using Jitter.Collision;
|
||||||
|
using Jitter.LinearMath;
|
||||||
|
using Jitter.Dynamics;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KinPortal{
|
||||||
|
public interface TargetingStrategy {
|
||||||
|
void Update(DynamicObject obj, GameTime gameTime);
|
||||||
|
void Target(DynamicObject obj, HandsProjection lefthand, HandsProjection righthand);
|
||||||
|
}
|
||||||
|
}
|
40
KinPortal.sln
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2013
|
||||||
|
VisualStudioVersion = 12.0.31101.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Game", "Game\Game.csproj", "{FAA2E885-42FD-49FD-8678-925331BBE9C8}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Resources", "Resources\Resources.contentproj", "{75D6A435-2F46-4192-B2B7-37A17468C066}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|Mixed Platforms = Release|Mixed Platforms
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{FAA2E885-42FD-49FD-8678-925331BBE9C8}.Release|x86.Build.0 = Release|x86
|
||||||
|
{75D6A435-2F46-4192-B2B7-37A17468C066}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{75D6A435-2F46-4192-B2B7-37A17468C066}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
|
{75D6A435-2F46-4192-B2B7-37A17468C066}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{75D6A435-2F46-4192-B2B7-37A17468C066}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{75D6A435-2F46-4192-B2B7-37A17468C066}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
|
{75D6A435-2F46-4192-B2B7-37A17468C066}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
139
Resources/Resources.contentproj
Executable file
@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectGuid>{75D6A435-2F46-4192-B2B7-37A17468C066}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{96E2B04D-8817-42c6-938A-82C39BA4D311};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
|
||||||
|
<OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
|
||||||
|
<ContentRootDirectory>Resources</ContentRootDirectory>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<RootNamespace>WindowsGame1Content</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.EffectImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.FBXImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.TextureImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.XImporter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.AudioImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.Xna.Framework.Content.Pipeline.VideoImporters, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=MSIL" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="models\monkey.fbx">
|
||||||
|
<Name>monkey</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="textures\tex_wall.png">
|
||||||
|
<Name>tex_wall</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="models\cube.fbx">
|
||||||
|
<Name>cube</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="models\sphere.fbx">
|
||||||
|
<Name>sphere</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="textures\tex_cursor_blue.png">
|
||||||
|
<Name>tex_cursor_blue</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="textures\tex_cursor_red.png">
|
||||||
|
<Name>tex_cursor_red</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="textures\tex_floor.png">
|
||||||
|
<Name>tex_floor</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="textures\tex_roof.png">
|
||||||
|
<Name>tex_roof</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="models\level.fbx">
|
||||||
|
<Name>level</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="textures\tex_portal_blue.png">
|
||||||
|
<Name>tex_portal_blue</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="textures\tex_portal_red.png">
|
||||||
|
<Name>tex_portal_red</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="models\portal_blue.fbx">
|
||||||
|
<Name>portal_blue</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="models\portal_red.fbx">
|
||||||
|
<Name>portal_red</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="textures\tex_target.png">
|
||||||
|
<Name>tex_target</Name>
|
||||||
|
<Importer>TextureImporter</Importer>
|
||||||
|
<Processor>TextureProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="models\target.fbx">
|
||||||
|
<Name>target</Name>
|
||||||
|
<Importer>FbxImporter</Importer>
|
||||||
|
<Processor>ModelProcessor</Processor>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
BIN
Resources/level.blend
Executable file
BIN
Resources/models/cube.fbx
Executable file
BIN
Resources/models/level.fbx
Executable file
BIN
Resources/models/monkey.fbx
Executable file
BIN
Resources/models/portal_blue.fbx
Executable file
BIN
Resources/models/portal_red.fbx
Executable file
BIN
Resources/models/sphere.fbx
Executable file
BIN
Resources/models/target.fbx
Executable file
BIN
Resources/portal.blend
Executable file
BIN
Resources/target.blend
Executable file
BIN
Resources/textures/tex_cursor_blue.png
Executable file
After Width: | Height: | Size: 31 KiB |
BIN
Resources/textures/tex_cursor_red.png
Executable file
After Width: | Height: | Size: 31 KiB |
BIN
Resources/textures/tex_floor.png
Executable file
After Width: | Height: | Size: 507 KiB |
BIN
Resources/textures/tex_portal_blue.png
Executable file
After Width: | Height: | Size: 41 KiB |
BIN
Resources/textures/tex_portal_red.png
Executable file
After Width: | Height: | Size: 35 KiB |
BIN
Resources/textures/tex_roof.png
Executable file
After Width: | Height: | Size: 558 KiB |
BIN
Resources/textures/tex_target.png
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
Resources/textures/tex_wall.png
Executable file
After Width: | Height: | Size: 2.1 MiB |