// Returns a new tree (frame) with new positions based on the calculated
// corresponding points in the spline. When called in succession, it moves the
// model and all of its joints along the spline.
Node jointsToSpline(Node* root,
                    const vector<Point>& spline,
                    vector<int> correspondingPoints,
                    int& index,
                    ofstream* myfile) {
  Node frame;
  frame.set_name(root->name());
  //*myfile << frame.name() << endl;

  int c = correspondingPoints.at(index);
  Point s = spline.at(c);

  double x0, x1, x2;
  double y0, y1, y2;
  double z0, z1, z2;

  Point s0;
  Point s2;
  Point m0;

  if (c == 0) {
    s2 = spline.at(c + 1);
    m0 = forwardDiff(s, s2);
  } else if (c == spline.size() - 1) {
    s0 = spline.at(c - 1);
    m0 = forwardDiff(s0, s);
  } else {
    s0 = spline.at(c - 1);
    s2 = spline.at(c + 1);
    m0 = midpointDiff(s0, s, s2);
  }

  frame.mutable_position()->set_x(s.x);
  frame.mutable_position()->set_y(s.y);
  frame.mutable_position()->set_z(s.z);

  frame.mutable_eularangles()->set_x(m0.x);
  frame.mutable_eularangles()->set_y(m0.y);
  frame.mutable_eularangles()->set_z(m0.z);

  //*myfile << "-- ";
  //*myfile << root.name() << endl;
  //*myfile << frame.mutable_position()->z() << endl;

  for (int i = 0; i < root->children_size(); i++) {
    Node tmp = jointsToSpline(root->mutable_children(i), spline,
                              correspondingPoints, ++index, myfile);
    tmp.set_name(root->children(i).name());
    Node* p = frame.add_children();
    p->CopyFrom(tmp);
  }
  return frame;
}
Пример #2
0
Node* Node::SetAsRootInCopy(Node* ignore)
{
    Node* copy = new Node(false);
    set<Node*> ignoreSet;
    if (ignore)
        ignoreSet.insert(ignore);
    copy->CopyFrom(this, ignoreSet);

    if (this->parent)
    {
        Node* parentCopy = this->parent->SetAsRootInCopy(this);
        copy->AddSubTree(parentCopy);
    }

    return copy;
}
Пример #3
0
Node* Node::SetRootOnParentEdgeInCopy()
{
    if (!this->parent)
        throw "Node has no parent edge.";

    Node* newRoot = new Node(false);

    Node* thisCopy = new Node(false);
    thisCopy->CopyFrom(this);

    Node* parentCopy = this->parent->SetAsRootInCopy(this);

    newRoot->AddSubTree(thisCopy);
    newRoot->AddSubTree(parentCopy);

    return newRoot;
}
Пример #4
0
void Node::CopyFrom(Node *n, set<Node *> ignoreNodes)
{
    this->depth = n->depth;
    this->label = n->label;
    this->pathBits = n->pathBits;
    this->state = n->state;
    this->branchLength = n->GetBranchLength();

    if (n->nodeInfo)
    {
        this->nodeInfo = n->nodeInfo->GetClone();
    }

    for (int i = 0; i < n->children.size(); i++)
    {
        if (ignoreNodes.find(n->children[i]) == ignoreNodes.end())
        {
            Node* nc = this->AddChild();
            nc->CopyFrom(n->children[i], ignoreNodes);
        }
    }
}
// Returns a new tree (frame) with new positions based on the calculated
// corresponding points in the spline. When called in succession, it moves the
// model and all of its joints along the spline.
Node jointsToSpline(Node* root,
                    vector<struct pt*> spline,
                    vector<int> correspondingPoints,
                    int& index,
                    ofstream* myfile) {
  Node frame;
  frame.set_name(root->name());
  //*myfile << frame.name() << endl;

  int c = correspondingPoints.at(index);
  struct pt* s = spline.at(c);

  double x0, x1, x2;
  double y0, y1, y2;
  double z0, z1, z2;

  struct pt* s0;
  struct pt* s2;
  struct pt* m0;

  if (c == 0) {
    x0 = s->x;
    y0 = s->y;
    z0 = s->z;
    s2 = spline.at(c + 1);
    x1 = (s->x + s2->x) / 2;
    y1 = (s->y + s2->y) / 2;
    z1 = (s->z + s2->z) / 2;
    x2 = s2->x;
    y2 = s2->y;
    z2 = s2->z;
    m0 = forwardDiff(s, s2);
  } else if (c == spline.size() - 1) {
    s0 = spline.at(c - 1);
    x0 = s0->x;
    y0 = s0->y;
    z0 = s0->z;
    x1 = (s->x + s0->x) / 2;
    y1 = (s->y + s0->y) / 2;
    z1 = (s->z + s0->z) / 2;
    x2 = s->x;
    y2 = s->y;
    z2 = s->z;
    m0 = forwardDiff(s0, s);
  } else {
    s0 = spline.at(c - 1);
    s2 = spline.at(c + 1);
    x0 = s0->x;
    y0 = s0->y;
    z0 = s0->z;
    x1 = s->x;
    y1 = s->y;
    z1 = s->z;
    x2 = s2->x;
    y2 = s2->y;
    z2 = s2->z;
    m0 = midpointDiff(s0, s, s2);
  }

  frame.mutable_position()->set_x(s->x);
  frame.mutable_position()->set_y(s->y);
  frame.mutable_position()->set_z(s->z);

  frame.mutable_eularangles()->set_x(m0->x);
  frame.mutable_eularangles()->set_y(m0->y);
  frame.mutable_eularangles()->set_z(m0->z);

  *myfile << "-- ";
  *myfile << root->name() << endl;
  *myfile << m0->x << endl;
  *myfile << m0->y << endl;
  *myfile << m0->z << endl;

  for (int i = 0; i < root->children_size(); i++) {
    Node tmp = jointsToSpline(root->mutable_children(i), spline,
                              correspondingPoints, ++index, myfile);
    tmp.set_name(root->children(i).name());
    Node* p = frame.add_children();
    p->CopyFrom(tmp);
  }
  return frame;
}
// Returns an animation of the model evaluated at a certain point along spline.
// TODO: get the time it takes the user to draw the LOA, going to need the
// control points dropped at intervals
Animation* evaluateDLOA(ModelData* modelData, vector<struct pt*> spline) {
  Animation* animation = new Animation();
  ofstream myfile;
  myfile.open("/home/psarahdactyl/Documents/ccfunfunfun.txt");
  spline.clear();
  for (int i = 0; i < 100; i += 1) {
    spline.push_back(createPoint(i, 0, 0));
  }

  // calculate the constant b
  double modelLength = getModelLength(modelData->mutable_model());
  double splineLength = getSplineLength(spline);
  myfile << "ml " << modelLength << endl;
  myfile << "sl " << splineLength << endl;
  double b = modelLength / (splineLength);
  myfile << "b " << b << endl;

  // calculate points in spline per frame
  double pointsPerFrame = spline.size() * b;
  myfile << "ss: " << spline.size() << endl;
  myfile << "ppf: " << pointsPerFrame << endl;

  // calculate which point goes with which joint
  Node* root = modelData->mutable_model();

  // maps points from user drawn curve -- now a spline -- to the joints in the
  // model
  vector<int> correspondingPoints =
      mapPoints(root, pointsPerFrame, modelLength);
  for (int h = 0; h < correspondingPoints.size(); h++) {
    myfile << correspondingPoints.at(h) << endl;
  }

  vector<struct pt*> extra;

  struct pt* last = spline.at(spline.size() - 1);
  struct pt* secondLast = spline.at(spline.size() - 2);

  double x = last->x - secondLast->x;
  double y = last->y - secondLast->y;
  double z = last->z - secondLast->z;
  struct pt* difference = createPoint(x, y, z);

  for (double t = 1; t <= pointsPerFrame; t++) {
    struct pt* diff = multScalar(t, difference);
    struct pt* r = add(last, diff);
    extra.push_back(r);
  }

  vector<struct pt*> newSpline;
  newSpline.reserve(spline.size() + extra.size());  // preallocate memory
  newSpline.insert(newSpline.end(), spline.begin(), spline.end());
  newSpline.insert(newSpline.end(), extra.begin(), extra.end());

  // go through every point in spline
  // iterating by 1 every time gives us frames overlapping points in the spline
  for (int i = 0; i < newSpline.size() - pointsPerFrame; i++) {
    int index = 0;
    // move model and its joints
    Node frame =
        jointsToSpline(root, newSpline, correspondingPoints, index, &myfile);
    frame.set_name(root->name());

    // go through the mapped joints on the model and move them up by 1
    // since we are on a new frame
    vector<int> newCorresponding;
    for (int j = 0; j < correspondingPoints.size(); j++) {
      newCorresponding.push_back(correspondingPoints.at(j) + 1);
    }
    // copy for the next iteration
    correspondingPoints = newCorresponding;

    // add frames to the animation
    Node* a = animation->add_frames();
    Node parent;
    Node* p = parent.add_children();
    parent.CopyFrom(frame);
    p->CopyFrom(frame);
    a->CopyFrom(parent);
    a->set_name(root->name());
  }

  return animation;
}
// Returns an animation of the model evaluated at a certain point along spline.
// TODO: get the time it takes the user to draw the LOA, going to need the
// control points dropped at intervals
Animation* evaluateDLOA(ModelData* modelData,
                        const vector<Point>& spline,
                        int* modelFrames) {
  Animation* animation = new Animation();
  ofstream myfile;
  // myfile.open ("/home/psarahdactyl/Documents/ccfunfunfun.txt");

  // calculate the constant b
  double modelLength = getModelLength(modelData->mutable_model());
  double splineLength = getSplineLength(spline);
  double b = modelLength / (splineLength);

  // calculate points in spline per frame
  double pointsPerFrame = spline.size() * b;
  *modelFrames = pointsPerFrame;
  // myfile << pointsPerFrame << endl;

  // calculate which point goes with which joint
  Node* root = modelData->mutable_model();

  // maps points from user drawn curve -- now a spline -- to the joints in the
  // model
  vector<int> correspondingPoints =
      mapPoints(root, pointsPerFrame, modelLength);
  for (int h = 0; h < correspondingPoints.size(); h++) {
    myfile << correspondingPoints.at(h) << endl;
  }

  // End animation on curve unless there are not enough points on spline.
  vector<Point> extra;
  if (spline.size() < pointsPerFrame) {
    Point last = spline.at(spline.size() - 1);
    Point secondLast = spline.at(spline.size() - 2);

    double x = last.x - secondLast.x;
    double y = last.y - secondLast.y;
    double z = last.z - secondLast.z;
    Point difference = createPoint(x, y, z);

    for (double t = 1; t <= pointsPerFrame; t++) {
      Point diff = multScalar(t, difference);
      Point r = add(last, diff);
      extra.push_back(r);
    }
  }

  vector<Point> newSpline;
  newSpline.reserve(spline.size() + extra.size());  // preallocate memory
  newSpline.insert(newSpline.end(), spline.begin(), spline.end());
  newSpline.insert(newSpline.end(), extra.begin(), extra.end());

  // go through every point in spline
  // iterating by 1 every time gives us frames overlapping points in the spline
  for (int i = 0; i <= newSpline.size() - pointsPerFrame; i++) {
    int index = 0;
    // move model and its joints
    Node frame =
        jointsToSpline(root, newSpline, correspondingPoints, index, &myfile);
    frame.set_name(root->name());

    // go through the mapped joints on the model and move them up by 1
    // since we are on a new frame
    vector<int> newCorresponding;
    for (int j = 0; j < correspondingPoints.size(); j++) {
      newCorresponding.push_back(correspondingPoints.at(j) + 1);
    }
    // copy for the next iteration
    correspondingPoints = newCorresponding;

    // add frames to the animation
    Node* a = animation->add_frames();
    a->CopyFrom(frame);
    a->set_name(root->name());
  }

  return animation;
}