I am prototyping a hover ship game and the goal is to have the ship smoothly adjust its orientation as it moves across terrain. Currently the C++ code uses quaternions to accurately snap the ship’s normal to the surface normal of the static mesh under the ship.
To achieve smooth orientation changes I am cast a ray downward to get the impact face, and then fetch vertex coordinates and vertex normals, and calculate the barycentric coordinate. However, I am having trouble using this information to calculate a vector to orient the ship to. I believe the vector should be a weighted sum of the vertex normals but my calculation at the end does not give the correct result.
Can you provide suggestions on how to calculate this vector? Here is a code snippet.
FStaticMeshVertexBuffers* VertexBuffers = &StaticMesh->GetRenderData()->LODResources[0].VertexBuffers;
FStaticMeshVertexBuffer* StaticMeshVertexBuffer = &VertexBuffers->StaticMeshVertexBuffer;
FPositionVertexBuffer* PositionVertexBuffer = &VertexBuffers->PositionVertexBuffer;
FIndexArrayView IndexBuffer = StaticMesh->GetRenderData()->LODResources[0].IndexBuffer.GetArrayView();
// Storage for the triangle vertices
FVector VertexPositions[3];
FVector VertexNormals[3];
for (int i = 0; i < 3; i++) {
// Get vertex index
uint32 index = IndexBuffer[FaceIndex * 3 + i];
// Get vertex position and normal
VertexPositions[i] = FVector(PositionVertexBuffer->VertexPosition(index));
VertexNormals[i] = FVector(StaticMeshVertexBuffer->VertexTangentZ(index));
// Transform position and normal into world space
VertexPositions[i] = ComponentTransform.TransformPosition(VertexPositions[i]);
VertexNormals[i] = ComponentTransform.TransformVector(VertexNormals[i]);
}
// Get barycentric coordinates at raycast impact point
FVector b = FMath::ComputeBaryCentric2D(ImpactPoint, VertexPositions[0], VertexPositions[1], VertexPositions[2]);
// Vector that will use to orient ship
FVector BaryNormal;
// This code attempts to build the BaryNormal vector but it does not give the desired result
BaryNormal.X = b.X * VertexNormals[0].X + b.Y * VertexNormals[1].X + b.Z * VertexNormals[2].X;
BaryNormal.Y = b.X * VertexNormals[0].Y + b.Y * VertexNormals[1].Y + b.Z * VertexNormals[2].Y;
BaryNormal.Z = b.X * VertexNormals[0].Z + b.Y * VertexNormals[1].Z + b.Z * VertexNormals[2].Z;
BaryNormal.Normalize();