text: /**
    \file PhysicsFrameSpline.cpp
  
    \author Morgan McGuire, http://graphics.cs.williams.edu
   */
  #include "G3D/PhysicsFrameSpline.h"
  #include "G3D/Any.h"
  #include "G3D/stringutils.h"
  
  namespace G3D {
  
  PhysicsFrameSpline::PhysicsFrameSpline() {}
  
  PhysicsFrameSpline::PhysicsFrameSpline(const Any& any) {
      *this = any;
  }
  
  PhysicsFrameSpline& PhysicsFrameSpline::operator=(const Any& any) {
      const std::string& n = toLower(any.name());
      *this = PhysicsFrameSpline();
  
      if (n == "physicsframespline" || n == "pframespline") {
          any.verifyName("PhysicsFrameSpline", "PFrameSpline");
          
          for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
              const std::string& k = toLower(it->key);
              if (k == "cyclic") {
                  cyclic = it->value;
              } else if (k == "control") {
                  const Any& v = it->value;
                  v.verifyType(Any::ARRAY);
                  control.resize(v.size());
                  for (int i = 0; i < control.size(); ++i) {
                      control[i] = v[i];
                  }
                  if (! any.containsKey("time")) {
                      time.resize(control.size());
                      for (int i = 0; i < time.size(); ++i) {
                          time[i] = i;
                      }
                  }
              } else if (k == "finalinterval") {
                  finalInterval = it->value;
              } else if (k == "time") {
                  const Any& v = it->value;
                  v.verifyType(Any::ARRAY);
                  time.resize(v.size());
                  for (int i = 0; i < time.size(); ++i) {
                      time[i] = v[i];
                  }
              }
          }
      } else {
          // Must be a PhysicsFrame constructor of some kind
          append(any);
      }
      return *this;
  }
  
  
  void PhysicsFrameSpline::correct(PhysicsFrame& frame) const {
      frame.rotation.unitize();
  }
  
  
  void PhysicsFrameSpline::ensureShortestPath(PhysicsFrame* A, int N) const {
      for (int i = 1; i < N; ++i) {
          const Quat& p = A[i - 1].rotation;
          Quat& q = A[i].rotation;
  
          float cosphi = p.dot(q);
  
          if (cosphi < 0) {
              // Going the long way, so change the order
              q = -q;
          }
      }
  }
  
  }
  