Commit initial

This commit is contained in:
2020-05-15 12:18:51 +02:00
commit 8e6c723751
46 changed files with 1857 additions and 0 deletions
Executable
+135
View 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
View 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);
}
}
Executable
+39
View 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
View 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
View 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);
}
}
}
Executable
+164
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
}
}
}
Executable
+58
View 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);
}
}
}
Executable
+24
View 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
View 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
View 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
View 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
View 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")]
Executable
+161
View 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
View 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
View 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
View 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
View 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);
}
}
Executable
+40
View 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
View 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
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB