# Problem with per-triangle collision detection when geometry is rotated

For my game, I am attempting to implement per-triangle collision detection with the camera. It appears as though the code is mostly working, in that non-rotated geometry is correctly hit-tested, and stops the camera. However, the problem arises when I attempt to move the camera into any piece of rotated geometry. I’m going to provide a few pictures to help illustrate my problem, as well as the code that I’m currently using for collision detection. It should be noted that I’m using SharpDX as a 3D library.

In this picture, I am correctly hit-testing the wall beside me. I cannot penetrate it from any direction. This piece of geometry is not rotated.

In this picture I am correctly hit-testing the floor below me. Again, it is not rotated.

In this picture, I circle a series of pieces of geometry, all of which are rotated by 270 degrees on the Y axis. I can pass right through these pieces.

In this picture I am hitting something head-on, which is causing my hit-detection to trigger. You will see in the next picture what this "something" is.

Finally, here is a picture of those pieces of rotated geometry without rotation. I correctly hit-detect them in this state. When they’re rotated, the hitboxes remain in the same location as you visually see them in this picture, which is why I hit "something" in front of them.

Here is my current code for camera hit detection (Updated for better readability):

if (isCameraMoving)
{
foreach (StaticGeometry geometry in this.StaticGeometry)
{
BoundingSphere cameraSphere = Camera.Bounds;
for (int i = 0; i < geometry.Mesh.Vertices.Length; i += 3)
{
// Get the Vertex Positions for the current Triangle
Vector3 position1 = geometry.Mesh.Vertices[i].Location;
Vector3 position2 = geometry.Mesh.Vertices[i + 1].Location;
Vector3 position3 = geometry.Mesh.Vertices[i + 2].Location;

// Create the rotation matrix using the geometry's current rotation setting.
Matrix rotationMatrix = VoidwalkerMath.CreateRotationMatrix(geometry.Rotation);

// rotate and translate each vertex
Matrix matrix1 = rotationMatrix * Matrix.Translation(position1 + geometry.Location);
Matrix matrix2 = rotationMatrix * Matrix.Translation(position2 + geometry.Location);
Matrix matrix3 = rotationMatrix * Matrix.Translation(position3 + geometry.Location);

// extract the new position from the rotated and translated Matrices.
Vector3 finalVertexLocation1 = matrix1.TranslationVector;
Vector3 finalVertexLocation2 = matrix2.TranslationVector;
Vector3 finalVertexLocation3 = matrix3.TranslationVector;

// Do hit detection for a triangle.
if (cameraSphere.Intersects(ref finalVertexLocation1, ref finalVertexLocation2, ref finalVertexLocation3))
{
this.Camera.Location = previousCameraPosition;
return;
}
}
}
}


And my code for creating a rotation matrix. I’m positive this code works as intended, because it’s the same function I use for rotating my geometry.

/// <summary>
/// </summary>
/// <param name="degrees">The angle in degrees.</param>
{
return degrees / 360.0f * TwoPi;
}

/// <summary>
/// Creates a rotation matrix using degrees.
/// </summary>
/// <param name="xDegrees"></param>
/// <param name="yDegrees"></param>
/// <param name="zDegrees"></param>
/// <returns></returns>
public static Matrix CreateRotationMatrix(float xDegrees, float yDegrees, float zDegrees)
{
return
}

/// <summary>
/// Converts a Vector3 of Degrees to a Vector3 of Radians
/// </summary>
/// <param name="degrees"></param>
/// <returns></returns>
{
}


And here is my Vertex class. If you guys need anything else, just let me know.

using SharpDX;
using System.Runtime.InteropServices;

namespace VoidwalkerEngine.Framework.DirectX.Rendering
{
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{

public static Vertex Zero = new Vertex(Vector3.Zero,Vector2.Zero,Vector3.Zero);

public Vector3 Location;
public Vector2 TexCoords;
public Vector3 Normal;

public const int Size = 32;

public Vertex(Vector3 position, Vector2 texCoords, Vector3 normal)
{
this.Location = position;
this.Normal = normal;
this.TexCoords = texCoords;
}

public Vertex(Vertex other)
{
this.Location = other.Location;
this.Normal = other.Normal;
this.TexCoords = other.TexCoords;
}

public override string ToString()
{
return
"Location: " + Location.ToString() +
", TexCoords: " + TexCoords.ToString() +
", Normal: " + Normal.ToString();
}

}
}


I am clearly doing something wrong, but I don’t know what it could be. I’m rotating the vertices first, then translating them. Am I missing something here?

Stack Overflow Asked on November 15, 2021

So it turns out I was just being dumb. The way that you actually rotate a vertex is with Vector3.TransformCoordinate(); and feed it the rotation matrix of the model. Here is the updated and working code (Which is pretty glorious to see working in person).

if (isCameraMoving)
{
foreach (StaticGeometry geometry in this.StaticGeometry)
{
BoundingSphere cameraSphere = Camera.Bounds;
for (int i = 0; i < geometry.Mesh.Vertices.Length; i += 3)
{
// Get the Vertex Positions for the current Triangle
Vector3 position1 = geometry.Mesh.Vertices[i].Location;
Vector3 position2 = geometry.Mesh.Vertices[i + 1].Location;
Vector3 position3 = geometry.Mesh.Vertices[i + 2].Location;

// Create the rotation matrix using the geometry's current rotation setting.
Matrix rotationMatrix = VoidwalkerMath.CreateRotationMatrix(geometry.Rotation);

// Transform the Coordinate with the Rotation Matrix, then add the geometry's location
Vector3 finalVertexLocation1 = Vector3.TransformCoordinate(position1, rotationMatrix) + geometry.Location;
Vector3 finalVertexLocation2 = Vector3.TransformCoordinate(position2, rotationMatrix) + geometry.Location;
Vector3 finalVertexLocation3 = Vector3.TransformCoordinate(position3, rotationMatrix) + geometry.Location;

// Do hit detection for a triangle.
if (cameraSphere.Intersects(ref finalVertexLocation1, ref finalVertexLocation2, ref finalVertexLocation3))
{
this.Camera.Location = previousCameraPosition;
return;
}
}
}
}


Answered by Krythic on November 15, 2021

## Related Questions

### StackOverflowException when big numbers in recursive algorithm. Optimization?

1  Asked on August 4, 2020 by ivan-g

### Animate gradient bar chart – matplotlib

1  Asked on August 4, 2020 by jonboy

### c# error – Can not convert Array to byte array

1  Asked on August 2, 2020 by rakesh

### Is there a way to store a template variable from constructor for later use? (c++)

1  Asked on August 2, 2020

### JavaScript Inner Anonymous Function Cannot Access Member?

2  Asked on August 2, 2020 by phil

1  Asked on August 2, 2020 by jonathan-rauscher

### Why does the new version of ffmpeg play non-interleaved http files so stuck?

0  Asked on August 1, 2020 by fredirty2017

### Succinctly calculate differences between all datetime columns in a row

0  Asked on August 1, 2020 by visionary_20

### How to cut a string to the first “/” from right to left c# .net

1  Asked on August 1, 2020 by ignacio-gomez

### Inserting random data from a list

2  Asked on August 1, 2020 by smiley

### How to exit Java stream processing after a required number of results?

1  Asked on July 31, 2020 by mandroid

### Invalid token SELECT

2  Asked on July 31, 2020 by virendra-varma

### Failing the mock method return with arguments as Parameter

2  Asked on July 30, 2020 by podoi17

### Django – No column found for custom field?

0  Asked on July 29, 2020 by jare42

### Package.json with multiple entrypoints

1  Asked on July 29, 2020 by jeanluca-scaljeri

### REACT vs REACT_PROJECT vs WEBPACK for storybook type?

1  Asked on July 29, 2020 by temporary_user_name

### Random Background Image from Button Click

1  Asked on July 29, 2020 by charmy

### Systemd-journald disk wear-out

0  Asked on July 29, 2020 by rohit

### How to create a new python dictionary from loop results without overwrite

1  Asked on July 29, 2020 by anderson-soares