KinPortal/Game/GrapStrategy.cs
2020-05-15 12:18:51 +02:00

103 lines
4.1 KiB
C#
Executable File

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;
}
}
}
}