Пример #1
0
void CAOGenerator::RenderSetupSceneNode(CConversionSceneNode* pNode, tvector<tvector<float>>& aaflVerts)
{
    if (!pNode)
        return;

    for (size_t c = 0; c < pNode->GetNumChildren(); c++)
        RenderSetupSceneNode(pNode->GetChild(c), aaflVerts);

    for (size_t m = 0; m < pNode->GetNumMeshInstances(); m++)
    {
        CConversionMeshInstance* pMeshInstance = pNode->GetMeshInstance(m);
        CConversionMesh* pMesh = pMeshInstance->GetMesh();
        for (size_t f = 0; f < pMesh->GetNumFaces(); f++)
        {
            CConversionFace* pFace = pMesh->GetFace(f);

            size_t iMaterial = pMeshInstance->GetMappedMaterial(pFace->m)->m_iMaterial;
            while (aaflVerts.size() <= iMaterial)
                aaflVerts.push_back();

            CConversionVertex* pVertex0 = pFace->GetVertex(0);

            for (size_t k = 2; k < pFace->GetNumVertices(); k++)
            {
                CConversionVertex* pVertex1 = pFace->GetVertex(k-1);
                CConversionVertex* pVertex2 = pFace->GetVertex(k);

                AddRenderedVertex(aaflVerts[iMaterial], pMeshInstance->GetVertex(pVertex0->v), pMesh->GetUV(pVertex0->vu));
                AddRenderedVertex(aaflVerts[iMaterial], pMeshInstance->GetVertex(pVertex1->v), pMesh->GetUV(pVertex1->vu));
                AddRenderedVertex(aaflVerts[iMaterial], pMeshInstance->GetVertex(pVertex2->v), pMesh->GetUV(pVertex2->vu));
            }
        }
    }
}
Пример #2
0
void CGeppetto::LoadMeshInstanceIntoToyPhysics(CConversionScene* pScene, CConversionMeshInstance* pMeshInstance, const Matrix4x4& mParentTransformations, CToyUtil* pToy)
{
	if (!pMeshInstance->IsVisible())
		return;

	CConversionMesh* pMesh = pMeshInstance->GetMesh();

	size_t iVertsSize = pToy->GetNumPhysVerts();

	for (size_t v = 0; v < pMesh->GetNumVertices(); v++)
		pToy->AddPhysVertex(mParentTransformations * pMesh->GetVertex(v));

	for (size_t j = 0; j < pMesh->GetNumFaces(); j++)
	{
		size_t k;
		CConversionFace* pFace = pMesh->GetFace(j);

		CConversionVertex* pVertex0 = pFace->GetVertex(0);

		for (k = 2; k < pFace->GetNumVertices(); k++)
		{
			CConversionVertex* pVertex1 = pFace->GetVertex(k-1);
			CConversionVertex* pVertex2 = pFace->GetVertex(k);

			pToy->AddPhysTriangle(iVertsSize + pVertex0->v, iVertsSize + pVertex1->v, iVertsSize + pVertex2->v);
		}
	}
}
Пример #3
0
void CTexelNormalMethod::GenerateTexel(size_t iTexel, CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, CConversionVertex* pV1, CConversionVertex* pV2, CConversionVertex* pV3, raytrace::CTraceResult* tr, const Vector& vecUVPosition, raytrace::CRaytracer* pTracer)
{
	CConversionFace* pHitFace = tr->m_pMeshInstance->GetMesh()->GetFace(tr->m_iFace);
	Vector vecHitNormal = pHitFace->GetNormal(tr->m_vecHit, tr->m_pMeshInstance);

	// Build rotation matrix
	Matrix4x4 mObjectToTangent;

	Vector t = pFace->GetBaseVector(vecUVPosition, 0, pMeshInstance);
	Vector b = pFace->GetBaseVector(vecUVPosition, 1, pMeshInstance);
	Vector n = pFace->GetBaseVector(vecUVPosition, 2, pMeshInstance);

	mObjectToTangent.SetForwardVector(t);
	mObjectToTangent.SetUpVector(b);
	mObjectToTangent.SetRightVector(n);
	mObjectToTangent.InvertRT();

	Vector vecTangentNormal = mObjectToTangent*vecHitNormal;

	m_pGenerator->GetParallelizer()->LockData();

	m_avecNormalValues[iTexel] += vecTangentNormal;
	m_pGenerator->MarkTexelUsed(iTexel);

	m_pGenerator->GetParallelizer()->UnlockData();
}
Пример #4
0
void CAOGenerator::GenerateNodeByTexel(CConversionSceneNode* pNode, raytrace::CRaytracer* pTracer, size_t& iRendered)
{
    for (size_t c = 0; c < pNode->GetNumChildren(); c++)
        GenerateNodeByTexel(pNode->GetChild(c), pTracer, iRendered);

    for (size_t m = 0; m < pNode->GetNumMeshInstances(); m++)
    {
        CConversionMeshInstance* pMeshInstance = pNode->GetMeshInstance(m);
        CConversionMesh* pMesh = pMeshInstance->GetMesh();

        if (!pMesh->GetNumUVs())
            continue;

        for (size_t f = 0; f < pMesh->GetNumFaces(); f++)
        {
            CConversionFace* pFace = pMesh->GetFace(f);

            if (pFace->m != ~0)
            {
                if (!pMeshInstance->GetMappedMaterial(pFace->m)->IsVisible())
                    continue;

                CConversionMaterial* pMaterial = m_pScene->GetMaterial(pMeshInstance->GetMappedMaterial(pFace->m)->m_iMaterial);
                if (pMaterial && !pMaterial->IsVisible())
                    continue;
            }

            tvector<Vector> avecPoints;
            tvector<size_t> aiPoints;
            for (size_t t = 0; t < pFace->GetNumVertices(); t++)
            {
                avecPoints.push_back(pMeshInstance->GetVertex(pFace->GetVertex(t)->v));
                aiPoints.push_back(t);
            }

            while (avecPoints.size() > 3)
            {
                size_t iEar = FindEar(avecPoints);
                size_t iLast = iEar==0?avecPoints.size()-1:iEar-1;
                size_t iNext = iEar==avecPoints.size()-1?0:iEar+1;
                GenerateTriangleByTexel(pMeshInstance, pFace, aiPoints[iLast], aiPoints[iEar], aiPoints[iNext], pTracer, iRendered);
                avecPoints.erase(avecPoints.begin()+iEar);
                aiPoints.erase(aiPoints.begin()+iEar);
                if (m_bStopGenerating)
                    break;
            }
            GenerateTriangleByTexel(pMeshInstance, pFace, aiPoints[0], aiPoints[1], aiPoints[2], pTracer, iRendered);
            if (m_bStopGenerating)
                break;
        }
        if (m_bStopGenerating)
            break;
    }
}
Пример #5
0
void LoadMeshInstanceIntoToy(CConversionScene* pScene, CConversionMeshInstance* pMeshInstance, const Matrix4x4& mParentTransformations)
{
	if (!pMeshInstance->IsVisible())
		return;

	CConversionMesh* pMesh = pMeshInstance->GetMesh();

	for (size_t m = 0; m < pScene->GetNumMaterials(); m++)
	{
		for (size_t j = 0; j < pMesh->GetNumFaces(); j++)
		{
			size_t k;
			CConversionFace* pFace = pMesh->GetFace(j);

			if (pFace->m == ~0)
				continue;

			CConversionMaterial* pMaterial = NULL;
			CConversionMaterialMap* pConversionMaterialMap = pMeshInstance->GetMappedMaterial(pFace->m);

			if (!pConversionMaterialMap)
				continue;

			if (!pConversionMaterialMap->IsVisible())
				continue;

			if (pConversionMaterialMap->m_iMaterial != m)
				continue;

			while (g_asTextures.size() <= pConversionMaterialMap->m_iMaterial)
			{
				g_asTextures.push_back(pScene->GetMaterial(pConversionMaterialMap->m_iMaterial)->GetDiffuseTexture());
				g_aaflData.push_back();
			}

			size_t iMaterial = pConversionMaterialMap->m_iMaterial;

			CConversionVertex* pVertex0 = pFace->GetVertex(0);

			for (k = 2; k < pFace->GetNumVertices(); k++)
			{
				CConversionVertex* pVertex1 = pFace->GetVertex(k-1);
				CConversionVertex* pVertex2 = pFace->GetVertex(k);

				AddVertex(iMaterial, mParentTransformations * pMesh->GetVertex(pVertex0->v), pMesh->GetUV(pVertex0->vu));
				AddVertex(iMaterial, mParentTransformations * pMesh->GetVertex(pVertex1->v), pMesh->GetUV(pVertex1->vu));
				AddVertex(iMaterial, mParentTransformations * pMesh->GetVertex(pVertex2->v), pMesh->GetUV(pVertex2->vu));
			}
		}
	}
}
Пример #6
0
void CAOGenerator::GenerateByTexel()
{
    if (m_eAOMethod == AOMETHOD_RAYTRACE)
        RaytraceSetupThreads();

    float flTotalArea = 0;

    for (size_t m = 0; m < m_pScene->GetNumMeshes(); m++)
    {
        CConversionMesh* pMesh = m_pScene->GetMesh(m);
        for (size_t f = 0; f < pMesh->GetNumFaces(); f++)
        {
            CConversionFace* pFace = pMesh->GetFace(f);
            flTotalArea += pFace->GetUVArea();
        }
    }

    raytrace::CRaytracer* pTracer = NULL;

    if (m_eAOMethod == AOMETHOD_RAYTRACE)
    {
        m_pWorkListener->SetAction("Building tree", 0);

        pTracer = new raytrace::CRaytracer(m_pScene);
        pTracer->AddMeshesFromNode(m_pScene->GetScene(0));
        pTracer->BuildTree();

        srand((unsigned int)time(0));
    }

    if (m_eAOMethod == AOMETHOD_RAYTRACE && GetNumberOfProcessors() > 1)
        m_pWorkListener->SetAction("Dispatching jobs", (size_t)(flTotalArea*m_iWidth*m_iHeight));
    else
        m_pWorkListener->SetAction("Rendering", (size_t)(flTotalArea*m_iWidth*m_iHeight));

    size_t iRendered = 0;

    if (m_pScene->GetNumScenes())
        GenerateNodeByTexel(m_pScene->GetScene(0), pTracer, iRendered);

    if (m_eAOMethod == AOMETHOD_RAYTRACE)
    {
        RaytraceJoinThreads();
        RaytraceCleanupThreads();
        delete pTracer;
    }
}
Пример #7
0
void CAOGenerator::ShadowMapSetupSceneNode(CConversionSceneNode* pNode, tvector<float>& aflVerts, bool bDepth)
{
    if (!pNode)
        return;

    for (size_t c = 0; c < pNode->GetNumChildren(); c++)
        ShadowMapSetupSceneNode(pNode->GetChild(c), aflVerts, bDepth);

    for (size_t m = 0; m < pNode->GetNumMeshInstances(); m++)
    {
        CConversionMeshInstance* pMeshInstance = pNode->GetMeshInstance(m);
        CConversionMesh* pMesh = pMeshInstance->GetMesh();
        for (size_t f = 0; f < pMesh->GetNumFaces(); f++)
        {
            CConversionFace* pFace = pMesh->GetFace(f);

            if (!bDepth)
            {
                // Allow this in the depth model so that it still projects a shadow, but we don't produce a map for it.
                if (pFace->m != ~0 && pMeshInstance->GetMappedMaterial(pFace->m))
                {
                    if (!pMeshInstance->GetMappedMaterial(pFace->m)->IsVisible())
                        continue;

                    CConversionMaterial* pMaterial = m_pScene->GetMaterial(pMeshInstance->GetMappedMaterial(pFace->m)->m_iMaterial);
                    if (pMaterial && !pMaterial->IsVisible())
                        continue;
                }
            }

            CConversionVertex* pVertex0 = pFace->GetVertex(0);

            for (size_t k = 2; k < pFace->GetNumVertices(); k++)
            {
                CConversionVertex* pVertex1 = pFace->GetVertex(k-1);
                CConversionVertex* pVertex2 = pFace->GetVertex(k);

                AddShadowMapVertex(aflVerts, pMeshInstance->GetVertex(pVertex0->v), pMeshInstance->GetNormal(pVertex0->vn), pMesh->GetUV(pVertex0->vu));
                AddShadowMapVertex(aflVerts, pMeshInstance->GetVertex(pVertex1->v), pMeshInstance->GetNormal(pVertex1->vn), pMesh->GetUV(pVertex1->vu));
                AddShadowMapVertex(aflVerts, pMeshInstance->GetVertex(pVertex2->v), pMeshInstance->GetNormal(pVertex2->vn), pMesh->GetUV(pVertex2->vu));
            }
        }
    }
}
Пример #8
0
void CModelConverter::SaveSIA(const tstring& sFilename)
{
	tstring sSIAFileName = tstring(GetDirectory(sFilename).c_str()) + _T("/") + GetFilename(sFilename).c_str() + _T(".sia");

	std::wofstream sFile(convertstring<tchar, char>(sSIAFileName).c_str());
	if (!sFile.is_open())
		return;

	sFile.precision(8);
	sFile.setf(std::ios::fixed, std::ios::floatfield);

	if (m_pWorkListener)
	{
		m_pWorkListener->BeginProgress();
		m_pWorkListener->SetAction(_T("Writing materials..."), 0);
	}

	sFile << _T("-Version 1.0") << std::endl;

	for (size_t i = 0; i < m_pScene->GetNumMaterials(); i++)
	{
		sFile << _T("-Mat") << std::endl;

		CConversionMaterial* pMaterial = m_pScene->GetMaterial(i);

		sFile << "-amb " << pMaterial->m_vecAmbient.x << _T(" ") << pMaterial->m_vecAmbient.y << _T(" ") << pMaterial->m_vecAmbient.z << _T(" 0") << std::endl;
		sFile << "-dif " << pMaterial->m_vecDiffuse.x << _T(" ") << pMaterial->m_vecDiffuse.y << _T(" ") << pMaterial->m_vecDiffuse.z << _T(" 0") << std::endl;
		sFile << "-spec " << pMaterial->m_vecSpecular.x << _T(" ") << pMaterial->m_vecSpecular.y << _T(" ") << pMaterial->m_vecSpecular.z << _T(" 0") << std::endl;
		sFile << "-emis " << pMaterial->m_vecEmissive.x << _T(" ") << pMaterial->m_vecEmissive.y << _T(" ") << pMaterial->m_vecEmissive.z << _T(" 0") << std::endl;
		sFile << "-shin " << pMaterial->m_flShininess << std::endl;
		sFile << "-name \"" << pMaterial->GetName().c_str() << _T("\"") << std::endl;
		if (pMaterial->GetDiffuseTexture().length() > 0)
			sFile << "-tex \"" << pMaterial->GetDiffuseTexture().c_str() << _T("\"") << std::endl;
		sFile << _T("-endMat") << std::endl;
	}

	for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++)
	{
		CConversionMesh* pMesh = m_pScene->GetMesh(i);

		size_t iAddV = pMesh->GetNumVertices();
		size_t iAddE = pMesh->GetNumEdges();
		size_t iAddUV = pMesh->GetNumUVs();
		size_t iAddN = pMesh->GetNumNormals();

		// Find the default scene for this mesh.
		CConversionSceneNode* pScene = NULL;
		for (size_t j = 0; j < m_pScene->GetNumScenes(); j++)
		{
			if (m_pScene->GetScene(j)->GetName() == pMesh->GetName() + _T(".sia"))
			{
				pScene = m_pScene->GetScene(j);
				break;
			}
		}

		tstring sNodeName = pMesh->GetName();

		sFile << _T("-Shape") << std::endl;
		sFile << _T("-snam \"") << sNodeName.c_str() << _T("\"") << std::endl;
		sFile << _T("-shad 0") << std::endl;
		sFile << _T("-shadw 1") << std::endl;

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" vertices...")).c_str(), pMesh->GetNumVertices());

		for (size_t iVertices = 0; iVertices < pMesh->GetNumVertices(); iVertices++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iVertices);

			Vector vecVertex = pMesh->GetVertex(iVertices);
			sFile << _T("-vert ") << vecVertex.x << _T(" ") << vecVertex.y << _T(" ") << vecVertex.z << std::endl;
		}

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" edges...")).c_str(), pMesh->GetNumEdges());

		tstring sCreases;

		for (size_t iEdges = 0; iEdges < pMesh->GetNumEdges(); iEdges++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iEdges);

			CConversionEdge* pEdge = pMesh->GetEdge(iEdges);
			sFile << _T("-edge ") << pEdge->v1 << _T(" ") << pEdge->v2 << std::endl;

			if (pEdge->m_bCreased)
				sCreases += sprintf(tstring(" %d"), iEdges);
		}

		if (sCreases.length())
			sFile << _T("-creas") << sCreases.c_str() << std::endl;

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" faces...")).c_str(), pMesh->GetNumFaces());

		size_t iMaterial = 0;

		for (size_t iFaces = 0; iFaces < pMesh->GetNumFaces(); iFaces++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iFaces);

			CConversionFace* pFace = pMesh->GetFace(iFaces);

			if (iFaces == 0 || iMaterial != pFace->m)
			{
				iMaterial = pFace->m;

				if (iMaterial == ~0)
					sFile << _T("-setmat -1") << std::endl;
				else
				{
					CConversionSceneNode* pNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh, false);

					if (!pNode || pNode->GetNumMeshInstances() != 1)
						sFile << _T("-setmat -1") << std::endl;
					else
					{
						CConversionMaterialMap* pMap = pNode->GetMeshInstance(0)->GetMappedMaterial(iMaterial);
						if (pMap)
							sFile << _T("-setmat -1") << std::endl;
						else
							sFile << _T("-setmat ") << pMap->m_iMaterial << std::endl;
					}
				}
			}

			sFile << _T("-face ") << pFace->GetNumVertices();

			TAssert(pFace->GetNumEdges() == pFace->GetNumVertices());

			for (size_t iVertsInFace = 0; iVertsInFace < pFace->GetNumVertices(); iVertsInFace++)
			{
				CConversionVertex* pVertex = pFace->GetVertex(iVertsInFace);
				CConversionVertex* pNextVertex = pFace->GetVertex((iVertsInFace+1)%pFace->GetNumVertices());

				// Find the edge that heads in a counter-clockwise direction.
				size_t iEdge = ~0;
				for (size_t i = 0; i < pFace->GetNumEdges(); i++)
				{
					size_t iEdgeCandidate = pFace->GetEdge(i);
					CConversionEdge* pEdge = pMesh->GetEdge(iEdgeCandidate);
					if ((pEdge->v1 == pVertex->v && pEdge->v2 == pNextVertex->v) || (pEdge->v2 == pVertex->v && pEdge->v1 == pNextVertex->v))
					{
						iEdge = iEdgeCandidate;
						break;
					}
				}
				TAssert(iEdge != ~0);

				Vector vecUV = pMesh->GetUV(pVertex->vu);
				sFile << _T(" ") << pVertex->v << _T(" ") << iEdge << _T(" ") << vecUV.x << _T(" ") << vecUV.y;
			}

			sFile << std::endl;
		}

		sFile << _T("-axis 0 0.5 0 1 0 0 0 1 0 0 0 1") << std::endl;
		sFile << _T("-mirp 0 0 0 1 0 0") << std::endl;
		sFile << _T("-endShape") << std::endl;
	}

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
Пример #9
0
void CModelConverter::SaveOBJ(const tstring& sFilename)
{
	tstring sMaterialFileName = tstring(GetDirectory(sFilename).c_str()) + _T("/") + GetFilename(sFilename).c_str() + _T(".mtl");

	std::wofstream sMaterialFile(convertstring<tchar, char>(sMaterialFileName).c_str());
	if (!sMaterialFile.is_open())
		return;

	if (m_pWorkListener)
	{
		m_pWorkListener->BeginProgress();
		m_pWorkListener->SetAction(_T("Writing materials file"), 0);
	}

	for (size_t i = 0; i < m_pScene->GetNumMaterials(); i++)
	{
		CConversionMaterial* pMaterial = m_pScene->GetMaterial(i);
		sMaterialFile << "newmtl " << pMaterial->GetName().c_str() << std::endl;
		sMaterialFile << "Ka " << pMaterial->m_vecAmbient.x << _T(" ") << pMaterial->m_vecAmbient.y << _T(" ") << pMaterial->m_vecAmbient.z << std::endl;
		sMaterialFile << "Kd " << pMaterial->m_vecDiffuse.x << _T(" ") << pMaterial->m_vecDiffuse.y << _T(" ") << pMaterial->m_vecDiffuse.z << std::endl;
		sMaterialFile << "Ks " << pMaterial->m_vecSpecular.x << _T(" ") << pMaterial->m_vecSpecular.y << _T(" ") << pMaterial->m_vecSpecular.z << std::endl;
		sMaterialFile << "d " << pMaterial->m_flTransparency << std::endl;
		sMaterialFile << "Ns " << pMaterial->m_flShininess << std::endl;
		sMaterialFile << "illum " << pMaterial->m_eIllumType << std::endl;
		if (pMaterial->GetDiffuseTexture().length() > 0)
			sMaterialFile << "map_Kd " << pMaterial->GetDiffuseTexture().c_str() << std::endl;
		sMaterialFile << std::endl;
	}

	sMaterialFile.close();

	for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++)
	{
		CConversionMesh* pMesh = m_pScene->GetMesh(i);

		// Find the default scene for this mesh.
		CConversionSceneNode* pScene = NULL;
		for (size_t j = 0; j < m_pScene->GetNumScenes(); j++)
		{
			if (m_pScene->GetScene(j)->GetName() == pMesh->GetName() + _T(".obj"))
			{
				pScene = m_pScene->GetScene(j);
				break;
			}
		}

		tstring sNodeName = pMesh->GetName();

		tstring sOBJFilename = tstring(GetDirectory(sFilename).c_str()) + _T("/") + GetFilename(sNodeName).c_str() + _T(".obj");
		tstring sMTLFilename = tstring(GetFilename(sFilename).c_str()) + _T(".mtl");

		if (m_pScene->GetNumMeshes() == 1)
			sOBJFilename = sFilename;

		std::wofstream sOBJFile(convertstring<tchar, char>(sOBJFilename).c_str());
		sOBJFile.precision(8);
		sOBJFile.setf(std::ios::fixed, std::ios::floatfield);

		sOBJFile << _T("mtllib ") << sMTLFilename.c_str() << std::endl;
		sOBJFile << std::endl;

		sOBJFile << _T("o ") << sNodeName.c_str() << std::endl;

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" vertices...")).c_str(), pMesh->GetNumVertices());

		for (size_t iVertices = 0; iVertices < pMesh->GetNumVertices(); iVertices++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iVertices);

			Vector vecVertex = pMesh->GetVertex(iVertices);
			sOBJFile << _T("v ") << vecVertex.x << _T(" ") << vecVertex.y << _T(" ") << vecVertex.z << std::endl;
		}

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" normals...")).c_str(), pMesh->GetNumNormals());

		for (size_t iNormals = 0; iNormals < pMesh->GetNumNormals(); iNormals++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iNormals);

			Vector vecNormal = pMesh->GetNormal(iNormals);
			sOBJFile << _T("vn ") << vecNormal.x << _T(" ") << vecNormal.y << _T(" ") << vecNormal.z << std::endl;
		}

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" UVs...")).c_str(), pMesh->GetNumUVs());

		for (size_t iUVs = 0; iUVs < pMesh->GetNumUVs(); iUVs++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iUVs);

			Vector vecUV = pMesh->GetUV(iUVs);
			sOBJFile << _T("vt ") << vecUV.x << _T(" ") << vecUV.y << std::endl;
		}

		if (m_pWorkListener)
			m_pWorkListener->SetAction((tstring(_T("Writing ")) + sNodeName + _T(" faces...")).c_str(), pMesh->GetNumFaces());

		size_t iLastMaterial = ~0;

		for (size_t iFaces = 0; iFaces < pMesh->GetNumFaces(); iFaces++)
		{
			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(iFaces);

			CConversionFace* pFace = pMesh->GetFace(iFaces);

			if (pFace->m != iLastMaterial)
			{
				iLastMaterial = pFace->m;

				CConversionSceneNode* pNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh, false);
				if (!pNode || pNode->GetNumMeshInstances() != 1)
					sOBJFile << "usemtl " << iLastMaterial << std::endl;
				else
				{
					CConversionMaterialMap* pMap = pNode->GetMeshInstance(0)->GetMappedMaterial(iLastMaterial);
					if (!pMap)
						sOBJFile << "usemtl " << iLastMaterial << std::endl;
					else
						sOBJFile << "usemtl " << m_pScene->GetMaterial(pMap->m_iMaterial)->GetName().c_str() << std::endl;
				}
			}

			sOBJFile << _T("f");
			for (size_t iVertsInFace = 0; iVertsInFace < pFace->GetNumVertices(); iVertsInFace++)
			{
				CConversionVertex* pVertex = pFace->GetVertex(iVertsInFace);
				sOBJFile << _T(" ") << pVertex->v+1 << _T("/") << pVertex->vu+1 << _T("/") << pVertex->vn+1;
			}
			sOBJFile << std::endl;
		}

		sOBJFile << std::endl;

		sOBJFile.close();
	}

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
Пример #10
0
void CTexelAOMethod::GenerateTexel(size_t iTexel, CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, CConversionVertex* pV1, CConversionVertex* pV2, CConversionVertex* pV3, raytrace::CTraceResult* tr, const Vector& vecUVPosition, raytrace::CRaytracer* pTracer)
{
	CConversionFace* pHitFace = tr->m_pMeshInstance->GetMesh()->GetFace(tr->m_iFace);
	Vector vecHitNormal = pHitFace->GetNormal(tr->m_vecHit, tr->m_pMeshInstance);

	// Build rotation matrix
	Matrix4x4 m;
	m.SetOrientation(vecHitNormal);

	// Turn it sideways so that pitch 90 is up
	Matrix4x4 m2;
	m2.SetAngles(EAngle(-90, 0, 0));

	m *= m2;

	//SMAKWindow()->AddDebugLine(vecUVPosition + pFace->GetNormal()*0.01f, vecUVPosition + vecNormal*0.5f, Color(0, 0, 255));

	float flHits = 0;
	float flTotalHits = 0;

	for (size_t x = 0; x < m_iSamples/2; x++)
	{
		float flRandom = 0;
		if (m_bRandomize)
			flRandom = RemapVal((float)(rand()%10000), 0, 10000.0f, -0.5f, 0.5f);

		float flPitch = RemapVal(cos(RemapVal((float)x+flRandom, 0, (float)m_iSamples/2, 0, (float)M_PI/2)), 0, 1, 90, 0);

		float flWeight = sin(flPitch * M_PI/180);

		for (size_t y = 0; y <= m_iSamples; y++)
		{
			flRandom = 0;
			if (m_bRandomize)
				flRandom = RemapVal((float)(rand()%10000), 0, 10000.0f, -0.5f, 0.5f);

			float flYaw = RemapVal((float)y+flRandom, 0, (float)m_iSamples, -180, 180);

			Vector vecDir = AngleVector(EAngle(flPitch, flYaw, 0));

			// Transform relative to the triangle's normal
			Vector vecRay = m * vecDir;

			flTotalHits += flWeight;

			//SMAKWindow()->AddDebugLine(vecUVPosition + pFace->GetNormal()*0.01f, vecUVPosition + vecRay.Normalized()*0.1f, vecDir);

			raytrace::CTraceResult tr2;
			if (pTracer->Raytrace(Ray(tr->m_vecHit + vecHitNormal*0.01f, vecRay), &tr2))
			{
				float flDistance = (tr2.m_vecHit - tr->m_vecHit).Length();
				if (m_flRayFalloff < 0)
					flHits += flWeight;
				else
					flHits += flWeight * (1/pow(2, flDistance/m_flRayFalloff));
			}
			else if (m_bGroundOcclusion && vecRay.y < 0)
			{
				// The following math is basically a plane-ray intersection algorithm,
				// with shortcuts made for the assumption of an infinite plane facing straight up.

				Vector n = Vector(0,1,0);

				float a = -(vecUVPosition.y - pMeshInstance->m_pParent->m_oExtends.m_vecMins.y);
				float b = vecRay.y;

				float flDistance = a/b;

				if (flDistance < 1e-4f || m_flRayFalloff < 0)
					flHits += flWeight;
				else
					flHits += flWeight * (1/pow(2, flDistance/m_flRayFalloff));
			}
		}
	}

	// One last ray directly up, it is skipped in the above loop so it's not done 10 times.
	Vector vecDir = AngleVector(EAngle(90, 0, 0));

	// Transform relative to the triangle's normal
	Vector vecRay = m * vecDir;

	//RenderSceneFromPosition(vecUVPosition, vecRay, pFace);

	flTotalHits++;

	//SMAKWindow()->AddDebugLine(vecUVPosition + pFace->GetNormal()*0.01f, vecUVPosition + vecRay.Normalized()*0.2f, vecDir);

	raytrace::CTraceResult tr2;
	if (pTracer->Raytrace(Ray(tr->m_vecHit + vecHitNormal*0.01f, vecRay), &tr2))
	{
		float flDistance = (tr2.m_vecHit - tr->m_vecHit).Length();
		if (m_flRayFalloff < 0)
			flHits += 1;
		else
			flHits += (1/pow(2, flDistance/m_flRayFalloff));
	}
	else if (m_bGroundOcclusion && vecRay.y < 0)
	{
		// The following math is basically a plane-ray intersection algorithm,
		// with shortcuts made for the assumption of an infinite plane facing straight up.
		float a = -(tr->m_vecHit.y - pMeshInstance->m_pParent->m_oExtends.m_vecMins.y);
		float b = vecRay.y;

		float flDistance = a/b;

		if (flDistance < 1e-4f || m_flRayFalloff < 0)
			flHits += 1;
		else
			flHits += (1/pow(2, flDistance/m_flRayFalloff));
	}

	float flShadowValue = 1 - ((float)flHits / (float)flTotalHits);

	// Mutex may be dead, try to bail before.
	if (m_pGenerator->IsStopped())
		return;

	m_pGenerator->GetParallelizer()->LockData();

	m_avecShadowValues[iTexel] += Vector(flShadowValue, flShadowValue, flShadowValue);
	m_aiShadowReads[iTexel]++;
	m_pGenerator->MarkTexelUsed(iTexel);

	m_pGenerator->GetParallelizer()->UnlockData();
}
Пример #11
0
void CTexelDiffuseMethod::GenerateTexel(size_t iTexel, CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, CConversionVertex* pV1, CConversionVertex* pV2, CConversionVertex* pV3, raytrace::CTraceResult* tr, const Vector& vecUVPosition, raytrace::CRaytracer* pTracer)
{
	CConversionFace* pHitFace = tr->m_pMeshInstance->GetMesh()->GetFace(tr->m_iFace);
	CTexture& oTexture = m_aTextures[tr->m_pMeshInstance->GetMappedMaterial(pHitFace->m)->m_iMaterial];

	if (!oTexture.m_pclrData)
		return;

	CConversionMesh* pHitMesh = tr->m_pMeshInstance->GetMesh();

	// TODO: Use the nearest triangle in this face.
	CConversionVertex* pHitV1 = pHitFace->GetVertex(0);
	CConversionVertex* pHitV2 = pHitFace->GetVertex(1);
	CConversionVertex* pHitV3 = pHitFace->GetVertex(2);

	Vector2D vu1 = pHitMesh->GetUV(pHitV1->vu);
	Vector2D vu2 = pHitMesh->GetUV(pHitV2->vu);
	Vector2D vu3 = pHitMesh->GetUV(pHitV3->vu);

	Vector v1 = tr->m_pMeshInstance->GetVertex(pHitV1->v);
	Vector v2 = tr->m_pMeshInstance->GetVertex(pHitV2->v);
	Vector v3 = tr->m_pMeshInstance->GetVertex(pHitV3->v);

	// Find where the world point is in UV space.

	// First convert to barycentric coordinates.
	Vector u = v2 - v1;
	Vector v = v3 - v1;
	float uu = u.Dot(u);
	float uv = u.Dot(v);
	float vv = v.Dot(v);
	Vector w = tr->m_vecHit - v1;
	float wu = w.Dot(u);
	float wv = w.Dot(v);

	float D = uv * uv - uu * vv;

	float b1, b2, b3;

	b1 = (uv * wu - uu * wv) / D;
	b2 = (uv * wv - vv * wu) / D;
	b3 = 1 - b1 - b2;

	// The position of the traceline's hit in (u, v) texture space
	Vector2D vecWorldPosition = vu1 * b1 + vu2 * b2 + vu3 * b3;

	// Mutex may be dead, try to bail before.
	if (m_pGenerator->IsStopped())
		return;

	size_t iU = (size_t)((vecWorldPosition.x * oTexture.m_iWidth) - 0.5f);
	size_t iV = (size_t)((vecWorldPosition.y * oTexture.m_iHeight) - 0.5f);

	iU %= oTexture.m_iWidth;
	iV %= oTexture.m_iHeight;

	size_t iColorTexel;
	m_pGenerator->Texel(iU, iV, iColorTexel, oTexture.m_iWidth, oTexture.m_iHeight);

	Color clrData = oTexture.m_pclrData[iColorTexel];

	m_pGenerator->GetParallelizer()->LockData();

	m_avecDiffuseValues[iTexel] += Vector(clrData);
	m_aiDiffuseReads[iTexel]++;
	m_pGenerator->MarkTexelUsed(iTexel);

	m_pGenerator->GetParallelizer()->UnlockData();
}
Пример #12
0
void CTexelGenerator::Generate()
{
	for (size_t i = 0; i < m_apMethods.size(); i++)
		m_apMethods[i]->PreGenerate();

	if (m_pWorkListener)
	{
		m_pWorkListener->BeginProgress();
		m_pWorkListener->SetAction("Building tree", 0);
	}

	if (SMAKWindow())
		SMAKWindow()->ClearDebugLines();

	memset(&m_abTexelMask[0], 0, m_iWidth*m_iHeight*sizeof(bool));

	m_bIsGenerating = true;
	m_bStopGenerating = false;
	m_bDoneGenerating = false;

	raytrace::CRaytracer* pTracer = NULL;

	pTracer = new raytrace::CRaytracer(m_pScene);

	for (size_t	m = 0; m < m_apHiRes.size(); m++)
		pTracer->AddMeshInstance(m_apHiRes[m]);

	pTracer->BuildTree();

	m_pWorkParallelizer = new CParallelizer((JobCallback)::ComputeAtTexel);
	m_pWorkParallelizer->Start();

	float flTotalArea = 0;

	for (size_t m = 0; m < m_pScene->GetNumMeshes(); m++)
	{
		CConversionMesh* pMesh = m_pScene->GetMesh(m);
		for (size_t f = 0; f < pMesh->GetNumFaces(); f++)
		{
			CConversionFace* pFace = pMesh->GetFace(f);
			flTotalArea += pFace->GetUVArea();
		}
	}

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Dispatching jobs", (size_t)(flTotalArea*m_iWidth*m_iHeight));

	size_t iRendered = 0;

	tvector<Vector> avecPoints;
	tvector<size_t> aiPoints;

	for (size_t i = 0; i < m_apLoRes.size(); i++)
	{
		CConversionMeshInstance* pMeshInstance = m_apLoRes[i];

		if (!pMeshInstance->GetMesh()->GetNumUVs())
			continue;

		for (size_t f = 0; f < pMeshInstance->GetMesh()->GetNumFaces(); f++)
		{
			CConversionFace* pFace = pMeshInstance->GetMesh()->GetFace(f);

			if (pFace->m != ~0)
			{
				if (!pMeshInstance->GetMappedMaterial(pFace->m)->IsVisible())
					continue;

				CConversionMaterial* pMaterial = m_pScene->GetMaterial(pMeshInstance->GetMappedMaterial(pFace->m)->m_iMaterial);
				if (pMaterial && !pMaterial->IsVisible())
					continue;
			}

			avecPoints.clear();
			aiPoints.clear();
			for (size_t t = 0; t < pFace->GetNumVertices(); t++)
			{
				avecPoints.push_back(pMeshInstance->GetVertex(pFace->GetVertex(t)->v));
				aiPoints.push_back(t);
			}

			while (avecPoints.size() > 3)
			{
				size_t iEar = FindEar(avecPoints);
				size_t iLast = iEar==0?avecPoints.size()-1:iEar-1;
				size_t iNext = iEar==avecPoints.size()-1?0:iEar+1;
				GenerateTriangleByTexel(pMeshInstance, pFace, aiPoints[iLast], aiPoints[iEar], aiPoints[iNext], pTracer, iRendered);
				avecPoints.erase(avecPoints.begin()+iEar);
				aiPoints.erase(aiPoints.begin()+iEar);
				if (m_bStopGenerating)
					break;
			}
			GenerateTriangleByTexel(pMeshInstance, pFace, aiPoints[0], aiPoints[1], aiPoints[2], pTracer, iRendered);
			if (m_bStopGenerating)
				break;
		}
		if (m_bStopGenerating)
			break;
	}

	m_pWorkParallelizer->FinishJobs();

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Rendering", m_pWorkParallelizer->GetJobsTotal());

	while (true)
	{
		if (m_pWorkParallelizer->AreAllJobsDone())
			break;

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(m_pWorkParallelizer->GetJobsDone());

		if (m_bStopGenerating)
			break;
	}

	delete m_pWorkParallelizer;

	delete pTracer;

	for (size_t i = 0; i < m_apMethods.size(); i++)
		m_apMethods[i]->PostGenerate();

	if (!m_bStopGenerating)
		m_bDoneGenerating = true;
	m_bIsGenerating = false;

	// One last call to let them know we're done.
	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
Пример #13
0
void CModelConverter::WriteSMD(size_t iMesh, const tstring& sFilename)
{
	CConversionMesh* pMesh = m_pScene->GetMesh(iMesh);

	tstring sFile;
	if (sFilename.length())
	{
		sFile.append(sFilename);
		sFile.append(_T("_"));
	}
	sFile.append(pMesh->GetBoneName(0));

	sFile = GetFilename(sFile.c_str());

	sFile.append(_T(".smd"));

	FILE* fp = tfopen(sFile, _T("w"));

	// SMD file format: http://developer.valvesoftware.com/wiki/SMD

	// Header section
	fprintf(fp, "version 1\n\n");

	// Nodes section
	fprintf(fp, "nodes\n");
	// Only bothering with one node, we're only doing static props with this code for now.
	fprintf(fp, "0 \"%s\" -1\n", convertstring<tchar, char>(pMesh->GetBoneName(0)).c_str());
	fprintf(fp, "end\n\n");

	// Skeleton section
	fprintf(fp, "skeleton\n");
	fprintf(fp, "time 0\n");
	fprintf(fp, "0 0.000000 0.000000 0.000000 1.570796 0.000000 0.0000001\n");
	fprintf(fp, "end\n\n");
	
	fprintf(fp, "triangles\n");
	for (size_t i = 0; i < pMesh->GetNumFaces(); i++)
	{
		CConversionFace* pFace = pMesh->GetFace(i);

		if (!pFace->GetNumVertices())
		{
			printf("WARNING! Found a face with no vertices.\n");
			continue;
		}

		CConversionVertex* pV1 = pFace->GetVertex(0);

		for (size_t j = 0; j < pFace->GetNumVertices()-2; j++)
		{
			CConversionVertex* pV2 = pFace->GetVertex(j+1);
			CConversionVertex* pV3 = pFace->GetVertex(j+2);

			Vector v1 = pMesh->GetVertex(pV1->v);
			Vector v2 = pMesh->GetVertex(pV2->v);
			Vector v3 = pMesh->GetVertex(pV3->v);

			Vector n1 = pMesh->GetNormal(pV1->vn);
			Vector n2 = pMesh->GetNormal(pV2->vn);
			Vector n3 = pMesh->GetNormal(pV3->vn);

			Vector uv1 = pMesh->GetUV(pV1->vu);
			Vector uv2 = pMesh->GetUV(pV2->vu);
			Vector uv3 = pMesh->GetUV(pV3->vu);

			// Material name
			size_t iMaterial = pFace->m;

			if (iMaterial == ((size_t)~0) || !m_pScene->GetMaterial(iMaterial))
			{
				printf("ERROR! Can't find a material for a triangle.\n");
				fprintf(fp, "error\n");
			}
			else
				fprintf(fp, "%s\n", convertstring<tchar, char>(m_pScene->GetMaterial(iMaterial)->GetName()).c_str());

			// <int|Parent bone> <float|PosX PosY PosZ> <normal|NormX NormY NormZ> <normal|U V>
			// Studio coordinates are not the same as game coordinates. Studio (x, y, z) is game (x, -z, y) and vice versa.
			fprintf(fp, "0 \t %f %f %f \t %f %f %f \t %f %f\n", v1.x, -v1.z, v1.y, n1.x, -n1.z, n1.y, uv1.x, uv1.y);
			fprintf(fp, "0 \t %f %f %f \t %f %f %f \t %f %f\n", v2.x, -v2.z, v2.y, n2.x, -n2.z, n2.y, uv2.x, uv2.y);
			fprintf(fp, "0 \t %f %f %f \t %f %f %f \t %f %f\n", v3.x, -v3.z, v3.y, n3.x, -n3.z, n3.y, uv3.x, uv3.y);
		}
	}
	fprintf(fp, "end\n");

	fclose(fp);
}
Пример #14
0
void CModelConverter::SaveDAE(const tstring& sFilename)
{
	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	FCollada::Initialize();

	FCDocument* pDoc = FCollada::NewTopDocument();

	FCDocumentTools::StandardizeUpAxisAndLength(pDoc, FMVector3(0, 1, 0));

	FCDAsset* pAsset = pDoc->GetAsset();
	FCDAssetContributor* pContributor = pAsset->AddContributor();
	pContributor->SetAuthoringTool(fstring_literal("Created by SMAK using FCollada"));

	FCDMaterialLibrary* pMatLib = pDoc->GetMaterialLibrary();

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Saving materials", m_pScene->GetNumMaterials());

	for (size_t iMaterial = 0; iMaterial < m_pScene->GetNumMaterials(); iMaterial++)
	{
		CConversionMaterial* pConversionMaterial = m_pScene->GetMaterial(iMaterial);

		FCDMaterial* pColladaMaterial = pMatLib->AddEntity();
		pColladaMaterial->SetName(convert_to_fstring(pConversionMaterial->GetName()));
		FCDEffect* pEffect = pMatLib->GetDocument()->GetEffectLibrary()->AddEntity();
		pColladaMaterial->SetEffect(pEffect);
		FCDEffectProfile* pEffectProfile = pEffect->AddProfile(FUDaeProfileType::COMMON);

		pEffect->SetName(convert_to_fstring(pConversionMaterial->GetName()));

		FCDEffectStandard* pStandardProfile = dynamic_cast<FCDEffectStandard*>(pEffectProfile);
		if (pStandardProfile)
		{
			pStandardProfile->SetLightingType(FCDEffectStandard::PHONG);
			pStandardProfile->SetAmbientColor(FMVector4(FMVector3((float*)pConversionMaterial->m_vecAmbient), 1));
			pStandardProfile->SetDiffuseColor(FMVector4(FMVector3((float*)pConversionMaterial->m_vecDiffuse), 1));
			pStandardProfile->SetSpecularColor(FMVector4(FMVector3((float*)pConversionMaterial->m_vecSpecular), 1));
			pStandardProfile->SetEmissionColor(FMVector4(FMVector3((float*)pConversionMaterial->m_vecEmissive), 1));
			pStandardProfile->SetShininess(pConversionMaterial->m_flShininess);
		}

		if (pConversionMaterial->GetDiffuseTexture().length())
		{
			FCDEffectParameter* pEffectParameterSampler = pEffectProfile->AddEffectParameter(FCDEffectParameter::SAMPLER);
			FCDEffectParameter* pEffectParameterSurface = pEffectProfile->AddEffectParameter(FCDEffectParameter::SURFACE);
			FCDEffectParameterSampler* pSampler = dynamic_cast<FCDEffectParameterSampler*>(pEffectParameterSampler);
			FCDEffectParameterSurface* pSurface = dynamic_cast<FCDEffectParameterSurface*>(pEffectParameterSurface);
			FCDImage* pSurfaceImage = pMatLib->GetDocument()->GetImageLibrary()->AddEntity();

			pSurfaceImage->SetFilename(convert_to_fstring(pConversionMaterial->GetDiffuseTexture()));

			pSurface->SetInitMethod(new FCDEffectParameterSurfaceInitFrom());
			pSurface->AddImage(pSurfaceImage);
			pSurface->SetReference((pConversionMaterial->GetName() + "-surface").c_str());

			pSampler->SetSurface(pSurface);
		}

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(iMaterial);
	}

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Saving geometry", m_pScene->GetNumMeshes());

	FCDGeometryLibrary* pGeoLib = pDoc->GetGeometryLibrary();

	for (size_t i = 0; i < m_pScene->GetNumMeshes(); ++i)
	{
		CConversionMesh* pConversionMesh = m_pScene->GetMesh(i);

		FCDGeometry* pGeometry = pGeoLib->AddEntity();
		pGeometry->SetName(convert_to_fstring(pConversionMesh->GetName()));
		pGeometry->CreateMesh();
		FCDGeometryMesh* pMesh = pGeometry->GetMesh();

		FCDGeometrySource* pPositionSource = pMesh->AddSource(FUDaeGeometryInput::POSITION);
		pPositionSource->SetName(convert_to_fstring(pConversionMesh->GetName() + "-position"));
		pPositionSource->SetStride(3);
		pPositionSource->SetValueCount(pConversionMesh->GetNumVertices());
		for (size_t j = 0; j < pConversionMesh->GetNumVertices(); j++)
			pPositionSource->SetValue(j, pConversionMesh->GetVertex(j));

		pMesh->AddVertexSource(pPositionSource);

		FCDGeometrySource* pNormalSource = pMesh->AddSource(FUDaeGeometryInput::NORMAL);
		pNormalSource->SetName(convert_to_fstring(pConversionMesh->GetName() + "-normal"));
		pNormalSource->SetStride(3);
		pNormalSource->SetValueCount(pConversionMesh->GetNumNormals());
		for (size_t j = 0; j < pConversionMesh->GetNumNormals(); j++)
			pNormalSource->SetValue(j, pConversionMesh->GetNormal(j));

		FCDGeometrySource* pUVSource = NULL;
		if (pConversionMesh->GetNumUVs())
		{
			pUVSource = pMesh->AddSource(FUDaeGeometryInput::TEXCOORD);
			pUVSource->SetName(convert_to_fstring(pConversionMesh->GetName() + "-texcoord"));
			pUVSource->SetStride(2);
			pUVSource->SetValueCount(pConversionMesh->GetNumUVs());
			for (size_t j = 0; j < pConversionMesh->GetNumUVs(); j++)
				pUVSource->SetValue(j, pConversionMesh->GetUV(j));
		}

		for (size_t iMaterials = 0; iMaterials < pConversionMesh->GetNumMaterialStubs(); iMaterials++)
		{
			CConversionMaterialStub* pStub = pConversionMesh->GetMaterialStub(iMaterials);

			FCDGeometryPolygons* pPolygons = pMesh->AddPolygons();
			pPolygons->SetMaterialSemantic(convert_to_fstring(pStub->GetName()));
			pPolygons->AddInput(pPositionSource, 0);
			pPolygons->AddInput(pNormalSource, 1);
			if (pConversionMesh->GetNumUVs())
				pPolygons->AddInput(pUVSource, 2);

			FCDGeometryPolygonsInput* pPositionInput = pPolygons->FindInput(pPositionSource);
			FCDGeometryPolygonsInput* pNormalInput = pPolygons->FindInput(pNormalSource);
			FCDGeometryPolygonsInput* pUVInput = pPolygons->FindInput(pUVSource);

			for (size_t iFace = 0; iFace < pConversionMesh->GetNumFaces(); iFace++)
			{
				CConversionFace* pFace = pConversionMesh->GetFace(iFace);

				if (pFace->m != iMaterials)
					continue;

				pPolygons->AddFaceVertexCount(pFace->GetNumVertices());
				for (size_t iVertex = 0; iVertex < pFace->GetNumVertices(); iVertex++)
				{
					pPositionInput->AddIndex(pFace->GetVertex(iVertex)->v);
					pNormalInput->AddIndex(pFace->GetVertex(iVertex)->vn);
					if (pConversionMesh->GetNumUVs())
						pUVInput->AddIndex(pFace->GetVertex(iVertex)->vu);
				}
			}
		}

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(i);
	}

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Saving scenes", m_pScene->GetNumScenes());

	FCDVisualSceneNodeLibrary* pVisualScenes = pDoc->GetVisualSceneLibrary();
	for (size_t i = 0; i < m_pScene->GetNumScenes(); ++i)
	{
		FCDSceneNode* pNode = pVisualScenes->AddEntity();

		SaveDAEScene(pNode, m_pScene->GetScene(i));

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(i);
	}

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Writing to disk...", 0);

	FCollada::SaveDocument(pDoc, convert_to_fstring(sFilename));

	pDoc->Release();

	FCollada::Release();

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
Пример #15
0
void LoadMesh(CConversionScene* pScene, size_t iMesh)
{
	TAssert(iMesh < pScene->GetNumMeshes());
	if (iMesh >= pScene->GetNumMeshes())
		return;

	// Reserve space for n+1, the last one represents the default material.
	g_aaflData.resize(pScene->GetNumMaterials()+1);

	tvector<Vector> avecPoints;
	tvector<size_t> aiPoints;

	CConversionMesh* pMesh = pScene->GetMesh(iMesh);

	for (size_t j = 0; j < pMesh->GetNumFaces(); j++)
	{
		CConversionFace* pFace = pMesh->GetFace(j);

		size_t iMaterial = pFace->m;
		if (iMaterial == ~0)
			iMaterial = pScene->GetNumMaterials();

		CConversionVertex* pVertex0 = pFace->GetVertex(0);
		CConversionVertex* pVertex1 = pFace->GetVertex(1);

		CConversionVertex* pLastVertex = pFace->GetVertex(pFace->GetNumVertices()-1);

		avecPoints.clear();
		aiPoints.clear();

		for (size_t t = 0; t < pFace->GetNumVertices(); t++)
		{
			avecPoints.push_back(pMesh->GetVertex(pFace->GetVertex(t)->v));
			aiPoints.push_back(t);
		}

		CConversionVertex* pVertex2;

		while (avecPoints.size() > 3)
		{
			size_t iEar = FindEar(avecPoints);
			size_t iLast = iEar==0?avecPoints.size()-1:iEar-1;
			size_t iNext = iEar==avecPoints.size()-1?0:iEar+1;

			pVertex0 = pFace->GetVertex(aiPoints[iLast]);
			pVertex1 = pFace->GetVertex(aiPoints[iEar]);
			pVertex2 = pFace->GetVertex(aiPoints[iNext]);

			AddVertex(iMaterial, pMesh->GetVertex(pVertex0->v), pMesh->GetUV(pVertex0->vu));
			AddVertex(iMaterial, pMesh->GetVertex(pVertex1->v), pMesh->GetUV(pVertex1->vu));
			AddVertex(iMaterial, pMesh->GetVertex(pVertex2->v), pMesh->GetUV(pVertex2->vu));

			avecPoints.erase(avecPoints.begin()+iEar);
			aiPoints.erase(aiPoints.begin()+iEar);
		}

		TAssert(aiPoints.size() == 3);
		if (aiPoints.size() != 3)
			continue;

		pVertex0 = pFace->GetVertex(aiPoints[0]);
		pVertex1 = pFace->GetVertex(aiPoints[1]);
		pVertex2 = pFace->GetVertex(aiPoints[2]);

		AddVertex(iMaterial, pMesh->GetVertex(pVertex0->v), pMesh->GetUV(pVertex0->vu));
		AddVertex(iMaterial, pMesh->GetVertex(pVertex1->v), pMesh->GetUV(pVertex1->vu));
		AddVertex(iMaterial, pMesh->GetVertex(pVertex2->v), pMesh->GetUV(pVertex2->vu));
	}
}