2012-11-25 12 views
8

Sto lavorando ad un metodo di estensione per spostare uno scheletro in una posizione desiderata nella vista os del campo di cinematica.Come spostare uno scheletro di cinematica in un'altra posizione

Il mio codice riceve uno scheletro da spostare e la posizione del destino, calcolo la distanza tra il centro dell'anca dello scheletro ricevuto e la posizione del destino per trovare how much to move, quindi una iterazione nel giunto applicando questo fattore. Il mio codice, sembra proprio questo.

public static Skeleton MoveTo(this Skeleton skToBeMoved, Vector4 destiny) 
    { 
     Joint newJoint = new Joint(); 

     ///Based on the HipCenter (i dont know if it is reliable, seems it is.) 
     float howMuchMoveToX = Math.Abs(skToBeMoved.Joints[JointType.HipCenter].Position.X - destiny.X); 
     float howMuchMoveToY = Math.Abs(skToBeMoved.Joints[JointType.HipCenter].Position.Y - destiny.Y); 
     float howMuchMoveToZ = Math.Abs(skToBeMoved.Joints[JointType.HipCenter].Position.Z - destiny.Z); 
     float howMuchToMultiply = 1; 

     // Iterate in the 20 Joints 
     foreach (JointType item in Enum.GetValues(typeof(JointType))) 
     { 
      newJoint = skToBeMoved.Joints[item]; 

      // This adjust, try to keeps the skToBeMoved in the desired position 
      if (newJoint.Position.X < 0) 
       howMuchToMultiply = 1; // if the point is in a negative position, carry it to a "more positive" position 
      else 
       howMuchToMultiply = -1; // if the point is in a positive position, carry it to a "more negative" position 

      // applying the new values to the joint 
      SkeletonPoint pos = new SkeletonPoint() 
      { 
       X = newJoint.Position.X + (howMuchMoveToX * howMuchToMultiply), 
       Y = newJoint.Position.Y, // * (float)whatToMultiplyY, 
       Z = newJoint.Position.Z, // * (float)whatToMultiplyZ 
      }; 

      newJoint.Position = pos; 
      skToBeMoved.Joints[item] = newJoint; 

      //if (skToBeMoved.Joints[JointType.HipCenter].Position.X < 0) 
      //{ 
      // if (item == JointType.HandLeft) 
      // { 
      //  if (skToBeMoved.Joints[item].Position.X > 0) 
      //  { 

      //  } 
      // } 
      //} 
     } 

     return skToBeMoved; 
    } 

In realtà, viene considerata solo la posizione X.

Ora, il problema:

Se mi trovo in una posizione negativa, e muovere la mano ad una posizione positiva, una ha un comportamento strano, guardate questa immagine

enter image description here

Per riprodurre questo comportamento è possibile utilizzare questo codice

using (SkeletonFrame frame = e.OpenSkeletonFrame()) 
     { 
      if (frame == null) 
       return new Skeleton(); 

      if (skeletons == null || skeletons.Length != frame.SkeletonArrayLength) 
      { 
       skeletons = new Skeleton[frame.SkeletonArrayLength]; 
      } 
      frame.CopySkeletonDataTo(skeletons); 

      Skeleton skeletonToTest = skeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked).FirstOrDefault(); 

      Vector4 newPosition = new Vector4(); 
      newPosition.X = -0.03412333f; 
      newPosition.Y = 0.0407479f; 
      newPosition.Z = 1.927342f; 
      newPosition.W = 0; // ignored 

      skeletonToTest.MoveTo(newPosition); 
     } 

lo so, questo è semplice matematica, ma i cant capirlo perché questo è accaduto. Qualsiasi aiuto sarà apprezzato.

+1

dovrebbe essere una questione di aggiungere il nuovo vettore di traslazione grado di ciascuna posizione comune nello scheletro e nulla più –

+0

@George Profenza Sì, lo è! Quali sono le tue modifiche al codice per risolverlo? – Ewerton

+0

Sono contento di averlo risolto, ero fuori quando hai risposto. Tuttavia, dal mio punto di vista, se 'Vector4 destiny' è una posizione relativa da tradurre verso il fatto che è solo una questione di fare qualcosa come' currentPositionVector + = translationVector' (in pseudo, come in, 'currentJoint.x + = newPos.x ', lo stesso per y e z). Se 'il destino è assoluto', useresti la differenza tra la posizione corrente e la nuova posizione. La parte che mi imbarazza nel tuo approccio è il motivo per cui devi capovolgere (moltiplicare per -1) il vettore di differenza. Inoltre, quando ottieni il vettore di differenza, sembra che tu aggiunga solo il componente X ... –

risposta

9

Problema risolto. Questo è il codice

public static Skeleton MoveTo(this Skeleton skToBeMoved, Vector4 destiny) 
    { 
     Joint newJoint = new Joint(); 

     ///Based on the HipCenter (i dont know if it is reliable, seems it is.) 
     float howMuchMoveToX = (skToBeMoved.Joints[JointType.HipCenter].Position.X - destiny.X) * -1; 
     float howMuchMoveToY = (skToBeMoved.Joints[JointType.HipCenter].Position.Y - destiny.Y) * -1; 
     float howMuchMoveToZ = (skToBeMoved.Joints[JointType.HipCenter].Position.Z - destiny.Z) * -1; 

     // Iterate in the 20 Joints 
     foreach (JointType item in Enum.GetValues(typeof(JointType))) 
     { 
      newJoint = skToBeMoved.Joints[item]; 

      // applying the new values to the joint 
      SkeletonPoint pos = new SkeletonPoint() 
      { 
       X = (float)(newJoint.Position.X + (howMuchMoveToX)), 
       Y = (float)(newJoint.Position.Y + (howMuchMoveToY)), 
       Z = (float)(newJoint.Position.Z + (howMuchMoveToZ)) 
      }; 

      newJoint.Position = pos; 
      skToBeMoved.Joints[item] = newJoint; 
     } 

     return skToBeMoved; 
    } 
Problemi correlati