/** * Attaches vertices to the selected bone. * \param verts pointer to the vertices vector holding the vertices to * be attached **/ void Skeleton::attachVertices(vector<Vertex *> *verts) { Bone *selectedBone = NULL; int s = 0; for (unsigned i = 0; i < bones->size(); i++) { if ((*bones)[i]->selected) { selectedBone = (*bones)[i]; s++; } } if (s == 1) { selectedBone->attachVertices(verts); delete verts; } }
/// Loads skeleton. void IO::loadSkeleton(TiXmlNode *parent, Skeleton *skeleton, Mesh *m) { // skeleton object is missing if (parent == NULL) return; // load joints TiXmlNode *jointsNode = parent->FirstChild("joints"); if (jointsNode == NULL) return; TiXmlNode *jointNode = NULL; int jointCount = 0; int loadedJointCount = 0; while ((jointNode = jointsNode->IterateChildren(jointNode))) { TiXmlElement *j = jointNode->ToElement(); const char *name; float x, y; int selected; int osc; int fixed; jointCount++; /* if there's a critical error the joint is skipped */ QUERY_CRITICAL_ATTR(j, "x", x); QUERY_CRITICAL_ATTR(j, "y", y); /* loadedJointCount holds the number of actually loaded joints */ loadedJointCount++; QUERY_ATTR(j, "selected", selected, 0); QUERY_ATTR(j, "osc", osc, 0); QUERY_ATTR(j, "fixed", fixed, 0); name = j->Attribute("name"); // can be NULL Joint *joint = skeleton->addJoint(x, y); joint->selected = selected; joint->osc = osc; joint->fixed = fixed; if (name) joint->setName(name); // add or remove the joint from the vector of joints // needed to be sent via OSC if (osc) { ui->editorBox->addToOSCJoints(joint); } } // skip the loading of bones if there was a problematic joint if (jointCount != loadedJointCount) return; // load bones TiXmlNode *bonesNode = parent->FirstChild("bones"); if (bonesNode == NULL) return; TiXmlNode *boneNode = NULL; vector<Joint*> *joints = skeleton->getJoints(); while ((boneNode = bonesNode->IterateChildren(boneNode))) { TiXmlElement *b = boneNode->ToElement(); const char *name; int j0, j1; float size, stiffness, lengthMult; float lengthMultMin, lengthMultMax, time, tempo; int selected; float radius; name = b->Attribute("name"); // can be NULL QUERY_CRITICAL_ATTR(b, "j0", j0); QUERY_CRITICAL_ATTR(b, "j1", j1); QUERY_CRITICAL_ATTR(b, "size", size); QUERY_ATTR(b, "stiffness", stiffness, BONE_DEFAULT_DAMP); QUERY_ATTR(b, "lm", lengthMult, BONE_DEFAULT_LENGTH_MULT); QUERY_ATTR(b, "lmmin", lengthMultMin, BONE_DEFAULT_LENGTH_MULT_MIN); QUERY_ATTR(b, "lmmax", lengthMultMax, BONE_DEFAULT_LENGTH_MULT_MAX); QUERY_ATTR(b, "tempo", tempo, 0); QUERY_ATTR(b, "time", time, 0); QUERY_ATTR(b, "selected", selected, 0); QUERY_ATTR(b, "radius", radius, 1); if ((j0 >= jointCount) || (j1 >= jointCount)) continue; Joint *j0p = (*joints)[j0]; Joint *j1p = (*joints)[j1]; Bone *bone = skeleton->addBone(j0p, j1p); if (name) bone->setName(name); bone->setOrigSize(size); bone->damp = stiffness; bone->setLengthMult(lengthMult); bone->setLengthMultMin(lengthMultMin); bone->setLengthMultMax(lengthMultMax); bone->setTempo(tempo); bone->setTime(time); bone->selected = selected; bone->setRadiusMult(radius); // load attached vertices TiXmlNode *attachedNode = boneNode->FirstChild("attached"); if (attachedNode == NULL) continue; TiXmlNode *vertexNode = NULL; // vector to hold vertices to be attached vector<Vertex *> *vertsToAttach = new vector<Vertex *>; // all vertices in mesh vector<Vertex *> *vertices = m->getVertices(); // iterate over children to find all vertices while ((vertexNode = attachedNode->IterateChildren(vertexNode))) { TiXmlElement *vertexXML = vertexNode->ToElement(); int id; QUERY_CRITICAL_ATTR(vertexXML, "id", id); if ((id >= (int)(vertices->size())) || (id < 0)) continue; Vertex *v = (*vertices)[id]; vertsToAttach->push_back(v); } // setup parameter arrays vertexNode = NULL; float *dsts, *weights, *ca, *sa; int count = vertsToAttach->size(); dsts = new float[count]; weights = new float[count]; ca = new float[count]; sa = new float[count]; // load parameters of attached vertices int i = 0; while ((vertexNode = attachedNode->IterateChildren(vertexNode))) { TiXmlElement *vertexXML = vertexNode->ToElement(); int id; float d, w; float s, c; QUERY_CRITICAL_ATTR(vertexXML, "id", id); QUERY_CRITICAL_ATTR(vertexXML, "d", d); QUERY_CRITICAL_ATTR(vertexXML, "w", w); QUERY_CRITICAL_ATTR(vertexXML, "sa", s); QUERY_CRITICAL_ATTR(vertexXML, "ca", c); if ((id >= (int)(vertices->size())) || (id < 0)) continue; dsts[i] = d; weights[i] = w; ca[i] = c; sa[i] = s; i++; } bone->attachVertices(vertsToAttach, dsts, weights, ca, sa); vertsToAttach->clear(); delete vertsToAttach; } }