Physics Camera Help

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Spykam22
Posts: 13
Joined: Fri Dec 09, 2011 9:48 pm

Physics Camera Help

Post by Spykam22 »

Hello!

I am working on a game for PSM and I am using BEPU Physics. Everything's been going well so far. The player is affected by gravity, but I am able to walk through walls. How would I prevent this? What do I need to add to the code below? Thanks! :)

Code: Select all

public class Camera3D : Capsule
	{
		Vector3 forwardVector;
		public Vector3 Forward 
		{
			get { return -forwardVector; }
		}
		public Vector3 Target = Vector3.Zero;

		public Matrix4 ViewMatrix, ProjectionMatrix;
		public BoundingSphere Bounds;
		
		public float Yaw = 0.0f;
		public float Pitch = 0.0f;
		
		/// <summary>
		/// The move speed. Default is 6.
		/// </summary>
		public float MoveSpeed = 6;
		/// <summary>
		/// The jump velocity. Default is 60. Recommeded ForceUpdater.Gravity Value: (0, -90.81, 0))
		/// </summary>
		public float JumpVelocity = 60;
		public float Sensitivity = 5;
		
		public bool Active;
		public bool TouchEnabled = true;
		public bool GamePadEnabled = true;
		public bool DebugMode = false;
		public bool LookXOnly = false;
		public bool LookYOnly = false;
		public bool InvertX = false;
		public bool InvertY = false;
		public bool Attached = false;
		public bool RenderTarget = false;
		
		private Matrix4 RotationMatrix;
		private Vector3 upVector;
		
		public Camera3D (Vector3 Start, float height, float radius) : base(Start.ToBEPUVector(), height, radius / 2)
		{
			this.BecomeDynamic(1);
			upVector = Vector3.UnitY;
			float aspect = GraphicsDevice.AspectRatio;
	        float fov = FMath.Radians(45.0f);
			
			ProjectionMatrix = Matrix4.Perspective(fov, aspect, 0.1f, 10000000.0f);
			
			this.LocalInertiaTensorInverse = new Matrix3X3();
			
			Active = true;
		}
		public void Update()
		{	
			if (this.Active)
				UpdateCamera();
		}
		
		private void UpdateCamera()
		{
			#region Touch
			if (TouchEnabled)
			{
				foreach (TouchData t in TouchHelper.Data)
				{
					if (t.Skip) continue;
				
					switch (t.Status)
					{
						case TouchStatus.Move:
						{
							if (LookYOnly && !LookXOnly)
							{
								if (InvertY)
									Yaw += (t.Y * (Sensitivity));
								else
									Yaw -= (t.Y * (Sensitivity));
							}
					
							if (LookXOnly && !LookYOnly)
							{
								if (InvertX)
									Pitch -= (t.X * (Sensitivity));
								else
									Pitch += (t.X * (Sensitivity));
							}	
						
							if (!LookXOnly && !LookYOnly)
							{
								if (InvertX)
									Pitch -= (t.X * (Sensitivity));
								else
									Pitch += (t.X * (Sensitivity));
							
								if (InvertY)
									Yaw += (t.Y * (Sensitivity));
								else
									Yaw -= (t.Y * (Sensitivity));
							}
						
					
							break;
						}
					}
				}
			}

			
			#endregion
			
			#region GamePad
		
			if (GamePadEnabled)
			{
				float xDiff = GamePadHelper.AnalogRightX;
				float yDiff = GamePadHelper.AnalogRightY;
				Yaw -= Sensitivity * xDiff;
				Pitch -= Sensitivity * yDiff;
				
				if (GamePadHelper.ButtonAreDown(GamePadButtons.Up))
					AddToCameraPosition(new Vector3(0, 0, -sensibility));
				
				if (GamePadHelper.ButtonAreDown(GamePadButtons.Down))
					AddToCameraPosition(new Vector3(0, 0, sensibility));
				
				if (RenderTarget)
				{
					if (GamePadHelper.ButtonAreDown(GamePadButtons.Left))
						AddToCameraPosition(new Vector3(sensibility, 0, 0));
				
					if (GamePadHelper.ButtonAreDown(GamePadButtons.Right))
						AddToCameraPosition(new Vector3(-sensibility, 0, 0));
				}
				else
				{
					if (GamePadHelper.ButtonAreDown(GamePadButtons.Left))
						AddToCameraPosition(new Vector3(-sensibility, 0, 0));
				
					if (GamePadHelper.ButtonAreDown(GamePadButtons.Right))
						AddToCameraPosition(new Vector3(sensibility, 0, 0));
				}
				
				if (GamePadHelper.ButtonIsDown(GamePadButtons.Cross))
					Jump();
			}	
			
			#endregion
			
			UpdateViewMatrix();
		}
		
		bool isCrouching = false;
		private float sensibility = 0.5f;
		private void UpdateViewMatrix()
		{
			RotationMatrix = Matrix4.RotationXyz(FMath.Radians(Yaw), FMath.Radians(Pitch), 0.0f);
			Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
			Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
			Vector3 cameraRotatedVector = Matrix4.TransformVector(RotationMatrix, cameraOriginalTarget);
			Target = Position.ToPSSVector() + cameraRotatedVector;
			upVector = Matrix4.TransformVector(RotationMatrix, cameraOriginalUpVector);
			forwardVector = cameraRotatedVector;
			ViewMatrix = Matrix4.LookAt(Position.ToPSSVector(), Target, upVector);
		}
		
		private void AddToCameraPosition(Vector3 vectorToAdd)
		{
			Vector3 rotatedVector = Matrix4.TransformVector(RotationMatrix, vectorToAdd);
			Position += MoveSpeed * rotatedVector.ToBEPUVector();
			UpdateViewMatrix();
		}
		
		private void Jump()
		{
			if (this.CollisionInformation.Pairs.Count >= 1)
				this.LinearVelocity += new Vector3D(0, JumpVelocity, 0);
		}
	}
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Physics Camera Help

Post by Norbo »

The entity is being teleported for movement. Collision response operates on velocity. A teleporting object's motion is not based on its velocity. So, collision response can't do anything to stop the object from going through a wall.

If you want to shove objects around, it should be done by changing the velocity or applying a force.

If you want a character, I would recommend just using the CharacterController.
Post Reply