예제 #1
0
파일: Entity.cpp 프로젝트: zgpxgame/iEngine
//-----------------------------------------------------------------------
void Entity::_updateRenderQueue(RenderQueue* queue) {
  SubEntityList* subEntList;
  // Check we're not using a manual LOD
  if (mMeshLodIndex > 0 && mMesh->isLodManual()) {
    // Use alternate subentities
    assert((mMeshLodIndex-1) < mLodSubEntityList.size() &&
           "No LOD SubEntityList - did you build the manual LODs after creating the entity?");
    // index - 1 as we skip index 0 (original lod)
    subEntList = mLodSubEntityList[mMeshLodIndex - 1];
  } else {
    subEntList = &mSubEntityList;
  }

  // Add each SubEntity to the queue
  SubEntityList::iterator i, iend;
  iend = subEntList->end();
  for (i = subEntList->begin(); i != iend; ++i) {
    queue->addRenderable(*i, mRenderQueueID, RENDERABLE_DEFAULT_PRIORITY);
  }

  // Since we know we're going to be rendered, take this opportunity to
  // cache bone matrices & apply world matrix to them
  if (mMesh->hasSkeleton()) {
    cacheBoneMatrices();

    //--- pass this point,  we are sure that the transformation matrix of each bone and tagPoint have been updated
    // 挂到骨头上的子物体
    ChildObjectList::iterator child_itr = mChildObjectList.begin();
    ChildObjectList::iterator child_itr_end = mChildObjectList.end();
    for( ; child_itr != child_itr_end; child_itr++) {
      (*child_itr).second->_updateRenderQueue(queue);
    }
  }

  // HACK to display bones
  // This won't work if the entity is not centered at the origin
  // TODO work out a way to allow bones to be rendered when Entity not centered
  if (mDisplaySkeleton && mMesh->hasSkeleton()) {
    Skeleton* pSkel = mMesh->getSkeleton();
    int numBones = pSkel->getNumBones();
    for (int b = 0; b < numBones; ++b) {
      Bone* bone = pSkel->getBone(b);
      queue->addRenderable(bone, mRenderQueueID);
    }
  }




}
예제 #2
0
void SkeletonTool::drawSkeleton(const Skeleton &skeleton, int row)
{
	bool buildingSkeleton = m_mode.getValue() == BUILD_SKELETON;
	bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS;

	TXsheet *xsh = getXsheet();
	std::vector<int> showBoneIndex;
	int i;
	for (i = 0; i < skeleton.getBoneCount(); i++) {
		Skeleton::Bone *bone = skeleton.getBone(i);
		TStageObjectId id = bone->getStageObject()->getId();
		bool canShow = canShowBone(bone, xsh, row);
		if (!canShow)
			continue;
		showBoneIndex.push_back(i);
	}

	bool changingParent = dynamic_cast<ParentChangeTool *>(m_dragTool) != 0;
	TStageObjectId currentObjectId = TTool::getApplication()->getCurrentObject()->getObjectId();
	std::string currentHandle = xsh->getStageObject(currentObjectId)->getHandle();

	for (i = 0; i < (int)showBoneIndex.size(); i++) {
		Skeleton::Bone *bone = skeleton.getBone(showBoneIndex[i]);
		TStageObjectId id = bone->getStageObject()->getId();
		bool isCurrent = id == currentObjectId;
		if (isCurrent && buildingSkeleton && m_parentProbeEnabled) {
			if (!m_magicLinks.empty()) {
				drawBone(bone->getCenter(), m_magicLinks[0].m_h1.m_pos, false);
			}
			drawBone(bone->getCenter(), m_parentProbe, true);
		} else if (ikEnabled) {
			if (bone->getParent())
				drawIKBone(bone->getCenter(), bone->getParent()->getCenter());
		} else if (bone->getParent() || isCurrent) {
			double pixelSize = getPixelSize();
			TPointD a = bone->getCenter();
			TPointD b, pm;
			if (bone->getParent()) {
				b = bone->getParent()->getCenter();
				pm = (a + b) * 0.5;
			} else {
				pm = b = a + TPointD(0, 60) * pixelSize;
			}
			bool boneIsVisible = false;
			if (buildingSkeleton) {
				boneIsVisible = true;
				if (bone->isSelected())
					drawBone(a, b, true);
				else if (!m_showOnlyActiveSkeleton.getValue())
					drawBone(a, b, false);
				else
					boneIsVisible = false;
			}
			if (boneIsVisible && isCurrent) {
				// draw change parent gadget
				double r = pixelSize * 5;
				if (isPicking()) {
					// int code = TD_ResetParent + bone->getStageObject()->getId().getIndex();
					glPushName(TD_ChangeParent);
					tglDrawDisk(pm, r);
					glPopName();
				} else {
					if (m_device == TD_ChangeParent) {
						glColor4d(0.47 * alpha, 0.6 * alpha, 0.65 * alpha, alpha);
						r *= 1.5;
					} else
						glColor4d(0.37 * alpha, 0.5 * alpha, 0.55 * alpha, alpha);
					glRectd(pm.x - r, pm.y - r, pm.x + r, pm.y + r);
					glColor3d(0, 0, 0);
					tglDrawRect(pm.x - r, pm.y - r, pm.x + r, pm.y + r);
				}
			}
		}
	}
	for (i = 0; i < (int)showBoneIndex.size(); i++) {
		Skeleton::Bone *bone = skeleton.getBone(showBoneIndex[i]);
		if (!m_showOnlyActiveSkeleton.getValue() || bone->isSelected())
			drawJoint(bone->getCenter(),
					  currentObjectId == bone->getStageObject()->getId() &&
						  currentHandle.find("H") != 0);
	}
}
예제 #3
0
void SkeletonTool::togglePinnedStatus(int columnIndex, int frame, bool shiftPressed)
{
	Skeleton skeleton;
	buildSkeleton(skeleton, columnIndex);
	if (!skeleton.getRootBone() || !skeleton.getRootBone()->getStageObject())
		return;
	Skeleton::Bone *bone = skeleton.getBoneByColumnIndex(columnIndex);
	assert(bone);
	if (!bone)
		return;

	TogglePinnedStatusUndo *undo = new TogglePinnedStatusUndo(this, frame);
	for (int i = 0; i < skeleton.getBoneCount(); i++) {
		TStageObject *obj = skeleton.getBone(i)->getStageObject();
		if (obj) {
			undo->addBoneId(obj->getId());
			obj->setKeyframeWithoutUndo(frame);
		}
	}

	getApplication()->getCurrentXsheet()->notifyXsheetChanged();
	getApplication()->getCurrentObject()->notifyObjectIdChanged(false);

	undo->setOldTemp(m_temporaryPinnedColumns);
	bool isTemporaryPinned = m_temporaryPinnedColumns.count(columnIndex) > 0;
	if (shiftPressed || isTemporaryPinned) {
		if (isTemporaryPinned)
			m_temporaryPinnedColumns.erase(columnIndex);
		else
			m_temporaryPinnedColumns.insert(columnIndex);
	} else {
		TXsheet *xsh = TTool::getApplication()->getCurrentXsheet()->getXsheet();
		TAffine placement = xsh->getPlacement(bone->getStageObject()->getId(), frame);

		TStageObjectId rootId = skeleton.getRootBone()->getStageObject()->getId();
		TAffine rootPlacement = xsh->getPlacement(rootId, frame);

		int pinnedStatus = bone->getPinnedStatus();
		if (pinnedStatus != Skeleton::Bone::PINNED) {
			int oldPinned = -1;
			for (int i = 0; i < skeleton.getBoneCount(); i++) {
				TStageObject *obj = skeleton.getBone(i)->getStageObject();
				if (obj->getPinnedRangeSet()->isPinned(frame)) {
					oldPinned = i;
					break;
				}
			}

			int lastFrame = 1000000;
			if (oldPinned >= 0) {
				assert(skeleton.getBone(oldPinned) != bone);
				TStageObject *obj = skeleton.getBone(oldPinned)->getStageObject();
				const TPinnedRangeSet::Range *range = obj->getPinnedRangeSet()->getRange(frame);
				assert(range && range->first <= frame && frame <= range->second);
				lastFrame = range->second;
				TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet();
				rangeSet->removeRange(frame, range->second);
				obj->invalidate();
				undo->setOldRange(oldPinned, frame, range->second, rangeSet->getPlacement());
			} else {
				for (int i = 0; i < skeleton.getBoneCount(); i++) {
					TStageObject *obj = skeleton.getBone(i)->getStageObject();
					const TPinnedRangeSet::Range *range = obj->getPinnedRangeSet()->getNextRange(frame);
					if (range) {
						assert(range->first > frame);
						if (range->first - 1 < lastFrame)
							lastFrame = range->first - 1;
					}
				}
			}

			TStageObject *obj = bone->getStageObject();
			TPinnedRangeSet *rangeSet = obj->getPinnedRangeSet();
			rangeSet->setRange(frame, lastFrame);
			if (frame == 0) {
				// this code should be moved elsewhere, possibly in the stageobject implementation
				// the idea is to remove the normal
				TStageObject *rootObj = skeleton.getRootBone()->getStageObject();
				rootObj->setStatus(TStageObject::XY);
				placement = rootObj->getPlacement(0).inv() * placement;
				rootObj->setStatus(TStageObject::IK);
				rangeSet->setPlacement(placement);
				rootObj->invalidate();
			}
			undo->setNewRange(bone->getColumnIndex(), frame, lastFrame, rangeSet->getPlacement());
		}
	}
	undo->setNewTemp(m_temporaryPinnedColumns);
	TUndoManager::manager()->add(undo);
}
예제 #4
0
void SkeletonTool::draw()
{
	// parent object reference system
	//glColor3d(1,0,0);
	//tglDrawRect(0,0,100,100);

	if (m_label != "")
		ToolUtils::drawBalloon(m_labelPos, m_label, TPixel32::Red, TPoint(20, -20), false);

	bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS;
	assert(glGetError() == GL_NO_ERROR);

	// l'xsheet, oggetto (e relativo placement), frame corrente
	TTool::Application *app = TTool::getApplication();
	TXsheet *xsh = getXsheet();
	assert(xsh);
	TStageObjectId objId = app->getCurrentObject()->getObjectId();
	// se l'oggetto corrente non e' una colonna non disegno nulla
	if (!objId.isColumn())
		return;

	TStageObject *pegbar = xsh->getStageObject(objId);
	int col = objId.getIndex();

	int frame = app->getCurrentFrame()->getFrame();
	if (m_currentFrame != frame)
		m_temporaryPinnedColumns.clear();

	TAffine aff = getMatrix();
	// puo' suggere che il placement degeneri (es.: c'e' uno h-scale = 0%)
	if (fabs(aff.det()) < 0.00001)
		return;

	// m_unit = getPixelSize() * sqrt(fabs(aff.det()));

	if (!ikEnabled)
		drawLevelBoundingBox(frame, col);

	glPushMatrix();
	tglMultMatrix(aff.inv());

	// camera stand reference system
	//glColor3d(0,1,0);
	//tglDrawRect(0,0,100,100);

	bool changingParent = dynamic_cast<ParentChangeTool *>(m_dragTool) != 0;

	// !changingParent &&
	if (m_mode.getValue() == BUILD_SKELETON && !xsh->getStageObjectParent(objId).isColumn()) {
		if (!changingParent)
			drawHooks();
	}

	Skeleton skeleton;
	buildSkeleton(skeleton, col);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	drawSkeleton(skeleton, frame);
	glDisable(GL_BLEND);

	TXshCell cell = xsh->getCell(frame, objId.getIndex());
	Skeleton::Bone *rootBone = skeleton.getRootBone();
	for (int i = 0; i < skeleton.getBoneCount(); i++) {
		Skeleton::Bone *bone = skeleton.getBone(i);
		TStageObjectId currentId = bone->getStageObject()->getId();
		bool isCurrent = (currentId == objId);
		TPointD pos = bone->getCenter();
		if (isCurrent && m_mode.getValue() != BUILD_SKELETON) {
			drawDrawingBrowser(cell, pos);
		}

		bool isActiveChain = bone->isSelected();

		glColor3d(0, 1, 0);
		if (ikEnabled) {
			drawIKJoint(bone);
		} else {
			TPointD pos = bone->getCenter();
			if (isCurrent && m_mode.getValue() == ANIMATE) {
				drawMainGadget(pos);
			}
		}
	}
	m_currentFrame = frame;

	if (m_dragTool)
		m_dragTool->draw();
	glPopMatrix();
}
예제 #5
0
void Skeleton::fitToTargetSkeleton(const Skeleton &target)
{
    // find root bone
    int rootId = -1;
    for(unsigned int i = 0; i < mBones.size(); ++i)
    {
        if(mBones[i].parent == -1)
        {
            rootId = i;
            break;
        }
    }

    // is a root in the skeleton
    if(rootId == -1)
    {
        LOG("no root bone found");
        return;
    }

    // check for consistency
    if(mBones.size() != target.getNumBones())
    {
        LOG("skeletons does not match");
        return;
    }

    // init stack with root
    std::vector<int> ndStack(0);
    ndStack.push_back(rootId);

    // level pt
    int sp = 0;
    while((unsigned int)sp < ndStack.size())
    {
        Bone& cur = mBones[ndStack[sp]];

        for(unsigned int j = 0; j < cur.children.size(); ++j)
        {
            ndStack.push_back(cur.children[j]);
        }

        sp++;
    }

    // apply all rotations according stack order
    for(unsigned int k = 0; k < ndStack.size(); ++k)
    {
        // get current bone
        unsigned int l = ndStack[k];
        Bone& _tB = mBones[l];

        // transform rotation from other bone
        Bone _oB;
        target.getBone(l, _oB);
        _tB.R = _oB.R;

        // offset is the fathers end position
        if(_tB.parent > -1 && (unsigned int)_tB.parent < mBones.size())
        {
            Bone& _pP = mBones[_tB.parent];
            _tB.t = _pP.t + _pP.R.col(1) * _pP.length;
        }
        else
        {
            // LOG("no t correction for bone " << l);
        }

        mJoints[_tB.j0] = _tB.t;
        mJoints[_tB.j1] = _tB.t + _tB.R.col(1) * _tB.length;
    }
}
예제 #6
0
bool FileSystem::loadModelAndSkeletonDae(const char *path, Model &m, Skeleton &s)
{
	size_t pos;
	std::string line, armatureName;
	std::ifstream fileStream(path);
	std::vector<bool> closed;

	glm::mat4 bindShapeMatrix;
	std::vector<float> v, n, t, w;
	std::vector<glm::mat4> bindPoses;
	std::vector<std::vector<int> > weightJoints, weightWeights, indices;
	std::vector<std::string> polylistMaterials;
	std::vector<int> vcount;

	if (fileStream.is_open())
	{
		getline(fileStream, line);
		while (line.find("<library_geometries>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}

		while (line.find("<mesh>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}

		//load model
		while (fileStream.good())
		{
			getline(fileStream, line);
			size_t pos;

			if ((pos = line.find("<source id=")) != std::string::npos) {
				std::string id = line;

				getline(fileStream, line);
				std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
				std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);

				if ((pos = id.find("-positions")) != std::string::npos) {
					v.reserve(atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str()));
					split(begIt, endIt, ' ', v);
				}
				else if ((pos = id.find("-normals")) != std::string::npos) {
					n.reserve(atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str()));
					split(begIt, endIt, ' ', n);
				}
				else if ((pos = id.find("-map")) != std::string::npos) {
					t.reserve(atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str()));
					split(begIt, endIt, ' ', t);
				}
			}
			else if ((pos = line.find("<polylist")) != std::string::npos) {
				polylistMaterials.push_back(line.substr((pos = line.find("material=\"") + 10), line.find("-material\"", pos + 1) - pos));
				indices.push_back(std::vector<int>());
				indices.back().reserve(atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str()));
				while (line.find("<p>") == std::string::npos && fileStream.good()) {
					getline(fileStream, line);
				}
				std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
				std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);
				split(begIt, endIt, ' ', indices.back());
			}
			else if ((pos = line.find("</mesh>")) != std::string::npos) {
				break;
			}
		}

		while (line.find("<library_controllers>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}

		while (line.find("</library_controllers>") == std::string::npos && fileStream.good()) {
			if (line.find("<controller id") != std::string::npos) {
				if ((pos = line.find("-skin\"")) != std::string::npos) {
					pos = line.find("name=");
					armatureName = line.substr((pos = line.find_first_of("\"", pos)) + 1, line.find_first_of("\"", pos + 1) - (pos + 1));
					break;
				}
			}
			getline(fileStream, line);
		}

		while (line.find("<bind_shape_matrix>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}
		{
			std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
			std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);
			std::vector<float> matrixValues;
			split(begIt, endIt, ' ', matrixValues);
			for (unsigned int i = 0; i < 16; i++)
				bindShapeMatrix[i / 4][i % 4] = matrixValues[i];
			bindShapeMatrix = glm::transpose(bindShapeMatrix);
		}

		//load vertex weights
		while (fileStream.good())
		{
			getline(fileStream, line);

			if ((pos = line.find("<source id=")) != std::string::npos) {
				getline(fileStream, line);
				std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
				std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);

				if ((pos = line.find("-bind_poses-array")) != std::string::npos) {
					std::vector<float> matrixValues;
					matrixValues.reserve(atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str()));
					split(begIt, endIt, ' ', matrixValues);
					for (unsigned int i = 0; i < matrixValues.size(); i++) {
						glm::mat4 m;
						for (int j = 0; j < 16; j++) {
							m[j / 4][j % 4] = matrixValues[i];
							i++;
						}
						i--;
						bindPoses.push_back(m);
					}
				}
				else if ((pos = line.find("-weights-array")) != std::string::npos) {
					w.reserve(atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str()));
					split(begIt, endIt, ' ', w);
				}
			}
			else if (line.find("<vertex_weights") != std::string::npos)
				break;
		}

		int weightsCount = atoi(line.substr((pos = line.find("count=\"")) + 7, line.find_first_of("\"", pos + 1) - (pos + 1)).c_str());

		while (line.find("<vcount>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}
		std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
		std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);
		vcount.reserve(weightsCount);
		split(begIt, endIt, ' ', vcount);
		while (line.find("<v>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}
		begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
		endIt = line.begin() + line.find_first_of("<", pos + 1);
		std::vector<int> weights;
		weights.reserve(weightsCount);
		split(begIt, endIt, ' ', weights);
		int k = 0;
		weightJoints.reserve(vcount.size());
		weightWeights.reserve(vcount.size());
		for (unsigned int i = 0; i < vcount.size(); i++) {
			weightJoints.push_back(std::vector<int>()); weightJoints.back().reserve(vcount[i]);
			weightWeights.push_back(std::vector<int>()); weightWeights.back().reserve(vcount[i]);
			for (int j = 0; j < vcount[i]; j++) {
				weightJoints[i].push_back(weights[k]); k++;
				weightWeights[i].push_back(weights[k]); k++;
			}
		}

		while (line.find("<library_visual_scenes>") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}
		
		while (line.find("node id=\"" + armatureName + "\"") == std::string::npos && fileStream.good()) {
			getline(fileStream, line);
		}
		getline(fileStream, line);
		{
			std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
			std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);
			std::vector<float> mat; mat.reserve(16);
			split(begIt, endIt, ' ', mat);
			glm::mat4 m;
			for (unsigned int i = 0; i < 16; i++)
				m[i / 4][i % 4] = mat[i];
			s.setRootTransformMatrix(glm::transpose(m));
		}

		s.setBonesNumber(bindPoses.size());

		//load skeleton
		while (fileStream.good())
		{
			getline(fileStream, line);

			if (line.find("</node>") != std::string::npos) {
				int last = findLastOpen(closed);
				if (last < 0)
					break;

				closed[last] = true;;
			}

			else if ((pos = line.find("<node id=")) != std::string::npos) {
				int parent = findLastOpen(closed);
				std::string name = line.substr((pos = line.find_first_of("\"")) + 1, line.find_first_of("\"", pos + 1) - (pos + 1));
					
				getline(fileStream, line);
				std::string::iterator begIt = line.begin() + (pos = line.find_first_of(">")) + 1;
				std::string::iterator endIt = line.begin() + line.find_first_of("<", pos + 1);
				std::vector<float> mat; mat.reserve(16);
				split(begIt, endIt, ' ', mat);
				glm::mat4 m;
				for (unsigned int i = 0; i < 16; i++)
					m[i / 4][i % 4] = mat[i];

				s.addBone(glm::transpose(m), findLastOpen(closed));

				closed.push_back(false);
			}
		}

		if (!fileStream.good()) {
			std::cout << "File is in incorrect format " << path << std::endl;
			return false;
		}


		//add inverse bind pose matrices
		for (unsigned int i = 0; i < bindPoses.size(); i++) {
			s.getBone(i)->inverseBindMatrix = glm::transpose(bindPoses[i]) * bindShapeMatrix;
		}

		s.fixScale();

		//sort weights
		std::vector<std::vector<float> > wSorted;
		std::vector<std::vector<int> > jSorted;
		wSorted.reserve(weightJoints.size());
		jSorted.reserve(weightJoints.size());
		for (unsigned int i = 0; i < weightJoints.size(); i++) {
			wSorted.push_back(std::vector<float>()); wSorted.back().reserve(weightJoints[i].size());
			jSorted.push_back(std::vector<int>()); jSorted.back().reserve(weightJoints[i].size());
			for (unsigned int j = 0; j < weightJoints[i].size(); j++) {
				if (j == 0) {
					wSorted[i].push_back(w[weightWeights[i][j]]);
					jSorted[i].push_back(weightJoints[i][j]);
				}
				else {
					for (unsigned int k = 0; k < wSorted[i].size(); k++) {
						if (w[weightWeights[i][j]] > wSorted[i][k]) {
							wSorted[i].insert(wSorted[i].begin() + k, w[weightWeights[i][j]]);
							jSorted[i].insert(jSorted[i].begin() + k, weightJoints[i][j]);
							break;
						}
						if (k == wSorted[i].size() - 1) {
							wSorted[i].push_back(w[weightWeights[i][j]]);
							jSorted[i].push_back(weightJoints[i][j]);
							break;
						}
					}
				}
			}
		}

		for (unsigned int i = 0; i < wSorted.size(); i++) {
			if (wSorted[i].size() > 4) {
				for (unsigned int j = wSorted[i].size() - 1; j > 3; j--) {
					for (int k = 0; k < 4; k++)
						wSorted[i][k] += wSorted[i][j] * 0.25f;

					wSorted[i].erase(wSorted[i].begin() + j);
					jSorted[i].erase(jSorted[i].begin() + j);
				}
			}
		}

		//push in faces
		for (unsigned int k = 0; k < indices.size(); k++)
		{
			WeightedMesh mesh;
			mesh.reserve(indices[k].size());
			for (unsigned int i = 0; i < indices[k].size(); i += 3) {
				glm::vec3 vertex, normal;
				glm::vec2 texCoord;
				glm::vec4 weights;
				glm::ivec4 joints;

				vertex.x = v[indices[k][i] * 3];
				vertex.y = v[indices[k][i] * 3 + 1];
				vertex.z = v[indices[k][i] * 3 + 2];
				weights = glm::vec4(0.0f); joints = glm::ivec4(0);

				for (unsigned int j = 0; j < wSorted[indices[k][i]].size(); j++) {
					weights[j] = wSorted[indices[k][i]][j];
					joints[j] = jSorted[indices[k][i]][j];
				}

				normal.x = n[indices[k][i + 1] * 3];
				normal.y = n[indices[k][i + 1] * 3 + 1];
				normal.z = n[indices[k][i + 1] * 3 + 2];

				if (t.size() > 0) {
					texCoord.x = t[indices[k][i + 2] * 2];
					texCoord.y = 1.0f - t[indices[k][i + 2] * 2 + 1]; //OpenGL coords
				}
				else
					texCoord = glm::vec2(0.0f);

				mesh.addVertex(vertex, normal, texCoord, weights, joints);
			}

			std::shared_ptr<Material> mat(new Material);
			Texture tex;
			if (!loadTexture(std::string("resource/").append(polylistMaterials[k].append("_D.png")).c_str(), tex)) {
				if (!loadTexture("resource/white_D.png", tex))
					return false;
			}
			mat->setDifTex(tex);
			mesh.addMaterial(mat);

			m.addMesh(std::make_shared<WeightedMesh>(mesh));
		}

		fileStream.close();
		return true;
	}
	
	std::cout << "Unable to open file " << path << std::endl;
	return false;
}