// 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; }
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; }
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; }
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; }