Advertisement
Krythic

Camera Collision Detection (Over penetrates)

Jul 9th, 2021
2,015
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.51 KB | None | 0 0
  1. private void ProcessCameraCollisions(Vector3 previousCameraLocation)
  2.         {
  3.             /**
  4.              * Process Camera Collisions
  5.              */
  6.             if (Camera.IsCollisionEnabled)
  7.             {
  8.                 Vector3 currentCameraLocation = this.Camera.Location;
  9.                 float finalCameraLocationX = currentCameraLocation.X;
  10.                 float finalCameraLocationY = currentCameraLocation.Y;
  11.                 float finalCameraLocationZ = currentCameraLocation.Z;
  12.                 bool hasXCollision = false;
  13.                 bool hasYCollision = false;
  14.                 bool hasZCollision = false;
  15.                 BoundingSphere cameraBounds = Camera.HardBounds;
  16.                 Vector3 velocity = currentCameraLocation - previousCameraLocation;
  17.                 Ray cameraRay = new Ray(previousCameraLocation,currentCameraLocation);
  18.                 foreach (StaticGeometry geometry in this.StaticGeometry)
  19.                 {
  20.                     if (geometry.IsCollidable)
  21.                     {
  22.                         if (Vector3.Distance(geometry.Location, currentCameraLocation) <= Camera.CollisionDistance)
  23.                         {
  24.                             if (cameraBounds.Intersects(geometry.BoundingBox.ToBoundingBox()))
  25.                             {
  26.                                 // Create the rotation matrix using the geometry's current rotation setting.
  27.                                 Matrix rotationMatrix = VoidwalkerMath.CreateRotationMatrix(geometry.Rotation);
  28.                                 for (int i = 0; i < geometry.Mesh.Vertices.Length; i += 3)
  29.                                 {
  30.                                     // Get the Vertex Positions for the current Triangle
  31.                                     Vector3 position1 = geometry.Mesh.Vertices[i].Location;
  32.                                     Vector3 position2 = geometry.Mesh.Vertices[i + 1].Location;
  33.                                     Vector3 position3 = geometry.Mesh.Vertices[i + 2].Location;
  34.                                     // Transform the Coordinate with the Rotation Matrix, then add the geometry's location
  35.                                     Vector3 finalVertexLocation1 = Vector3.TransformCoordinate(position1, rotationMatrix) + geometry.Location;
  36.                                     Vector3 finalVertexLocation2 = Vector3.TransformCoordinate(position2, rotationMatrix) + geometry.Location;
  37.                                     Vector3 finalVertexLocation3 = Vector3.TransformCoordinate(position3, rotationMatrix) + geometry.Location;
  38.  
  39.                                     Vector3 normal = Vector3.Cross(finalVertexLocation2 - finalVertexLocation1, finalVertexLocation3 - finalVertexLocation1);
  40.                                     if (Vector3.Dot(velocity, normal) < 0)
  41.                                     {
  42.                                         Vector3 translationX = new Vector3(currentCameraLocation.X, previousCameraLocation.Y, previousCameraLocation.Z);
  43.                                         Vector3 translationY = new Vector3(previousCameraLocation.X, currentCameraLocation.Y, previousCameraLocation.Z);
  44.                                         Vector3 translationZ = new Vector3(previousCameraLocation.X, previousCameraLocation.Y, currentCameraLocation.Z);
  45.                                         // Test X
  46.  
  47.                                         BoundingSphere sphereX = new BoundingSphere(translationX, Camera.HardBoundsRadius);
  48.                                         if (sphereX.Intersects(ref finalVertexLocation1, ref finalVertexLocation2, ref finalVertexLocation3))
  49.                                         {
  50.                                             finalCameraLocationX = previousCameraLocation.X;
  51.                                             hasXCollision = true;
  52.                                             this.Camera.Velocity = Vector3.Zero;
  53.                                         }
  54.                                         // Test Y
  55.                                         BoundingSphere sphereY = new BoundingSphere(translationY, Camera.HardBoundsRadius);
  56.                                         if (sphereY.Intersects(ref finalVertexLocation1, ref finalVertexLocation2, ref finalVertexLocation3))
  57.                                         {
  58.                                             finalCameraLocationY = previousCameraLocation.Y;
  59.                                             hasYCollision = true;
  60.                                             this.Camera.Velocity = Vector3.Zero;
  61.                                         }
  62.                                         // Test Z
  63.                                         BoundingSphere sphereZ = new BoundingSphere(translationZ, Camera.HardBoundsRadius);
  64.                                         if (sphereZ.Intersects(ref finalVertexLocation1, ref finalVertexLocation2, ref finalVertexLocation3))
  65.                                         {
  66.                                             finalCameraLocationZ = previousCameraLocation.Z;
  67.                                             hasZCollision = true;
  68.                                             this.Camera.Velocity = Vector3.Zero;
  69.                                         }
  70.  
  71.                                         /**
  72.                                          * Edge case early termination. If the camera is already colliding
  73.                                          * on all axis, we don't need to test for any further collisions. This seems
  74.                                          * to only trigger when the player is wedged in a corner.
  75.                                          */
  76.                                         if (hasXCollision && hasYCollision && hasZCollision)
  77.                                         {
  78.                                             this.Camera.Location = new Vector3(
  79.                                                     finalCameraLocationX,
  80.                                                     finalCameraLocationY,
  81.                                                     finalCameraLocationZ);
  82.                                             return;
  83.                                         }
  84.                                     }
  85.                                 }
  86.                             }
  87.                         }
  88.                     }
  89.                     this.Camera.Location = new Vector3(
  90.                         finalCameraLocationX,
  91.                         finalCameraLocationY,
  92.                         finalCameraLocationZ);
  93.                     OnCameraChanged();
  94.                 }
  95.             }
  96.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement