Reputation: 1
I'm currently coding a 3D animation engine with HelixToolkit and I want to be able to rotate the bones of any given model I import (I'm mostly working with .pmx and .fbx files) but it doesn't seem to be doing anything. It displays the skeleton but whenever I click on a bone in it, not only does it not change colors to let you know it has been selected, but it doesn't rotate anything. It does seem to detect the bones and their names but it selects them "wrong"; like I could be clicking on the ear of a model and it will select the spine and claim it is rotating it, but I can't see anything. Thoughts?
Here's the console output:
Camera adjusted: Position=-3,814697265625E-06;-89,0589065551758;422,181945800781, LookDirection=0;0;-461,878631591797, UpDirection=0;1;0, Width=461,878631591797
Selected bone: spine_01
Rotated bone: spine_01
Rotated bone: spine_01
Rotated bone: spine_01
Rotated bone: spine_01
Rotated bone: spine_01
...ad nauseam
Here's the relevant part of the code:
private void HandleMouseDown(object sender, SceneNodeMouseDownArgs e)
{
var result = e.HitResult;
if (result == null)
{
Console.WriteLine("HitResult is null");
return;
}
}
private bool showSkeleton = false;
public bool ShowSkeleton
{
set
{
if (SetProperty(ref showSkeleton, value))
{
foreach (var m in skeletonNodes)
{
m.Visible = value;
}
}
}
}
public void StartAnimation()
{
initTimeStamp = Stopwatch.GetTimestamp();
compositeHelper.Rendering += CompositeHelper_Rendering;
IsPlaying = true;
}
private Bone selectedBone;
private bool hasSelectedBone;
public bool HasSelectedBone
{
get => hasSelectedBone;
private set => SetProperty(ref hasSelectedBone, value);
}
public void SelectBone(Point mousePosition, Viewport3DX viewport)
{
var hitTestResults = viewport.FindHits(mousePosition);
if (hitTestResults != null && hitTestResults.Count > 0)
{
var hitTestResult = hitTestResults[0]; // Select the first hit
if (hitTestResult.ModelHit is BoneSkinMeshNode boneSkinMeshNode)
{
foreach (var bone in boneSkinMeshNode.Bones)
{
if (!hasSelectedBone)
{
selectedBone = bone;
hasSelectedBone = true;
UpdateBoneVisual(selectedBone);
Console.WriteLine($"Selected bone: {selectedBone.Name}");
break;
}
}
}
}
}
public void RotateSelectedBone(double deltaX, double deltaY)
{
if (hasSelectedBone)
{
// Apply rotation based on mouse delta
var transformMatrix = selectedBone.Node.ModelMatrix;
var rotationY = Matrix.RotationY((float)deltaX * 0.01f); // Adjust rotation speed as needed
var rotationX = Matrix.RotationX((float)deltaY * 0.01f); // Adjust rotation speed as needed
selectedBone.Node.ModelMatrix = transformMatrix * rotationY * rotationX;
selectedBone.Node.UpdateAllTransformMatrix();
Console.WriteLine($"Rotated bone: {selectedBone.Name}");
}
}
public void ClearBoneSelection()
{
if (hasSelectedBone)
{
ResetBoneVisual(selectedBone);
hasSelectedBone = false;
}
}
private void UpdateBoneVisual(Bone bone)
{
if (bone.Node is MeshNode meshNode)
{
meshNode.WireframeColor = new Color4(1, 0, 0, 1); // Change color to red
}
}
private void ResetBoneVisual(Bone bone)
{
if (bone.Node is MeshNode meshNode)
{
meshNode.WireframeColor = new Color4(0, 0, 1, 1); // Change color back to blue
}
}
Upvotes: 0
Views: 74