I have This 3D mesh class , I use helixToolKit SharpDX to display the mesh and transformations , but i want to apply these transformations to the vertcies dirctly so the mesh can be exported with these transformations . how to do that ?
using HelixToolkit.SharpDX.Core;
using SharpDX;
using System.Windows.Media.Media3D;
public class Vertex
{
public Vector3 Position { get; set; }
public Vector3 Normal { get; set; }
public int NormalW { get; set; }
public List<Vector3> UVs { get; set; }
public List<Vector4> Tangents { get; set; }
public Vector4 Bitangent { get; set; }
public List<VertexColor> Colors { get; set; }
}
public class Mesh
{
public Vector3 Translation { get; set; }
public Vector3 Rotation { get; set; } //radian values of Euler angels
public Vector3 Scale { get; set; }
public List<Vertex> Vertices { get; set; }
public List<int> Indices { get; set; }
public Transform3D Transform
{
get => new MatrixTransform3D(this.GetTransformMatrix().ToMatrix3D());
}
}
Following Enigmatisms answer and using SharpDX Namespace
it should be something like this
public static void ApplyTransformations(this MeshNodeViewModel mesh)
{
//Obtain the total transformations
var tm = SharpMatrix.Translation(mesh.Translation);
var sm = SharpMatrix.Scaling(mesh.Scale);
var rxm = SharpMatrix.RotationX(mesh.Rotation.X);
var rym = SharpMatrix.RotationY(mesh.Rotation.Y);
var rzm = SharpMatrix.RotationZ(mesh.Rotation.Z);
// Apply the transformations in the SRT order
var transformations = sm * (rxm * (rzm * (rym * tm)));
//Obtain the total rotations
SharpQuaternion rotationQuaternion = SharpQuaternion.RotationMatrix(rxm * rzm * rym);
List<MyVertex> vertices = new List<MyVertex>(mesh.Vertices);
foreach (var vertex in vertices)
{
// transform vertex position
SharpVector3 pos = vertex.Position;
SharpVector3.Transform(ref pos, ref transformations, out SharpVector3 newPos);
vertex.Position = newPos;
// transform normals
vertex.Normal = TransformVector3(vertex.Normal, rotationQuaternion);
// transform tangents (the w field is not accounted for)
for (int i = 0; i < vertex.Tangents.Count; i++)
{
vertex.Tangents[i] = TransformVector4(
vertex.Tangents[i].ToSharp4(),
rotationQuaternion
)
.ToNumerics();
}
// transform bi-tangents (the w field is not accounted for)
vertex.Bitangent = TransformVector4(vertex.Bitangent.ToSharp4(), rotationQuaternion)
.ToNumerics();
}
mesh.Vertices = vertices;
//Clear Transformations
mesh.Translation = SharpVector3.Zero;
mesh.Rotation = SharpVector3.Zero;
mesh.Scale = SharpVector3.One;
}
public static SharpVector3 TransformVector3(
SharpVector3 vector,
SharpQuaternion rotationQuaternion
)
{
Vector3D vector3D = new Vector3D(vector.X, vector.Y, vector.Z);
SharpVector3.Transform(
ref vector,
ref rotationQuaternion,
out SharpVector3 rotatedVector3D
);
return new SharpVector3(
(float)rotatedVector3D.X,
(float)rotatedVector3D.Y,
(float)rotatedVector3D.Z
);
}
public static SharpVector4 TransformVector4(
SharpVector4 vector,
SharpQuaternion rotationQuaternion
)
{
SharpVector3 vector3 = new SharpVector3(vector.X, vector.Y, vector.Z); // extract
SharpVector3.Transform(
ref vector3,
ref rotationQuaternion,
out SharpVector3 rotatedVector3D
);
return new SharpVector4(
(float)rotatedVector3D.X,
(float)rotatedVector3D.Y,
(float)rotatedVector3D.Z,
vector.W
);
}
however the normals/Light reflection would change a little after appling the transformations, But this will only happens if a scale is applied . Is this supposed to happen ?
Scale
is of typeVector3
. For uniform scaling, we can only apply rotation to the normal, tangents and bitangents, yet if is scaling is non-uniform, all these fields can't just be transformed by rotation. See this article for how to resolve this problem. $\endgroup$