コード例 #1
0
ファイル: ao.cpp プロジェクト: ezhangle/SMAK
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
ファイル: toy_physics.cpp プロジェクト: BSVino/Digitanks
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
ファイル: ao.cpp プロジェクト: ezhangle/SMAK
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;
    }
}
コード例 #4
0
ファイル: ao.cpp プロジェクト: ezhangle/SMAK
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;
    }
}
コード例 #5
0
ファイル: ao.cpp プロジェクト: ezhangle/SMAK
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));
            }
        }
    }
}
コード例 #6
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));
			}
		}
	}
}
コード例 #7
0
ファイル: obj.cpp プロジェクト: dfk789/CodenameInfinite
void CModelConverter::ReadOBJ(const tstring& sFilename)
{
	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	FILE* fp = tfopen(sFilename, _T("r"));

	if (!fp)
	{
		printf("No input file. Sorry!\n");
		return;
	}

	CConversionSceneNode* pScene = m_pScene->GetScene(m_pScene->AddScene(GetFilename(sFilename).append(_T(".obj"))));

	CConversionMesh* pMesh = m_pScene->GetMesh(m_pScene->AddMesh(GetFilename(sFilename)));
	// Make sure it exists.
	CConversionSceneNode* pMeshNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh);

	size_t iCurrentMaterial = ~0;
	size_t iSmoothingGroup = ~0;

	bool bSmoothingGroups = false;

	tstring sLastTask;

	int iTotalVertices = 0;
	int iTotalFaces = 0;
	int iVerticesComplete = 0;
	int iFacesComplete = 0;

	if (m_pWorkListener)
		m_pWorkListener->SetAction(_T("Reading file into memory..."), 0);

	fseek(fp, 0L, SEEK_END);
	long iOBJSize = ftell(fp);
	fseek(fp, 0L, SEEK_SET);

	// Make sure we allocate more than we need just in case.
	size_t iFileSize = (iOBJSize+1) * (sizeof(tchar)+1);
	tchar* pszEntireFile = (tchar*)malloc(iFileSize);
	tchar* pszCurrent = pszEntireFile;
	pszCurrent[0] = _T('\0');

	// Read the entire file into an array first for faster processing.
	tstring sLine;
	while (fgetts(sLine, fp))
	{
		tstrncpy(pszCurrent, iFileSize-(pszCurrent-pszEntireFile), sLine.c_str(), sLine.length());
		size_t iLength = sLine.length();

		tchar cLastChar = pszCurrent[iLength-1];
		while (cLastChar == _T('\n') || cLastChar == _T('\r'))
		{
			pszCurrent[iLength-1] = _T('\0');
			iLength--;
			cLastChar = pszCurrent[iLength-1];
		}

		pszCurrent += iLength;
		pszCurrent++;

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

	pszCurrent[0] = _T('\0');

	fclose(fp);

	const tchar* pszLine = pszEntireFile;
	const tchar* pszNextLine = NULL;
	while (pszLine < pszCurrent)
	{
		if (pszNextLine)
			pszLine = pszNextLine;

		pszNextLine = pszLine + tstrlen(pszLine) + 1;

		// This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines.
		// Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it.
		while (*pszLine && IsWhitespace(*pszLine))
			pszLine++;

		if (tstrlen(pszLine) == 0)
			continue;

		if (pszLine[0] == '#')
		{
			// ZBrush is kind enough to notate exactly how many vertices and faces we have in the comments at the top of the file.
			if (tstrncmp(pszLine, _T("#Vertex Count"), 13) == 0)
			{
				iTotalVertices = stoi(pszLine+13);
				pMesh->SetTotalVertices(iTotalVertices);
			}

			if (tstrncmp(pszLine, _T("#Face Count"), 11) == 0)
			{
				iTotalFaces = stoi(pszLine+11);
				pMesh->SetTotalFaces(iTotalFaces);

				// Don't kill the video card while we're loading the faces.
				if (iTotalFaces > 10000)
					pMeshNode->GetMeshInstance(0)->SetVisible(false);
			}

			continue;
		}

		tchar szToken[1024];
		tstrncpy(szToken, 1024, pszLine, 1024);
		tchar* pszState = NULL;
		tchar* pszToken = strtok<tchar>(szToken, " ", &pszState);

		if (tstrncmp(pszToken, _T("mtllib"), 6) == 0)
		{
			tstring sDirectory = GetDirectory(sFilename);
			tstring sMaterial = sprintf(tstring("%s/%s"), sDirectory.c_str(), pszLine + 7);
			ReadMTL(sMaterial);
		}
		else if (tstrncmp(pszToken, _T("o"), 1) == 0)
		{
			// Dunno what this does.
		}
		else if (tstrncmp(pszToken, _T("v"), 2) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(iVerticesComplete++);
				else
				{
					m_pWorkListener->SetAction(_T("Reading vertex data"), iTotalVertices);
					sLastTask = tstring(pszToken);
				}
			}

			// A vertex.
			float v[3];
			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+1;
			int iDimension = 0;
			while (*pszToken)
			{
				while (pszToken[0] == _T(' '))
					pszToken++;

				v[iDimension++] = (float)stof(pszToken);
				if (iDimension >= 3)
					break;

				while (pszToken[0] != _T(' '))
					pszToken++;
			}
			pMesh->AddVertex(v[0], v[1], v[2]);
		}
		else if (tstrncmp(pszToken, _T("vn"), 3) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(0);
				else
					m_pWorkListener->SetAction(_T("Reading vertex normal data"), 0);
			}
			sLastTask = tstring(pszToken);

			// A vertex normal.
			float x, y, z;
			eastl::vector<tstring> asTokens;
			tstrtok(pszLine, asTokens, _T(" "));
			if (asTokens.size() == 4)
			{
				x = stof(asTokens[1]);
				y = stof(asTokens[2]);
				z = stof(asTokens[3]);
				pMesh->AddNormal(x, y, z);
			}
		}
		else if (tstrncmp(pszToken, _T("vt"), 3) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(0);
				else
					m_pWorkListener->SetAction(_T("Reading texture coordinate data"), 0);
			}
			sLastTask = tstring(pszToken);

			// A UV coordinate for a vertex.
			float u, v;
			eastl::vector<tstring> asTokens;
			tstrtok(pszLine, asTokens, _T(" "));
			if (asTokens.size() == 3)
			{
				u = stof(asTokens[1]);
				v = stof(asTokens[2]);
				pMesh->AddUV(u, v);
			}
		}
		else if (tstrncmp(pszToken, _T("g"), 1) == 0)
		{
			// A group of faces.
			pMesh->AddBone(pszLine+2);
		}
		else if (tstrncmp(pszToken, _T("usemtl"), 6) == 0)
		{
			// All following faces should use this material.
			tstring sMaterial = tstring(pszLine+7);
			size_t iMaterial = pMesh->FindMaterialStub(sMaterial);
			if (iMaterial == ((size_t)~0))
			{
				size_t iSceneMaterial = m_pScene->FindMaterial(sMaterial);
				if (iSceneMaterial == ((size_t)~0))
					iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, sMaterial);
				else
				{
					size_t iMaterialStub = pMesh->AddMaterialStub(sMaterial);
					m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh)->GetMeshInstance(0)->AddMappedMaterial(iMaterialStub, iSceneMaterial);
					iCurrentMaterial = iMaterialStub;
				}
			}
			else
				iCurrentMaterial = iMaterial;
		}
		else if (tstrncmp(pszToken, _T("s"), 1) == 0)
		{
			if (tstrncmp(pszLine, _T("s off"), 5) == 0)
			{
				iSmoothingGroup = ~0;
			}
			else
			{
				bSmoothingGroups = true;
				eastl::vector<tstring> asTokens;
				tstrtok(pszLine, asTokens, _T(" "));
				if (asTokens.size() == 2)
					iSmoothingGroup = stoi(asTokens[1]);
			}
		}
		else if (tstrncmp(pszToken, _T("f"), 1) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(iFacesComplete++);
				else
				{
					m_pWorkListener->SetAction(_T("Reading polygon data"), iTotalFaces);
					sLastTask = tstring(pszToken);
				}
			}

			if (iCurrentMaterial == ~0)
				iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, pMesh->GetName());

			// A face.
			size_t iFace = pMesh->AddFace(iCurrentMaterial);

			// If we get to 10k faces force the mesh off so it doesn't kill the video card.
			if (iFace == 10000)
				pMeshNode->GetMeshInstance(0)->SetVisible(false);

			pMesh->GetFace(iFace)->m_iSmoothingGroup = iSmoothingGroup;

			while (pszToken = strtok<tchar>(NULL, _T(" "), &pszState))
			{
				if (tstrlen(pszToken) == 0)
					continue;

				// We don't use size_t because SOME EXPORTS put out negative numbers.
				long f[3];
				bool bValues[3];
				bValues[0] = false;
				bValues[1] = false;
				bValues[2] = false;

				// scanf is pretty slow even for such a short string due to lots of mallocs.
				const tchar* pszValues = pszToken;
				int iValue = 0;
				do
				{
					if (!pszValues)
						break;

					if (!bValues[0] || pszValues[0] == _T('/'))
					{
						if (pszValues[0] == _T('/'))
							pszValues++;

						bValues[iValue] = true;
						f[iValue++] = (long)stoi(pszValues);
						if (iValue >= 3)
							break;
					}

					// Don't advance if we're on a slash, because that means empty slashes. ie, 11//12 <-- the 12 would get skipped.
					if (pszValues[0] != _T('/'))
						pszValues++;
				}
				while (*pszValues);

				if (bValues[0])
				{
					if (f[0] < 0)
						f[0] = (long)pMesh->GetNumVertices()+f[0]+1;
					TAssert ( f[0] >= 1 && f[0] < (long)pMesh->GetNumVertices()+1 );
				}

				if (bValues[1] && pMesh->GetNumUVs())
				{
					if (f[1] < 0)
						f[1] = (long)pMesh->GetNumUVs()+f[1]+1;
					TAssert ( f[1] >= 1 && f[1] < (long)pMesh->GetNumUVs()+1 );
				}

				if (bValues[2] && pMesh->GetNumNormals())
				{
					if (f[2] < 0)
						f[2] = (long)pMesh->GetNumNormals()+f[2]+1;
					TAssert ( f[2] >= 1 && f[2] < (long)pMesh->GetNumNormals()+1 );
				}

				// OBJ uses 1-based indexing.
				// Convert to 0-based indexing.
				f[0]--;
				f[1]--;
				f[2]--;

				if (!pMesh->GetNumUVs())
					f[1] = ~0;
				if (bValues[2] == false || !pMesh->GetNumNormals())
					f[2] = ~0;

				pMesh->AddVertexToFace(iFace, f[0], f[1], f[2]);
			}
		}
	}

	free(pszEntireFile);

	m_pScene->SetWorkListener(m_pWorkListener);

	m_pScene->CalculateExtends();

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

		if (bSmoothingGroups || m_pScene->GetMesh(i)->GetNumNormals() == 0)
			m_pScene->GetMesh(i)->CalculateVertexNormals();

		m_pScene->GetMesh(i)->CalculateVertexTangents();
	}

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
コード例 #8
0
ファイル: silo.cpp プロジェクト: BSVino/SMAK
const tchar* CModelConverter::ReadSIAShape(const tchar* pszLine, const tchar* pszEnd, CConversionSceneNode* pScene, bool bCare)
{
	size_t iCurrentMaterial = ~0;

	CConversionMesh* pMesh = NULL;
	CConversionSceneNode* pMeshNode = NULL;
	size_t iAddV = 0;
	size_t iAddE = 0;
	size_t iAddUV = 0;
	size_t iAddN = 0;

	tstring sLastTask;
	tstring sToken;

	const tchar* pszNextLine = NULL;
	while (pszLine < pszEnd)
	{
		if (pszNextLine)
			pszLine = pszNextLine;

		size_t iLineLength = tstrlen(pszLine);
		pszNextLine = pszLine + iLineLength + 1;

		// This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines.
		// Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it.
		while (*pszLine && IsWhitespace(*pszLine))
			pszLine++;

		if (tstrlen(pszLine) == 0)
			continue;

		const tchar* pszToken = pszLine;

		while (*pszToken && *pszToken != ' ')
			pszToken++;

		sToken.reserve(iLineLength);
		sToken.clear();
		sToken.append(pszLine, pszToken-pszLine);
		pszToken = sToken.c_str();

		if (!bCare)
		{
			if (tstrncmp(pszToken, "-endShape", 9) == 0)
				return pszNextLine;
			else
				continue;
		}

		if (tstrncmp(pszToken, "-snam", 5) == 0)
		{
			// We name our mesh.
			tstring sName =pszLine+6;
			tvector<tstring> aName;
			tstrtok(sName, aName, "\"");	// Strip out the quotation marks.

			if (bCare)
			{
				size_t iMesh = m_pScene->FindMesh(aName[0].c_str());
				if (iMesh == (size_t)~0)
				{
					iMesh = m_pScene->AddMesh(aName[0].c_str());
					pMesh = m_pScene->GetMesh(iMesh);
					pMesh->AddBone(aName[0].c_str());
				}
				else
				{
					pMesh = m_pScene->GetMesh(iMesh);
					iAddV = pMesh->GetNumVertices();
					iAddE = pMesh->GetNumEdges();
					iAddUV = pMesh->GetNumUVs();
					iAddN = pMesh->GetNumNormals();
				}
				// Make sure it exists.
				pMeshNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh);
			}
		}
		else if (tstrncmp(pszToken, "-vert", 5) == 0)
		{
			if (m_pWorkListener)
			{
				if (sLastTask == pszToken)
					m_pWorkListener->WorkProgress(0);
				else
				{
					m_pWorkListener->SetAction("Reading vertex data", 0);
					sLastTask = tstring(pszToken);
				}
			}

			// A vertex.
			float v[3];
			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+5;
			int iDimension = 0;
			while (*pszToken)
			{
				while (pszToken[0] == ' ')
					pszToken++;

				v[iDimension++] = (float)stof(pszToken);
				if (iDimension >= 3)
					break;

				while (pszToken[0] != ' ')
					pszToken++;
			}
			pMesh->AddVertex(v[0], v[1], v[2]);
		}
		else if (tstrncmp(pszToken, "-edge", 5) == 0)
		{
			if (m_pWorkListener)
			{
				if (sLastTask == pszToken)
					m_pWorkListener->WorkProgress(0);
				else
				{
					m_pWorkListener->SetAction("Reading edge data", 0);
					sLastTask = tstring(pszToken);
				}
			}

			// An edge. We only need them so we can tell where the creases are, so we can calculate normals properly.
			int e[2];
			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+5;
			int iDimension = 0;
			while (*pszToken)
			{
				while (pszToken[0] == ' ')
					pszToken++;

				e[iDimension++] = (int)stoi(pszToken);
				if (iDimension >= 2)
					break;

				while (pszToken[0] != ' ')
					pszToken++;
			}
			pMesh->AddEdge(e[0]+iAddV, e[1]+iAddV);
		}
		else if (tstrncmp(pszToken, "-creas", 6) == 0)
		{
			// An edge. We only need them so we can tell where the creases are, so we can calculate normals properly.
			tstring sCreases = pszLine+7;
			tvector<tstring> aCreases;
			tstrtok(sCreases, aCreases, " ");

			size_t iCreases = aCreases.size();
			// The first one is the number of creases, skip it
			for (size_t i = 1; i < iCreases; i++)
			{
				int iEdge = stoi(aCreases[i].c_str());
				pMesh->GetEdge(iEdge+iAddE)->m_bCreased = true;
			}
		}
		else if (tstrncmp(pszToken, "-setmat", 7) == 0)
		{
			const tchar* pszMaterial = pszLine+8;
			size_t iNewMaterial = stoi(pszMaterial);

			if (iNewMaterial == (size_t)(-1))
				iCurrentMaterial = ~0;
			else
			{
				CConversionMaterial* pMaterial = m_pScene->GetMaterial(iNewMaterial);
				if (pMaterial)
				{
					iCurrentMaterial = pMesh->FindMaterialStub(pMaterial->GetName());
					if (iCurrentMaterial == (size_t)~0)
					{
						size_t iMaterialStub = pMesh->AddMaterialStub(pMaterial->GetName());
						m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh)->GetMeshInstance(0)->AddMappedMaterial(iMaterialStub, iNewMaterial);
						iCurrentMaterial = iMaterialStub;
					}
				}
				else
					iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, pMesh->GetName());
			}
		}
		else if (tstrncmp(pszToken, "-face", 5) == 0)
		{
			if (m_pWorkListener)
			{
				if (sLastTask == pszToken)
					m_pWorkListener->WorkProgress(0);
				else
				{
					m_pWorkListener->SetAction("Reading polygon data", 0);
					sLastTask = tstring(pszToken);
				}
			}

			// A face.
			size_t iFace = pMesh->AddFace(iCurrentMaterial);

			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+6;

			size_t iVerts = stoi(pszToken);

			while (pszToken[0] != ' ')
				pszToken++;

			size_t iProcessed = 0;
			while (iProcessed++ < iVerts)
			{
				size_t iVertex = stoi(++pszToken)+iAddV;

				while (pszToken[0] != ' ')
					pszToken++;

				size_t iEdge = stoi(++pszToken)+iAddE;

				while (pszToken[0] != ' ')
					pszToken++;

				float flU = (float)stof(++pszToken);

				while (pszToken[0] != ' ')
					pszToken++;

				float flV = (float)stof(++pszToken);

				size_t iUV = pMesh->AddUV(flU, flV);

				size_t iNormal = pMesh->AddNormal(0, 0, 1);	// For now!

				pMesh->AddVertexToFace(iFace, iVertex, iUV, iNormal);
				pMesh->AddEdgeToFace(iFace, iEdge);

				while (pszToken[0] != '\0' && pszToken[0] != ' ')
					pszToken++;
			}
		}
		else if (tstrncmp(pszToken, "-axis", 5) == 0)
		{
			// Object's transformations. Format is translation x y z, forward base vector x y z, then up vector and right vector.
			// Y is up.
			Matrix4x4 m;
			sscanf(pszLine, "-axis %f %f %f %f %f %f %f %f %f %f %f %f",
				&m.m[3][0], &m.m[3][1], &m.m[3][2],
				&m.m[0][0], &m.m[0][1], &m.m[0][2],
				&m.m[1][0], &m.m[1][1], &m.m[1][2],
				&m.m[2][0], &m.m[2][1], &m.m[2][2]);

			Matrix4x4 mGlobalToLocal = m.InvertedRT();

			// Unfortunately Silo stores all vertex data in global coordinates so we need to move them to the local frame first.
			size_t iVerts = pMesh->GetNumVertices();
			for (size_t i = 0; i < iVerts; i++)
				pMesh->m_aVertices[i] = mGlobalToLocal * pMesh->m_aVertices[i];

			pMeshNode->m_mTransformations = m;
		}
		else if (tstrncmp(pszToken, "-endShape", 9) == 0)
		{
			break;
		}
	}

	return pszNextLine;
}
コード例 #9
0
ファイル: crunch.cpp プロジェクト: BSVino/SMAK
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();
}
コード例 #10
0
ファイル: obj.cpp プロジェクト: dfk789/CodenameInfinite
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();
}
コード例 #11
0
ファイル: crunch.cpp プロジェクト: BSVino/SMAK
void CTexelGenerator::GenerateTriangleByTexel(CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, size_t v1, size_t v2, size_t v3, raytrace::CRaytracer* pTracer, size_t& iRendered)
{
	texel_data_t oJob;

	CConversionVertex* pV1 = pFace->GetVertex(v1);
	CConversionVertex* pV2 = pFace->GetVertex(v2);
	CConversionVertex* pV3 = pFace->GetVertex(v3);

	CConversionMesh* pMesh = pMeshInstance->GetMesh();

	oJob.pMeshInstance = pMeshInstance;
	oJob.pFace = pFace;
	oJob.pV1 = pV1;
	oJob.pV2 = pV2;
	oJob.pV3 = pV3;
	oJob.pTracer = pTracer;
	oJob.pGenerator = this;

	Vector vu1 = pMesh->GetUV(pV1->vu);
	Vector vu2 = pMesh->GetUV(pV2->vu);
	Vector vu3 = pMesh->GetUV(pV3->vu);

	Vector vecLoUV = vu1;
	Vector vecHiUV = vu1;

	if (vu2.x < vecLoUV.x)
		vecLoUV.x = vu2.x;
	if (vu3.x < vecLoUV.x)
		vecLoUV.x = vu3.x;
	if (vu2.x > vecHiUV.x)
		vecHiUV.x = vu2.x;
	if (vu3.x > vecHiUV.x)
		vecHiUV.x = vu3.x;

	if (vu2.y < vecLoUV.y)
		vecLoUV.y = vu2.y;
	if (vu3.y < vecLoUV.y)
		vecLoUV.y = vu3.y;
	if (vu2.y > vecHiUV.y)
		vecHiUV.y = vu2.y;
	if (vu3.y > vecHiUV.y)
		vecHiUV.y = vu3.y;

	size_t iLoX = (size_t)(vecLoUV.x * m_iWidth);
	size_t iLoY = (size_t)(vecLoUV.y * m_iHeight);
	size_t iHiX = (size_t)(vecHiUV.x * m_iWidth);
	size_t iHiY = (size_t)(vecHiUV.y * m_iHeight);

	for (size_t i = iLoX; i <= iHiX; i++)
	{
		for (size_t j = iLoY; j <= iHiY; j++)
		{
			oJob.x = i;
			oJob.y = j;

			m_pWorkParallelizer->AddJob(&oJob, sizeof(oJob));

			if (m_pWorkListener)
				m_pWorkListener->WorkProgress(++iRendered);

			if (m_bStopGenerating)
				break;
		}
		if (m_bStopGenerating)
			break;
	}
}
コード例 #12
0
ファイル: crunch.cpp プロジェクト: BSVino/SMAK
void CTexelGenerator::FindHiResMeshLocation(CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, CConversionVertex* pV1, CConversionVertex* pV2, CConversionVertex* pV3, size_t i, size_t j, raytrace::CRaytracer* pTracer)
{
	CConversionMesh* pMesh = pMeshInstance->GetMesh();

	Vector vu1 = pMesh->GetUV(pV1->vu);
	Vector vu2 = pMesh->GetUV(pV2->vu);
	Vector vu3 = pMesh->GetUV(pV3->vu);

	float flU = ((float)i + 0.5f)/(float)m_iWidth;
	float flV = ((float)j + 0.5f)/(float)m_iHeight;

	bool bInside = PointInTriangle(Vector(flU,flV,0), vu1, vu2, vu3);

	if (!bInside)
		return;

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

	// Find where the UV is in world space.

	// First build 2x2 a "matrix" of the UV values.
	float mta = vu2.x - vu1.x;
	float mtb = vu3.x - vu1.x;
	float mtc = vu2.y - vu1.y;
	float mtd = vu3.y - vu1.y;

	// Invert it.
	float d = mta*mtd - mtb*mtc;
	float mtia =  mtd / d;
	float mtib = -mtb / d;
	float mtic = -mtc / d;
	float mtid =  mta / d;

	// Now build a 2x3 "matrix" of the vertices.
	float mva = v2.x - v1.x;
	float mvb = v3.x - v1.x;
	float mvc = v2.y - v1.y;
	float mvd = v3.y - v1.y;
	float mve = v2.z - v1.z;
	float mvf = v3.z - v1.z;

	// Multiply them together.
	// [a b]   [a b]   [a b]
	// [c d] * [c d] = [c d]
	// [e f]           [e f]
	// Really wish I had a matrix math library about now!
	float mra = mva*mtia + mvb*mtic;
	float mrb = mva*mtib + mvb*mtid;
	float mrc = mvc*mtia + mvd*mtic;
	float mrd = mvc*mtib + mvd*mtid;
	float mre = mve*mtia + mvf*mtic;
	float mrf = mve*mtib + mvf*mtid;

	// These vectors should be the U and V axis in world space.
	Vector vecUAxis(mra, mrc, mre);
	Vector vecVAxis(mrb, mrd, mrf);

	Vector vecUVOrigin = v1 - vecUAxis * vu1.x - vecVAxis * vu1.y;

	Vector vecUVPosition = vecUVOrigin + vecUAxis * flU + vecVAxis * flV;

	Vector vecNormal = pFace->GetNormal(vecUVPosition, pMeshInstance);

	size_t iTexel;
	Texel(i, j, iTexel, false);

	// Maybe use a closest-poly check here to eliminate the need for some raytracing?

	raytrace::CTraceResult trFront;
	bool bHitFront = pTracer->Raytrace(Ray(vecUVPosition, vecNormal), &trFront);

	raytrace::CTraceResult trBack;
	bool bHitBack = pTracer->Raytrace(Ray(vecUVPosition, -vecNormal), &trBack);

#ifdef NORMAL_DEBUG
	GetParallelizer()->LockData();
	if (bHitFront && (vecUVPosition - trFront.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(vecUVPosition, trFront.m_vecHit);
	if (bHitBack && (vecUVPosition - trBack.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(vecUVPosition, trBack.m_vecHit);
	GetParallelizer()->UnlockData();
#endif

	if (!bHitBack && !bHitFront)
		return;

	raytrace::CTraceResult* trFinal;

	if (bHitFront && !bHitBack)
		trFinal = &trFront;
	else if (bHitBack && !bHitFront)
		trFinal = &trBack;
	else
	{
		float flHitFront = (vecUVPosition - trFront.m_vecHit).LengthSqr();
		float flHitBack = (vecUVPosition - trBack.m_vecHit).LengthSqr();

		if (flHitFront < flHitBack)
			trFinal = &trFront;
		else
			trFinal = &trBack;
	}

#ifdef NORMAL_DEBUG
	GetParallelizer()->LockData();
//	SMAKWindow()->AddDebugLine(vecUVPosition, vecUVPosition+vecHitNormal);
	if (bHitFront && (vecUVPosition - trFront.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(trFront.m_vecHit, trFront.m_vecHit + trFront.m_pFace->GetNormal(trFront.m_vecHit, trFront.m_pMeshInstance));
	if (bHitBack && (vecUVPosition - trBack.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(trBack.m_vecHit, trBack.m_vecHit + trBack.m_pFace->GetNormal(trBack.m_vecHit, trBack.m_pMeshInstance));
	GetParallelizer()->UnlockData();
#endif

	for (size_t i = 0; i < m_apMethods.size(); i++)
	{
		m_apMethods[i]->GenerateTexel(iTexel, pMeshInstance, pFace, pV1, pV2, pV3, trFinal, vecUVPosition, pTracer);
	}
}
コード例 #13
0
ファイル: ao.cpp プロジェクト: ezhangle/SMAK
void CAOGenerator::GenerateTriangleByTexel(CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, size_t v1, size_t v2, size_t v3, raytrace::CRaytracer* pTracer, size_t& iRendered)
{
    CConversionVertex* pV1 = pFace->GetVertex(v1);
    CConversionVertex* pV2 = pFace->GetVertex(v2);
    CConversionVertex* pV3 = pFace->GetVertex(v3);

    CConversionMesh* pMesh = pMeshInstance->GetMesh();

    Vector vu1 = pMesh->GetUV(pV1->vu);
    Vector vu2 = pMesh->GetUV(pV2->vu);
    Vector vu3 = pMesh->GetUV(pV3->vu);

    Vector vecLoUV = vu1;
    Vector vecHiUV = vu1;

    if (vu2.x < vecLoUV.x)
        vecLoUV.x = vu2.x;
    if (vu3.x < vecLoUV.x)
        vecLoUV.x = vu3.x;
    if (vu2.x > vecHiUV.x)
        vecHiUV.x = vu2.x;
    if (vu3.x > vecHiUV.x)
        vecHiUV.x = vu3.x;

    if (vu2.y < vecLoUV.y)
        vecLoUV.y = vu2.y;
    if (vu3.y < vecLoUV.y)
        vecLoUV.y = vu3.y;
    if (vu2.y > vecHiUV.y)
        vecHiUV.y = vu2.y;
    if (vu3.y > vecHiUV.y)
        vecHiUV.y = vu3.y;

    size_t iLoX = (size_t)(vecLoUV.x * m_iWidth);
    size_t iLoY = (size_t)(vecLoUV.y * m_iHeight);
    size_t iHiX = (size_t)(vecHiUV.x * m_iWidth);
    size_t iHiY = (size_t)(vecHiUV.y * m_iHeight);

    for (size_t i = iLoX; i <= iHiX; i++)
    {
        for (size_t j = iLoY; j <= iHiY; j++)
        {
            float flU = ((float)i + 0.5f)/(float)m_iWidth;
            float flV = ((float)j + 0.5f)/(float)m_iHeight;

            bool bInside = PointInTriangle(Vector(flU,flV,0), vu1, vu2, vu3);

            if (!bInside)
                continue;

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

            Vector vn1 = pMeshInstance->GetNormal(pV1->vn);
            Vector vn2 = pMeshInstance->GetNormal(pV2->vn);
            Vector vn3 = pMeshInstance->GetNormal(pV3->vn);

            // Find where the UV is in world space.

            // First build 2x2 a "matrix" of the UV values.
            float mta = vu2.x - vu1.x;
            float mtb = vu3.x - vu1.x;
            float mtc = vu2.y - vu1.y;
            float mtd = vu3.y - vu1.y;

            // Invert it.
            float d = mta*mtd - mtb*mtc;
            float mtia =  mtd / d;
            float mtib = -mtb / d;
            float mtic = -mtc / d;
            float mtid =  mta / d;

            // Now build a 2x3 "matrix" of the vertices.
            float mva = v2.x - v1.x;
            float mvb = v3.x - v1.x;
            float mvc = v2.y - v1.y;
            float mvd = v3.y - v1.y;
            float mve = v2.z - v1.z;
            float mvf = v3.z - v1.z;

            // Multiply them together.
            // [a b]   [a b]   [a b]
            // [c d] * [c d] = [c d]
            // [e f]           [e f]
            // Really wish I had a matrix math library about now!
            float mra = mva*mtia + mvb*mtic;
            float mrb = mva*mtib + mvb*mtid;
            float mrc = mvc*mtia + mvd*mtic;
            float mrd = mvc*mtib + mvd*mtid;
            float mre = mve*mtia + mvf*mtic;
            float mrf = mve*mtib + mvf*mtid;

            // These vectors should be the U and V axis in world space.
            Vector vecUAxis(mra, mrc, mre);
            Vector vecVAxis(mrb, mrd, mrf);

            Vector vecUVOrigin = v1 - vecUAxis * vu1.x - vecVAxis * vu1.y;

            Vector vecUVPosition = vecUVOrigin + vecUAxis * flU + vecVAxis * flV;

            Vector vecNormal;

            if (m_bCreaseEdges)
                vecNormal = pFace->GetNormal();
            else
            {
                float wv1 = DistanceToLine(vecUVPosition, v2, v3) / DistanceToLine(v1, v2, v3);
                float wv2 = DistanceToLine(vecUVPosition, v1, v3) / DistanceToLine(v2, v1, v3);
                float wv3 = DistanceToLine(vecUVPosition, v1, v2) / DistanceToLine(v3, v1, v2);

                vecNormal = vn1 * wv1 + vn2 * wv2 + vn3 * wv3;
            }

            if (ao_debug.GetInt() > 1)
                SMAKWindow()->AddDebugLine(vecUVPosition, vecUVPosition + vecNormal/2);

            size_t iTexel;
            if (!Texel(i, j, iTexel, false))
                continue;

            if (m_eAOMethod == AOMETHOD_RENDER)
            {
                // Render the scene from this location
                m_avecShadowValues[iTexel] += RenderSceneFromPosition(vecUVPosition, vecNormal, pFace);
            }
            else if (m_eAOMethod == AOMETHOD_RAYTRACE)
            {
                RaytraceSceneMultithreaded(pTracer, vecUVPosition, vecNormal, pMeshInstance, pFace, iTexel);
            }

            m_aiShadowReads[iTexel]++;
            m_bPixelMask[iTexel] = true;

            m_pWorkListener->WorkProgress(++iRendered);

            if (m_bStopGenerating)
                break;
        }
        if (m_bStopGenerating)
            break;
    }
}
コード例 #14
0
ファイル: loadsource.cpp プロジェクト: BSVino/Digitanks
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));
	}
}
コード例 #15
0
ファイル: silo.cpp プロジェクト: dfk789/CodenameInfinite
const tchar* CModelConverter::ReadSIAShape(const tchar* pszLine, const tchar* pszEnd, CConversionSceneNode* pScene, bool bCare)
{
	size_t iCurrentMaterial = ~0;

	CConversionMesh* pMesh = NULL;
	CConversionSceneNode* pMeshNode = NULL;
	size_t iAddV = 0;
	size_t iAddE = 0;
	size_t iAddUV = 0;
	size_t iAddN = 0;

	tstring sLastTask;
	tstring sToken;

	const tchar* pszNextLine = NULL;
	while (pszLine < pszEnd)
	{
		if (pszNextLine)
			pszLine = pszNextLine;

		size_t iLineLength = tstrlen(pszLine);
		pszNextLine = pszLine + iLineLength + 1;

		// This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines.
		// Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it.
		while (*pszLine && IsWhitespace(*pszLine))
			pszLine++;

		if (tstrlen(pszLine) == 0)
			continue;

		const tchar* pszToken = pszLine;

		while (*pszToken && *pszToken != _T(' '))
			pszToken++;

		sToken.reserve(iLineLength);
		sToken.clear();
		sToken.append(pszLine, pszToken-pszLine);
		sToken[pszToken-pszLine] = _T('\0');
		pszToken = sToken.c_str();

		if (!bCare)
		{
			if (tstrncmp(pszToken, _T("-endShape"), 9) == 0)
				return pszNextLine;
			else
				continue;
		}

		if (tstrncmp(pszToken, _T("-snam"), 5) == 0)
		{
			// We name our mesh.
			tstring sName =pszLine+6;
			eastl::vector<tstring> aName;
			tstrtok(sName, aName, _T("\""));	// Strip out the quotation marks.

			if (bCare)
			{
				size_t iMesh = m_pScene->FindMesh(aName[0].c_str());
				if (iMesh == (size_t)~0)
				{
					iMesh = m_pScene->AddMesh(aName[0].c_str());
					pMesh = m_pScene->GetMesh(iMesh);
					pMesh->AddBone(aName[0].c_str());
				}
				else
				{
					pMesh = m_pScene->GetMesh(iMesh);
					iAddV = pMesh->GetNumVertices();
					iAddE = pMesh->GetNumEdges();
					iAddUV = pMesh->GetNumUVs();
					iAddN = pMesh->GetNumNormals();
				}
				// Make sure it exists.
				pMeshNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh);
			}
		}
		else if (tstrncmp(pszToken, _T("-vert"), 5) == 0)
		{
			if (m_pWorkListener)
			{
				if (sLastTask == pszToken)
					m_pWorkListener->WorkProgress(0);
				else
				{
					m_pWorkListener->SetAction(_T("Reading vertex data"), 0);
					sLastTask = tstring(pszToken);
				}
			}

			// A vertex.
			float v[3];
			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+5;
			int iDimension = 0;
			while (*pszToken)
			{
				while (pszToken[0] == _T(' '))
					pszToken++;

				v[iDimension++] = (float)stof(pszToken);
				if (iDimension >= 3)
					break;

				while (pszToken[0] != _T(' '))
					pszToken++;
			}
			pMesh->AddVertex(v[0], v[1], v[2]);
		}
		else if (tstrncmp(pszToken, _T("-edge"), 5) == 0)
		{
			if (m_pWorkListener)
			{
				if (sLastTask == pszToken)
					m_pWorkListener->WorkProgress(0);
				else
				{
					m_pWorkListener->SetAction(_T("Reading edge data"), 0);
					sLastTask = tstring(pszToken);
				}
			}

			// An edge. We only need them so we can tell where the creases are, so we can calculate normals properly.
			int e[2];
			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+5;
			int iDimension = 0;
			while (*pszToken)
			{
				while (pszToken[0] == _T(' '))
					pszToken++;

				e[iDimension++] = (int)stoi(pszToken);
				if (iDimension >= 2)
					break;

				while (pszToken[0] != _T(' '))
					pszToken++;
			}
			pMesh->AddEdge(e[0]+iAddV, e[1]+iAddV);
		}
		else if (tstrncmp(pszToken, _T("-creas"), 6) == 0)
		{
			// An edge. We only need them so we can tell where the creases are, so we can calculate normals properly.
			tstring sCreases = pszLine+7;
			eastl::vector<tstring> aCreases;
			tstrtok(sCreases, aCreases, _T(" "));

			size_t iCreases = aCreases.size();
			// The first one is the number of creases, skip it
			for (size_t i = 1; i < iCreases; i++)
			{
				int iEdge = stoi(aCreases[i].c_str());
				pMesh->GetEdge(iEdge+iAddE)->m_bCreased = true;
			}
		}
		else if (tstrncmp(pszToken, _T("-setmat"), 7) == 0)
		{
			const tchar* pszMaterial = pszLine+8;
			size_t iNewMaterial = stoi(pszMaterial);

			if (iNewMaterial == (size_t)(-1))
				iCurrentMaterial = ~0;
			else
			{
				CConversionMaterial* pMaterial = m_pScene->GetMaterial(iNewMaterial);
				if (pMaterial)
				{
					iCurrentMaterial = pMesh->FindMaterialStub(pMaterial->GetName());
					if (iCurrentMaterial == (size_t)~0)
					{
						size_t iMaterialStub = pMesh->AddMaterialStub(pMaterial->GetName());
						m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh)->GetMeshInstance(0)->AddMappedMaterial(iMaterialStub, iNewMaterial);
						iCurrentMaterial = iMaterialStub;
					}
				}
				else
					iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, pMesh->GetName());
			}
		}
		else if (tstrncmp(pszToken, _T("-face"), 5) == 0)
		{
			if (m_pWorkListener)
			{
				if (sLastTask == pszToken)
					m_pWorkListener->WorkProgress(0);
				else
				{
					m_pWorkListener->SetAction(_T("Reading polygon data"), 0);
					sLastTask = tstring(pszToken);
				}
			}

			// A face.
			size_t iFace = pMesh->AddFace(iCurrentMaterial);

			if (iFace == 10000)
				pMeshNode->GetMeshInstance(0)->SetVisible(false);

			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+6;

			size_t iVerts = stoi(pszToken);

			while (pszToken[0] != _T(' '))
				pszToken++;

			size_t iProcessed = 0;
			while (iProcessed++ < iVerts)
			{
				size_t iVertex = stoi(++pszToken)+iAddV;

				while (pszToken[0] != _T(' '))
					pszToken++;

				size_t iEdge = stoi(++pszToken)+iAddE;

				while (pszToken[0] != _T(' '))
					pszToken++;

				float flU = (float)stof(++pszToken);

				while (pszToken[0] != _T(' '))
					pszToken++;

				float flV = (float)stof(++pszToken);

				size_t iUV = pMesh->AddUV(flU, flV);

				size_t iNormal = pMesh->AddNormal(0, 0, 1);	// For now!

				pMesh->AddVertexToFace(iFace, iVertex, iUV, iNormal);
				pMesh->AddEdgeToFace(iFace, iEdge);

				while (pszToken[0] != _T('\0') && pszToken[0] != _T(' '))
					pszToken++;
			}
		}
		else if (tstrncmp(pszToken, _T("-axis"), 5) == 0)
		{
			// This is the manipulator position and angles. The code below is untested and probably has the elements in the wrong
			// order. We don't support writing yet so no need to load it so I'm not bothering with it now.
		/*	Matrix4x4& m = pMeshNode->m_mManipulator;
			swscanf(sLine.c_str(), _T("-axis %f %f %f %f %f %f %f %f %f"),
				&m.m[0][3], &m.m[1][3], &m.m[2][3],
				&m.m[0][0], &m.m[0][1], &m.m[0][2],	// ?
				&m.m[1][0], &m.m[1][1], &m.m[1][2], // ?
				&m.m[2][0], &m.m[2][1], &m.m[2][2]  // ?
				);*/
		}
		else if (tstrncmp(pszToken, _T("-endShape"), 9) == 0)
		{
			break;
		}
	}

	return pszNextLine;
}
コード例 #16
0
ファイル: collada.cpp プロジェクト: BSVino/Digitanks
bool CModelConverter::ReadDAE(const tstring& sFilename)
{
	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	FCollada::Initialize();

	FCDocument* pDoc = FCollada::NewTopDocument();

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Reading file", 0);

	if (FCollada::LoadDocumentFromFile(pDoc, convert_to_fstring(sFilename)))
	{
		size_t i;

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

		FCDMaterialLibrary* pMatLib = pDoc->GetMaterialLibrary();
		size_t iEntities = pMatLib->GetEntityCount();

		if (m_pWorkListener)
			m_pWorkListener->SetAction("Reading materials", iEntities);

		for (i = 0; i < iEntities; ++i)
		{
			FCDMaterial* pColladaMaterial = pMatLib->GetEntity(i);
			FCDEffect* pEffect = pColladaMaterial->GetEffect();

			size_t iMaterial = m_pScene->AddMaterial(convert_from_fstring(pColladaMaterial->GetName()));
			CConversionMaterial* pMaterial = m_pScene->GetMaterial(iMaterial);

			if (pEffect->GetProfileCount() < 1)
				continue;

			FCDEffectProfile* pEffectProfile = pEffect->GetProfile(0);

			FUDaeProfileType::Type eProfileType = pEffectProfile->GetType();
			if (eProfileType == FUDaeProfileType::COMMON)
			{
				FCDEffectStandard* pStandardProfile = dynamic_cast<FCDEffectStandard*>(pEffectProfile);
				if (pStandardProfile)
				{
					pMaterial->m_vecAmbient = Vector((float*)pStandardProfile->GetAmbientColor());
					pMaterial->m_vecDiffuse = Vector((float*)pStandardProfile->GetDiffuseColor());
					pMaterial->m_vecSpecular = Vector((float*)pStandardProfile->GetSpecularColor());
					pMaterial->m_vecEmissive = Vector((float*)pStandardProfile->GetEmissionColor());
					pMaterial->m_flShininess = pStandardProfile->GetShininess();
				}
			}

			for (size_t j = 0; j < pEffectProfile->GetEffectParameterCount(); j++)
			{
				FCDEffectParameter* pEffectParameter = pEffectProfile->GetEffectParameter(j);

				FCDEffectParameter::Type eType = pEffectParameter->GetType();

				if (eType == FCDEffectParameter::SAMPLER)
				{
					FCDEffectParameterSampler* pSampler = dynamic_cast<FCDEffectParameterSampler*>(pEffectParameter);
					if (pSampler)
					{
						FCDEffectParameterSurface* pSurface = pSampler->GetSurface();
						if (pSurface)
						{
							if (pSurface->GetImageCount())
							{
								// Christ Collada why do you have to make things so damn complicated?
								FCDImage* pImage = pSurface->GetImage(0);

								pMaterial->m_sDiffuseTexture = convert_from_fstring(pImage->GetFilename());

								// Fix up a bug in the Max Collada exporter
								if (pMaterial->m_sDiffuseTexture.startswith("\\\\C\\"))
									pMaterial->m_sDiffuseTexture = "C:\\" + pMaterial->m_sDiffuseTexture.substr(4);
								else if (pMaterial->m_sDiffuseTexture.startswith("\\\\D\\"))
									pMaterial->m_sDiffuseTexture = "D:\\" + pMaterial->m_sDiffuseTexture.substr(4);
							}
						}
					}
				}
			}

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

		FCDGeometryLibrary* pGeoLib = pDoc->GetGeometryLibrary();
		iEntities = pGeoLib->GetEntityCount();

		if (m_pWorkListener)
			m_pWorkListener->SetAction("Loading entities", iEntities);

		for (i = 0; i < iEntities; ++i)
		{
			FCDGeometry* pGeometry = pGeoLib->GetEntity(i);
			if (pGeometry->IsMesh())
			{
				size_t j;

				size_t iMesh = m_pScene->AddMesh(convert_from_fstring(pGeometry->GetName()));
				CConversionMesh* pMesh = m_pScene->GetMesh(iMesh);
				pMesh->AddBone(convert_from_fstring(pGeometry->GetName()));

				FCDGeometryMesh* pGeoMesh = pGeometry->GetMesh();
				FCDGeometrySource* pPositionSource = pGeoMesh->GetPositionSource();
				size_t iVertexCount = pPositionSource->GetValueCount();

				for (j = 0; j < iVertexCount; j++)
				{
					const float* pflValues = pPositionSource->GetValue(j);
					pMesh->AddVertex(pflValues[0], pflValues[1], pflValues[2]);
				}

				FCDGeometrySource* pNormalSource = pGeoMesh->FindSourceByType(FUDaeGeometryInput::NORMAL);
				if (pNormalSource)
				{
					iVertexCount = pNormalSource->GetValueCount();
					for (j = 0; j < iVertexCount; j++)
					{
						const float* pflValues = pNormalSource->GetValue(j);
						pMesh->AddNormal(pflValues[0], pflValues[1], pflValues[2]);
					}
				}

				FCDGeometrySource* pUVSource = pGeoMesh->FindSourceByType(FUDaeGeometryInput::TEXCOORD);
				if (pUVSource)
				{
					iVertexCount = pUVSource->GetValueCount();
					for (j = 0; j < iVertexCount; j++)
					{
						const float* pflValues = pUVSource->GetValue(j);
						pMesh->AddUV(pflValues[0], pflValues[1]);
					}
				}

				for (j = 0; j < pGeoMesh->GetPolygonsCount(); j++)
				{
					FCDGeometryPolygons* pPolygons = pGeoMesh->GetPolygons(j);
					FCDGeometryPolygonsInput* pPositionInput = pPolygons->FindInput(FUDaeGeometryInput::POSITION);
					FCDGeometryPolygonsInput* pNormalInput = pPolygons->FindInput(FUDaeGeometryInput::NORMAL);
					FCDGeometryPolygonsInput* pUVInput = pPolygons->FindInput(FUDaeGeometryInput::TEXCOORD);

					size_t iPositionCount = pPositionInput->GetIndexCount();
					uint32* pPositions = pPositionInput->GetIndices();

					size_t iNormalCount = 0;
					uint32* pNormals = NULL;

					if (pNormalInput)
					{
						iNormalCount = pNormalInput->GetIndexCount();
						pNormals = pNormalInput->GetIndices();
					}

					size_t iUVCount = 0;
					uint32* pUVs = NULL;

					if (pUVInput)
					{
						iUVCount = pUVInput->GetIndexCount();
						pUVs = pUVInput->GetIndices();
					}

					fm::stringT<fchar> sMaterial = pPolygons->GetMaterialSemantic();

					size_t iCurrentMaterial = pMesh->AddMaterialStub(convert_from_fstring(sMaterial));

					if (pPolygons->TestPolyType() == 3)
					{
						// All triangles!
						for (size_t k = 0; k < iPositionCount; k+=3)
						{
							size_t iFace = pMesh->AddFace(iCurrentMaterial);

							pMesh->AddVertexToFace(iFace, pPositions[k+0], pUVs?pUVs[k+0]:~0, pNormals?pNormals[k+0]:~0);
							pMesh->AddVertexToFace(iFace, pPositions[k+1], pUVs?pUVs[k+1]:~0, pNormals?pNormals[k+1]:~0);
							pMesh->AddVertexToFace(iFace, pPositions[k+2], pUVs?pUVs[k+2]:~0, pNormals?pNormals[k+2]:~0);
						}
					}
					else if (pPolygons->TestPolyType() == 4)
					{
						// All quads!
						for (size_t k = 0; k < iPositionCount; k+=4)
						{
							size_t iFace = pMesh->AddFace(iCurrentMaterial);

							pMesh->AddVertexToFace(iFace, pPositions[k+0], pUVs?pUVs[k+0]:~0, pNormals?pNormals[k+0]:~0);
							pMesh->AddVertexToFace(iFace, pPositions[k+1], pUVs?pUVs[k+1]:~0, pNormals?pNormals[k+1]:~0);
							pMesh->AddVertexToFace(iFace, pPositions[k+2], pUVs?pUVs[k+2]:~0, pNormals?pNormals[k+2]:~0);
							pMesh->AddVertexToFace(iFace, pPositions[k+3], pUVs?pUVs[k+3]:~0, pNormals?pNormals[k+3]:~0);
						}
					}
					else
					{
						size_t iFaces = pPolygons->GetFaceCount();
						for (size_t k = 0; k < iFaces; k++)
						{
							size_t iFace = pMesh->AddFace(iCurrentMaterial);
							size_t o = pPolygons->GetFaceVertexOffset(k);
							size_t iFaceVertexCount = pPolygons->GetFaceVertexCount(k);
							for (size_t v = 0; v < iFaceVertexCount; v++)
								pMesh->AddVertexToFace(iFace, pPositions[o+v], pUVs?pUVs[o+v]:~0, pNormals?pNormals[o+v]:~0);
						}
					}
				}
			}

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

		FCDVisualSceneNodeLibrary* pVisualScenes = pDoc->GetVisualSceneLibrary();
		iEntities = pVisualScenes->GetEntityCount();
		for (i = 0; i < iEntities; ++i)
		{
			FCDSceneNode* pNode = pVisualScenes->GetEntity(i);

			size_t iScene = m_pScene->AddScene(convert_from_fstring(pNode->GetName()));
			ReadDAESceneTree(pNode, m_pScene->GetScene(iScene));
		}
	}
	else
	{
		printf("Oops! Some kind of error happened!\n");
		return false;
	}

	m_pScene->SetWorkListener(m_pWorkListener);

	m_pScene->CalculateExtends();

	for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++)
	{
		if (m_bWantEdges)
			m_pScene->GetMesh(i)->CalculateEdgeData();

		if (m_pScene->GetMesh(i)->GetNumNormals() == 0)
			m_pScene->GetMesh(i)->CalculateVertexNormals();

		m_pScene->GetMesh(i)->CalculateVertexTangents();
	}

	pDoc->Release();

	FCollada::Release();

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();

	return true;
}
コード例 #17
0
ファイル: collada.cpp プロジェクト: BSVino/Digitanks
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();
}
コード例 #18
0
ファイル: silo.cpp プロジェクト: dfk789/CodenameInfinite
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();
}
コード例 #19
0
ファイル: smd.cpp プロジェクト: dfk789/CodenameInfinite
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);
}
コード例 #20
0
ファイル: main.cpp プロジェクト: BSVino/CodenameInfinite
int main(int argc, const char* argv[])
{
	if (argc < 2)
	{
		printf("I need a file to convert!\n");
		return 0;
	}

	size_t iFileLength = strlen(argv[1]);
	const char* pszExtension = argv[1]+iFileLength-4;

	CConversionScene s;
	CModelConverter c(&s);

	tstring sFile = argv[1];

	if (strcmp(pszExtension, ".obj") == 0)
	{
		printf("Reading the OBJ... ");
		c.ReadOBJ(sFile);
	}
	else if (strcmp(pszExtension, ".sia") == 0)
	{
		printf("Reading the Silo ASCII file... ");
		c.ReadSIA(sFile);
	}
	else if (strcmp(pszExtension, ".dae") == 0)
	{
		printf("Reading the Collada .dae file... ");
		c.ReadDAE(sFile);
	}

	printf("Done.\n");
	printf("\n");

	printf("-------------\n");
	printf("Materials   : %d\n", s.GetNumMaterials());
	printf("Meshes      : %d\n", s.GetNumMeshes());
	printf("\n");

	for (size_t i = 0; i < s.GetNumMeshes(); i++)
	{
		CConversionMesh* pMesh = s.GetMesh(i);

		printf("-------------\n");
		printf("Mesh: %s\n", pMesh->GetBoneName(0));
		printf("Vertices    : %d\n", pMesh->GetNumVertices());
		printf("Normals     : %d\n", pMesh->GetNumNormals());
		printf("UVs         : %d\n", pMesh->GetNumUVs());
		printf("Bones       : %d\n", pMesh->GetNumBones());
		printf("Faces       : %d\n", pMesh->GetNumFaces());
		printf("\n");
	}

	printf("Writing the SMD... ");
	c.WriteSMDs();
	printf("Done.\n");
	printf("\n");

	printf("Press enter to continue...\n");
	getchar();

	return 0;
}
コード例 #21
0
ファイル: crunch.cpp プロジェクト: BSVino/SMAK
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();
}