void Skeleton::InitMesh(const aiMesh* paiMesh, unsigned int index)
{
	for (unsigned int i = 0; i < paiMesh->mNumBones; i++) {
		unsigned int boneIndex = 0;
		string boneName(paiMesh->mBones[i]->mName.data);

		if (skeletalBones.find(boneName) == skeletalBones.end()) {
			// Allocate an index for a new bone
			boneIndex = nrBones;
			BoneInfo bi;
			assimp::CopyMatix(paiMesh->mBones[i]->mOffsetMatrix, bi.BoneOffset);
			boneInfo.push_back(bi);
			skeletalBones[boneName] = boneIndex;
			nrBones++;
		}
		else {
			boneIndex = skeletalBones[boneName];
		}

		for (unsigned int j = 0; j < paiMesh->mBones[i]->mNumWeights; j++) {
			//uint VertexID = meshEntries[index]->baseVertex + paiMesh->mBones[i]->mWeights[j].mVertexId;
			float weight = paiMesh->mBones[i]->mWeights[j].mWeight;
			//boneData[VertexID].AddBoneData(boneIndex, weight);
		}
	}
}
Beispiel #2
0
void Animation::Mesh::LoadBones(unsigned int meshIndex, const aiMesh* mesh, std::vector<VertexInfo>& vertices)
{
    for (unsigned int i = 0; i < mesh->mNumBones; i++)
    {
        unsigned int boneIndex = 0;
        std::string boneName(mesh->mBones[i]->mName.data);

        if (m_boneMapping.find(boneName) == m_boneMapping.end())
        {
            // Allocate an index for a new bone
            boneIndex = m_numBones;
            m_numBones++;
            BoneInfo bi;
            m_boneInfo.push_back(bi);
            Assign(m_boneInfo[boneIndex].boneOffset, mesh->mBones[i]->mOffsetMatrix);
            m_boneMapping[boneName] = boneIndex;
        }
        else
        {
            boneIndex = m_boneMapping[boneName];
        }

        for (unsigned int j = 0; j < mesh->mBones[i]->mNumWeights; j++)
        {
            unsigned int vertexID = m_meshes[meshIndex].baseVertex + mesh->mBones[i]->mWeights[j].mVertexId;
            float weight = mesh->mBones[i]->mWeights[j].mWeight;
            vertices[vertexID].boneData.AddBoneData(boneIndex, weight);
        }
    }
}
Beispiel #3
0
void Mesh::loadBones(unsigned int _meshIndex, const aiMesh* _mesh, std::vector<VertexBoneData>& o_bones)
{
  for (unsigned int i = 0 ; i < _mesh->mNumBones ; ++i)
  {
    unsigned int BoneIndex = 0;
    std::string boneName(_mesh->mBones[i]->mName.data);

    if (m_boneMapping.find(boneName) == m_boneMapping.end())
    {
      // Allocate an index for a new bone
      BoneIndex = m_numBones;
      m_numBones++;
      BoneInfo bi;
      m_boneInfo.push_back(bi);
      // this is the Matrix that transforms from mesh space to bone space in bind pose.
      m_boneInfo[BoneIndex].boneOffset = AIU::aiMatrix4x4ToNGLMat4(_mesh->mBones[i]->mOffsetMatrix);
      m_boneMapping[boneName] =BoneIndex;
    }
    else
    {
      BoneIndex = m_boneMapping[boneName];
    }

    for (unsigned int j = 0 ; j < _mesh->mBones[i]->mNumWeights ; ++j)
    {
      unsigned int VertexID = m_entries[_meshIndex].BaseVertex + _mesh->mBones[i]->mWeights[j].mVertexId;
      float Weight  = _mesh->mBones[i]->mWeights[j].mWeight;
      o_bones[VertexID].addBoneData(BoneIndex, Weight);
    }
  }
}
Beispiel #4
0
void ASmrActor::TransformBone(UPoseableMeshComponent* mesh, SMRJoint* bone)
{
	//Build the local transform for this bone
	FTransform finalTransform;
	finalTransform.SetLocation(USmrFunctions::RightCoordToLeft(bone->getPosition()));
	finalTransform.SetRotation(USmrFunctions::RightCoordToLeft(bone->getOrientation()));

	if (bone->hasParent())
	{
		//Get the component space transform for the parent bone
		FName parentName(bone->getParentName().c_str());
		FTransform parentTransform = mesh->GetBoneTransformByName(parentName, EBoneSpaces::ComponentSpace);

		//Convert local transform to component space
		finalTransform *= parentTransform;
	}
	//Convert quaternion to Euler angles and apply to the mesh
	FVector euler = finalTransform.GetRotation().Euler();
	FRotator rotator = FRotator::MakeFromEuler(euler);
	FName boneName(bone->getName().c_str());
	mesh->SetBoneRotationByName(boneName, rotator, EBoneSpaces::ComponentSpace);
}
Beispiel #5
0
void AMWBattery::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	for (uint32 i = 0; i < kMaxLEDs; ++i)
	{
		// Attach to its point on the battery mesh
		FString name("led");
		name.AppendInt(i + 1);
		FName boneName(*name);
		LEDs[i]->AttachTo(BatteryMesh, boneName, EAttachLocation::SnapToTarget);

		// Assign common LED static mesh and create dynamic material. 
		LEDs[i]->StaticMesh = LEDMesh;
		LED_MIDs[i] = LEDs[i]->CreateAndSetMaterialInstanceDynamic(0);
	}

	BatteryMID = BatteryMesh->CreateAndSetMaterialInstanceDynamic(0);

	CurrentCharge = Capacity;
	CurrentPower = NormalPower;

	UpdateLEDs();
}
Beispiel #6
0
void WeightTableWindow::PaintWeightListLabel()
	{
	HDC hdc;
	PAINTSTRUCT		ps;
	BeginPaint(hWeightListLabel,&ps);
	EndPaint(hWeightListLabel,&ps);

	iWeightListLabelBuf->Erase();
	hdc = iWeightListLabelBuf->GetDC();

	WINDOWPLACEMENT winPos;
 	GetWindowPlacement(hWeightListLabel , &winPos);

	HFONT hOldFont = (HFONT)SelectObject(hdc, hFixedFont);

//5.1.01
	int  justify = TEXT_LEFT_JUSTIFIED;
	if (GetRightJustify()) justify = TEXT_RIGHT_JUSTIFIED;

	if (GetFlipFlopUI())
		{
//paint in names
	//draw bone name labels
	//paint in bone names
		int y = 0;
 		int x = 0;
		SetTextColor(hdc,textColor);
		for (int j = 0; j < numberOfRows; j++)
			{
//if not affacted 
//if not get weight
			TSTR boneName("-");
			if ((j+firstRow) < activeBones.Count())
				{
				int currentBone = activeBones[j+firstRow];
				if ((mod) && (currentBone < mod->BoneData.Count()))
					{
					if (mod->BoneData[currentBone].Node)
						{
						boneName.printf("%s",mod->BoneData[currentBone].Node->GetName());

						PaintCellName(hdc, x, y, buttonWidth, (mod->ModeBoneIndex == currentBone), justify,boneName);
						y+= textHeight;
						
						}	
					}
				}

			}

		}
	else
		{
		int y = 0;
		int x = 0;

	//5.1.01
		if (justify == TEXT_LEFT_JUSTIFIED)
			{
			for (int j = 0; j < numberOfColumns; j++)
				{
	//if not affacted 
	//if not get weight
				TSTR boneName("-");
				if ((j+firstColumn) < activeBones.Count())
					{
					int currentBone = activeBones[j+firstColumn];
					if ((mod) && (currentBone < mod->BoneData.Count()))
						{
						if (mod->BoneData[currentBone].Node)
							{
							boneName.printf("%s",mod->BoneData[currentBone].Node->GetName());

	//5.1.01
							PaintCellName(hdc, x, y,buttonWidth, (mod->ModeBoneIndex == currentBone), justify,boneName);
							x+= buttonWidth;
							}	
						}
					}
				}
			}
		else 	//5.1.01
			{
			int ct = 0;
			for (int j = 0; j < numberOfColumns; j++)
				{
				if ((j+firstColumn) < activeBones.Count())
					{
					x += buttonWidth ;
					ct++;
					}
				}

			x -=buttonWidth;
			
			for (j = (numberOfColumns-1); j >= 0; j--)
				{
	//if not affacted 
	//if not get weight
				TSTR boneName("-");
				if ((j+firstColumn) < activeBones.Count())
					{
					int currentBone = activeBones[j+firstColumn];
					if ((mod) && (currentBone < mod->BoneData.Count()))
						{
						if (mod->BoneData[currentBone].Node)
							{
							boneName.printf("%s",mod->BoneData[currentBone].Node->GetName());

	//5.1.01
							PaintCellName(hdc, x, y,buttonWidth, (mod->ModeBoneIndex == currentBone), justify,boneName);
							x-= buttonWidth;
							}	
						}
					}
				}
			}


		}


	BlackBorder(hdc, hWeightListLabel);

	SelectObject(hdc,GetStockObject(BLACK_PEN));
	SelectObject(hdc, hOldFont);
	iWeightListLabelBuf->Blit();
	}
// Imperfect function but hey it's just for testing!
Mesh* Assets::loadMeshFromFile(std::string &filePath)
{
	Assimp::Importer importer;

	const aiScene* scene = importer.ReadFile( filePath, 
        aiProcess_CalcTangentSpace       | 
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  |
        aiProcess_SortByPType);
  
	// If the import failed, report it
	if( !scene)
	{
		std::cout << "Error Loading : " << importer.GetErrorString() << "\n";
		return nullptr;
	}
	
	aiMatrix4x4 globalInverseTransform = scene->mRootNode->mTransformation;
     globalInverseTransform.Inverse();

	// Have to manually convert arrays of assimp's own Vector3 class to vectors of glm::vec3 to make it work for now 
	// Later we can implement faster method that uses the array to directly set vao (I hope...)
	std::vector<glm::vec3> verts;
	std::vector<unsigned int> indices;
	std::vector<glm::vec3> normals;
	std::vector<glm::vec2> uvs;
	std::vector<glm::vec3> colours;
	std::vector<glm::vec3> tangents;
	std::vector<glm::vec3> biTangents;

	// Assimp conversion here!
	aiMesh* loadedMesh = scene->mMeshes[0];

	
	std::map<std::string, int> boneMapping;

	// Lovely bone info
	struct BoneVertexInfo
	{
		int numWeights;
		glm::ivec4 boneID; 
		glm::vec4 boneWeight;

		void addWeight(int boneIDZ, float weight)
		{
			if(numWeights >= 4) return;

			boneID[numWeights] = boneIDZ;
			boneWeight[numWeights] = weight;
			numWeights +=1;
		}
	};

	std::vector<BoneVertexInfo> boneInfos;
	
	
	for(int i = 0; i < loadedMesh->mNumVertices; ++i)
	{
		verts.push_back(glm::vec3(loadedMesh->mVertices[i].x, loadedMesh->mVertices[i].y, loadedMesh->mVertices[i].z));
		
		if(loadedMesh->HasNormals())
			normals.push_back(glm::vec3(loadedMesh->mNormals[i].x, loadedMesh->mNormals[i].y, loadedMesh->mNormals[i].z));
		
		if(loadedMesh->HasTextureCoords(0))
			uvs.push_back(glm::vec2(loadedMesh->mTextureCoords[0][i].x, loadedMesh->mTextureCoords[0][i].y));

		if(loadedMesh->HasTangentsAndBitangents())
		{
			tangents.push_back  (glm::vec3(loadedMesh->mTangents[i].x,  loadedMesh->mTangents[i].y,  loadedMesh->mTangents[i].z));
		    biTangents.push_back(glm::vec3(loadedMesh->mBitangents[i].x,loadedMesh->mBitangents[i].y,loadedMesh->mBitangents[i].z));
		}
		colours.push_back(glm::vec3(1.0f, 1.0f, 1.0f));


		// Push empty values into boneID and boneWeight vectors
		BoneVertexInfo boneInfo;
		boneInfo.numWeights = 0;
		for(int j = 0; j < 4; ++j)
		{
			boneInfo.boneID[j] = 0;
			boneInfo.boneWeight[j] = 0;
		}
		boneInfos.push_back(boneInfo);
		
	}
	for(int i = 0; i < loadedMesh->mNumFaces; ++i)
	{
		for(int j = 0; j < loadedMesh->mFaces[i].mNumIndices; ++j)
		{
			indices.push_back(loadedMesh->mFaces[i].mIndices[j]);
		}
	}






	// This is where the fun starts
	for(int i = 0; i < loadedMesh->mNumBones; ++i) // for each bone
	{
		std::string boneName(loadedMesh->mBones[i]->mName.data);
		boneMapping.emplace(boneName, i);
	}
	/*
	for(int i = 0; i < loadedMesh->mNumBones; ++i) // for each bone
	{
		std::string boneName(loadedMesh->mBones[i]->mName.data);
		std::map<std::string, int>::iterator it = boneMapping.find(boneName);
		int boneID = it->second;

		// Populate BoneID and BoneWeight vectors 
		for(int j = 0; j < loadedMesh->mBones[i]->mNumWeights; ++j) // for each weight
		{
			float weight = loadedMesh->mBones[i]->mWeights[j].mWeight;


			int vertexID = loadedMesh->mBones[i]->mWeights[j].mVertexId;
			boneInfos[vertexID].addWeight(boneID, weight);

			if(weight != 0)
			{
				//std::cout << "HELLO!";
			}
		}
	}
	*/
	
		aiMatrix4x4 BoneOffset;
		std::vector<aiMatrix4x4> boneDataOffset;

	for(int i = 0; i < loadedMesh->mNumBones; ++i) // for each bone
	{
		std::string boneName(loadedMesh->mBones[i]->mName.data);
		std::map<std::string, int>::iterator it = boneMapping.find(boneName);
		int boneID = it->second;
		
			boneDataOffset.push_back(BoneOffset);

			boneDataOffset[i] = loadedMesh->mBones[i]->mOffsetMatrix;

		// Populate BoneID and BoneWeight vectors 
		for(int j = 0; j < loadedMesh->mBones[i]->mNumWeights; ++j) // for each weight
		{
			float weight = loadedMesh->mBones[i]->mWeights[j].mWeight;


			int vertexID = loadedMesh->mBones[i]->mWeights[j].mVertexId;
			boneInfos[vertexID].addWeight(boneID, weight);

			if(weight != 0)
			{
				//std::cout << "HELLO!";
			}
		}
	}
	/*
	int bonesCount = 0;
	for(int i = 0; i < loadedMesh->mNumBones; ++i) // for each bone
	{
		std::string boneName(loadedMesh->mBones[i]->mName.data);

		// Puts in map if not there
		std::map<std::string, int>::iterator it;
		it = boneMapping.find(boneName);

		if(it == boneMapping.end()) // then it can't find it
		{
			boneMapping.emplace(boneName, bonesCount);
			bonesCount ++;
		}
		
		// Get bone index
		GLint boneIndex = boneMapping.find(boneName)->second;

		// Store mOffset matrix from Assimp aiBone class? If we need it...
		// TO DO


		// Populate BoneID and BoneWeight vectors 
		for(int j = 0; j < loadedMesh->mBones[i]->mNumWeights; ++j) // for each
		{
			int vertexID = loadedMesh->mBones[i]->mWeights[j].mVertexId;
			int weigthNum = boneInfos[vertexID].numWeights; // the number of the weight, up to 3 (coz 4 possible)
			if(weigthNum >= 4) continue; //too many bones!!!
			boneInfos[vertexID].numWeights += 1; // add one to num of weights

			boneInfos[vertexID].boneID[weigthNum] = boneIndex;
			boneInfos[vertexID].boneWeight[weigthNum] = loadedMesh->mBones[i]->mWeights[j].mWeight;
		}
	}
	*/

	
	// This is a horrible stupid way of doing it but can change once you know it works
	std::vector<glm::ivec4> boneIDs;
	std::vector<glm::vec4> boneWeights;
	for(int i = 0; i < boneInfos.size(); ++i)
	{
		boneIDs.push_back(boneInfos[i].boneID);
		boneWeights.push_back(boneInfos[i].boneWeight);
	}
	// end horrible way of doing things



	// Now set mesh properties via vector
	Mesh* mesh = new Mesh();
	mesh->generateBuffers();
	mesh->setVerts(verts);
	mesh->setIndices(indices);
	mesh->setNormals(normals);
	mesh->setUvs(uvs);
	mesh->setColours(colours);
	mesh->setTangents(tangents);
	mesh->setBiTangents(biTangents);

	mesh->setBoneMap(boneMapping);
	mesh->setBones(boneIDs, boneWeights);
	mesh->setBoneOffset(boneDataOffset);
	mesh->setInverseTransform(globalInverseTransform);
	mesh->setNumJoints(loadedMesh->mNumBones);

	return mesh;
}
Beispiel #8
0
Mesh* ModelInterface::loadMesh(aiMesh* ai_mesh, aiMaterial* ai_material, const int index)
{
    Q_UNUSED(index)

    Mesh* mesh = new Mesh();

    QVector3D* vertices  = new QVector3D[ai_mesh->mNumVertices];
    QVector3D* normals   = new QVector3D[ai_mesh->mNumVertices];
    QVector3D* tangent   = new QVector3D[ai_mesh->mNumVertices];
    QVector2D* texCoords = new QVector2D[ai_mesh->mNumVertices];
    QVector4D* boneIDs   = new QVector4D[ai_mesh->mNumVertices];
    QVector4D* weight    = new QVector4D[ai_mesh->mNumVertices];

    QVector<uint> indices;

    if(ai_mesh->HasBones() && bones)
    {
        for(uint i = 0; i < ai_mesh->mNumBones; ++i)
        {
            for(uint j = 0; j < ai_mesh->mBones[i]->mNumWeights; ++j)
            {
                QString boneName(ai_mesh->mBones[i]->mName.data);

                aiVertexWeight w  = ai_mesh->mBones[i]->mWeights[j];
                int vertexId      = w.mVertexId;
                float weightValue = w.mWeight;

                int boneID = bones->getBone(boneName)->getId();

                addWeightData(&boneIDs[vertexId], &weight[vertexId], boneID, weightValue);
            }
        }
    }

    for(uint i = 0; i < ai_mesh->mNumVertices; ++i)
    {
        vertices[i] = QVector3D(ai_mesh->mVertices[i].x, ai_mesh->mVertices[i].y, ai_mesh->mVertices[i].z);
        normals[i]  = QVector3D(ai_mesh->mNormals[i].x,  ai_mesh->mNormals[i].y,  ai_mesh->mNormals[i].z);

        if(ai_mesh->mTangents)
            tangent[i] = QVector3D(ai_mesh->mTangents[i].x, ai_mesh->mTangents[i].y, ai_mesh->mTangents[i].z);
        else
            tangent[i] = QVector3D(1.0f, 0.0f, 0.0f);

        if(ai_mesh->mTextureCoords[0])
            texCoords[i] = QVector2D(ai_mesh->mTextureCoords[0][i].x, ai_mesh->mTextureCoords[0][i].y);
        else
            texCoords[i] = QVector2D(0.0f, 0.0f);
    }

    for(uint i = 0; i < ai_mesh->mNumFaces; ++i)
    {
        aiFace face = ai_mesh->mFaces[i];

        for(uint j = 0; j < face.mNumIndices; ++j)
            indices.push_back(face.mIndices[j]);
    }

    loadMaterial(ai_material, mesh);

    mesh->createVertexArrayObject();
    mesh->createBuffer(Mesh::Vertices,  vertices, sizeof(QVector3D)  * ai_mesh->mNumVertices);
    mesh->createBuffer(Mesh::Normals,   normals, sizeof(QVector3D)   * ai_mesh->mNumVertices);
    mesh->createBuffer(Mesh::TexCoords, texCoords, sizeof(QVector2D) * ai_mesh->mNumVertices);
    mesh->createBuffer(Mesh::Tangent,   tangent, sizeof(QVector3D)   * ai_mesh->mNumVertices);
    mesh->createBuffer(Mesh::Bones,     boneIDs, sizeof(QVector4D)   * ai_mesh->mNumVertices);
    mesh->createBuffer(Mesh::Weight,    weight, sizeof(QVector4D)    * ai_mesh->mNumVertices);
    mesh->createBuffer(Mesh::Index,     indices.data(), sizeof(int)  * indices.size());
    mesh->setNumFaces(indices.size());

    delete[] vertices;
    delete[] normals;
    delete[] tangent;
    delete[] texCoords;
    delete[] weight;
    delete[] boneIDs;

    return mesh;
}