162 lines
4.8 KiB
C#
Executable File
162 lines
4.8 KiB
C#
Executable File
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);
|
|
}
|
|
}
|
|
}
|