⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nvcomplexmesh.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					BoneWeights[dwQuadCount][i].y = fweight;
				}
				else if ((dwWeightCount & 0x3) == 2)
				{
					BoneWeights[dwQuadCount][i].z = fweight;
				}
				else if ((dwWeightCount & 0x3) == 3)
				{
					BoneWeights[dwQuadCount][i].w = fweight;
					
					dwQuadCount++;
					
					if (!bLastWeight)
						BoneWeights[dwQuadCount][i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
				}

				if (bLastWeight)
					break;

				dwWeightCount++;
			}

			// Add the indices.  We retrieve the list of dwords and pack them
			// into vec4's.
			dwQuadCount = 0;
			dwIndexCount = 0;
			
			// Reset to 0
			BoneIndices[dwQuadCount][i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
			
			do
			{
				float fIndex;
				DWORD dwIndexQuad = (*(DWORD*)pVert);
	
				if ((dwIndexCount & 0x3) == 0)
				{
					fIndex = (float)(dwIndexQuad & 0x000000FF) * 3.f;
					BoneIndices[dwQuadCount][i].x = fIndex;
				}
				else if ((dwIndexCount & 0x3) == 1)
				{
					fIndex = (float)((dwIndexQuad & 0x0000FF00) >> 8) * 3.f;
					BoneIndices[dwQuadCount][i].y = fIndex;
				}
				else if ((dwIndexCount & 0x3) == 2)
				{
					fIndex = (float)((dwIndexQuad & 0x00FF0000) >> 16) * 3.f;
					BoneIndices[dwQuadCount][i].z = fIndex;
				}
				else if ((dwIndexCount & 0x3) == 3)
				{
					fIndex = (float)((dwIndexQuad & 0xFF000000) >> 24) * 3.f;
					BoneIndices[dwQuadCount][i].w = fIndex;
			
					if ((dwIndexCount + 1) < m_dwNumWeights)
					{
						dwQuadCount++;
						pVert += sizeof(DWORD);
						BoneIndices[dwQuadCount][i] = D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f);
					}
				}

				dwIndexCount++;

			} while (dwIndexCount < m_dwNumWeights);

			// Make sure we step over the remaining indices.
			pVert += sizeof(DWORD);
		}

		// Normal
		if (vbdesc.FVF & D3DFVF_NORMAL)
		{
			if (pNormal)
				pNormal[i] = (*(D3DXVECTOR3*)pVert);
			
			pVert += sizeof(D3DXVECTOR3);
		}
		// Diffuse
		if (vbdesc.FVF & D3DFVF_DIFFUSE)
		{
			if (pDiffuse)
				pDiffuse[i] = (*(D3DXVECTOR4*)pVert);

			pVert += sizeof(D3DXVECTOR4);
		}
		// Specular
		if (vbdesc.FVF & D3DFVF_SPECULAR)
		{
			if (pSpecular)
				pSpecular[i] = (*(D3DXVECTOR4*)pVert);
			
			pVert += sizeof(D3DXVECTOR4);
		}
		// Up to 8 texture coordinates
		for (dwTexCount = 0; dwTexCount < dwTextures; dwTexCount++)
		{
			if ((Textures.size() > dwTexCount) && Textures[dwTexCount])
				Textures[dwTexCount][i] = (*(D3DXVECTOR2*)pVert);
		
			pVert += sizeof(D3DXVECTOR2);
		}

		pVertex += dwStride;

		// Sanity check to confirm sizes
		NVASSERT(pVert == pVertex, "Vertex size check wrong");
	}
	pVB->Unlock();
	
	// Copy the index data
	BYTE* pIndex;
	hr = pIB->Lock(0, ibdesc.Size,(BYTE**)&pIndex, 0);
	NVASSERT(ibdesc.Format == D3DFMT_INDEX16, "Index buffer should be INDEX16");
	m_Indices.resize(ibdesc.Size / 2);
	memcpy(&m_Indices[0], pIndex, ibdesc.Size);
	pIB->Unlock();

	if (pAttributes)
		HeapFree(GetProcessHeap(), 0, pAttributes);

	return true;
}

bool NVComplexMesh::CreateFromMFile(LPDIRECT3DDEVICE8 pDevice, const char* fileName)
{
	FILE* fp;
	char line[256];
	char* token;
	DWORD dwIndex = 0;
	DWORD dwNumVertices = 0;
	NVVertexData* pData = NULL;

	typedef std::map<DWORD, DWORD> tPositionIndexLookup;
	tPositionIndexLookup PositionIndexLookup;

	if((fp = fopen(fileName, "r")) == NULL)
		return false;

	Release();

	// Create vertex data in for the geometry we find in the mesh
	tNVData_float3* pVec3Data = static_cast<tNVData_float3*>(AddVertexData(NVVERT_POSITION, D3DDATATYPE_FLOAT3));
	if (!pVec3Data)
		return false;

	fgets(line, 256, fp);

	while(!feof(fp))
	{
		if(line[0] == '#')
		{
			//it's a comment
			fgets(line, 256, fp);
			continue;
		}
		else if(line[0] == 'V')
		{
			//it's a vertex
			float x, y, z;
			DWORD dwID;

			//get Vertex
			token = strtok(line, " ");

			//get the number
			token = strtok(NULL, " ");
			dwID = atoi(token);
			
			//get the vertex info
			token = strtok(NULL, " ");
			x = atof(token);

			token = strtok(NULL, " ");
			y = atof(token);

			token = strtok(NULL, " ");
			z = atof(token);

			pVec3Data->push_back(D3DXVECTOR3(x, y, z));
			PositionIndexLookup.insert(tPositionIndexLookup::value_type(dwID, dwIndex++) );
			dwNumVertices++;
		}
		else if(line[0] == 'F')
		{
			DWORD Index[3];
			//it's a face

			//get Face
			token = strtok(line, " ");

			//get number
			token = strtok(NULL, " ");

			//get index data
			token = strtok(NULL, " ");

			Index[0] = atoi(token);

			token = strtok(NULL, " ");
			Index[1] = atoi(token);

			token = strtok(NULL, " ");
			Index[2] = atoi(token);

			tPositionIndexLookup::iterator itrIndex[3];
			itrIndex[0] = PositionIndexLookup.find(Index[0]);
			itrIndex[1] = PositionIndexLookup.find(Index[1]);
			itrIndex[2] = PositionIndexLookup.find(Index[2]);

			// Some files may have faces, but no vertices to match them
			if ((itrIndex[0] != PositionIndexLookup.end()) &&
				(itrIndex[1] != PositionIndexLookup.end()) &&
				(itrIndex[2] != PositionIndexLookup.end()))
			{
				// Add the indices
				m_Indices.push_back(itrIndex[0]->second);
				m_Indices.push_back(itrIndex[1]->second);
				m_Indices.push_back(itrIndex[2]->second);
			}
		}
		else if(line[0] == 'E')
		{
		//edge, do nothing
		}
		else
		{
		}

		fgets(line, 256, fp);	
	}
	fclose(fp);

	if (pVec3Data->empty() || m_Indices.empty())
		return false;

	SetNumVertices(dwNumVertices);

	// Create named constants for this mesh
	NVMaterialResource* pMaterial = new NVMaterialResource;
	pMaterial->AddValue("diffuse", NVValue(NVV_VECTOR4, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f)));
	pMaterial->AddValue("ambient", NVValue(NVV_VECTOR4, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f)));
	pMaterial->AddValue("specular", NVValue(NVV_VECTOR4, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f)));

	// No sections in a .m file
	NVComplexMeshSection Attrib;
	Attrib.m_dwAttribId = 0;
	Attrib.m_dwIndexStart = 0;
	Attrib.m_dwIndexCount = m_Indices.size();
	Attrib.m_dwVertexStart = 0;
	Attrib.m_dwVertexCount = dwNumVertices;
	Attrib.m_Material = NVRESOURCEMANAGER.AddResource(pMaterial);
	m_Sections.push_back(Attrib);

	return true;
}

bool NVComplexMesh::CreateFromSphere(float fRadius, WORD wNumRings, WORD wNumSections, const D3DXVECTOR3& PositionScaling, const D3DXVECTOR2& TextureScaling)
{
    float x, y, z, v, rsintheta; // Temporary variables
    WORD  i, j, n, m;            // counters
    D3DXVECTOR3 vPoint;
	NVVertexData* pVertexData = NULL;
	NVVertexData* pTextureData = NULL;

	Release();

    //Generate space for the required triangles and vertices.
    WORD       wNumTriangles = (wNumRings + 1) * wNumSections * 2;
    DWORD      dwNumIndices   = wNumTriangles*3;
    DWORD      dwNumVertices  = (wNumRings + 1) * wNumSections + 2;
	SetNumVertices(dwNumVertices);

	// Create vertex data for the geometry we find in the mesh
	pVertexData = AddVertexData(NVVERT_POSITION, D3DDATATYPE_FLOAT3);
	if (!pVertexData)
		return false;

	pTextureData = AddVertexData(NVVERT_TEXTURE0, D3DDATATYPE_FLOAT2);
	if (!pTextureData)
		return false;

	D3DXVECTOR3* pPosition = GetDataPointer<D3DXVECTOR3, D3DDATATYPE_FLOAT3>(pVertexData);
	D3DXVECTOR2* pTexture = GetDataPointer<D3DXVECTOR2, D3DDATATYPE_FLOAT2>(pTextureData);

	m_Indices.resize(dwNumIndices);

    // Generate vertices at the top and bottom points.
    D3DXVECTOR3 vTopPoint  = D3DXVECTOR3( 0.0f, +PositionScaling.y*fRadius, 0.0f);
    D3DXVECTOR3 vBotPoint  = D3DXVECTOR3( 0.0f, -PositionScaling.y*fRadius, 0.0f);
    D3DXVECTOR3 vNormal = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

	pPosition[0] = D3DXVECTOR3(vTopPoint.x, vTopPoint.y, vTopPoint.z);
	pTexture[0] = D3DXVECTOR2(0.0f, 0.0f);

	pPosition[dwNumVertices-1] = D3DXVECTOR3(vBotPoint.x, vBotPoint.y, vBotPoint.z);
	pTexture[dwNumVertices-1] = D3DXVECTOR2(0.0f, 0.0f);

    // Generate vertex points for rings
    float dtheta = (float)(D3DX_PI / (wNumRings + 2));     //Angle between each ring
    float dphi   = (float)(2*D3DX_PI / (wNumSections)); //Angle between each section
    float theta  = dtheta;
    n = 1; //vertex being generated, begins at 1 to skip top point

    for( i = 0; i < (wNumRings+1); i++ )
    {
        y = fRadius * (float)cos(theta); // y is the same for each ring
        v = theta / D3DX_PI;     // v is the same for each ring
        rsintheta = fRadius * (float)sin(theta);
        float phi = 0.0f;

        for( j = 0; j < wNumSections; j++ )
        {
            x = rsintheta * (float)sin(phi);
            z = rsintheta * (float)cos(phi);
        
            float u = 1.0f - (float)(phi / (2 * D3DX_PI) );
            NVASSERT(u <= 1.001f, "Invalid texture coord");
			NVASSERT(u >= 0.0f, "Invalid texture coord");
            vPoint        = D3DXVECTOR3(PositionScaling.x * x, PositionScaling.y * y, PositionScaling.z * z );
			pPosition[n] = D3DXVECTOR3(vPoint.x, vPoint.y, vPoint.z);
			pTexture[n] = D3DXVECTOR2(u * TextureScaling.x, v * TextureScaling.y);

            phi += dphi;
            ++n;
        }
        theta += dtheta;
    }

    // Generate triangles for top and bottom caps.
    for( i = 0; i < wNumSections; i++ )
    {
        m_Indices[3*i+0] = 0;
        m_Indices[3*i+1] = i + 1;
        m_Indices[3*i+2] = 1 + ((i + 1) % wNumSections);

        m_Indices[3*(wNumTriangles - wNumSections + i)+0] = (WORD)( dwNumVertices - 1 );
        m_Indices[3*(wNumTriangles - wNumSections + i)+1] = (WORD)( dwNumVertices - 2 - i );
        m_Indices[3*(wNumTriangles - wNumSections + i)+2] = (WORD)( dwNumVertices - 2 - 
                ((1 + i) % wNumSections) );
    }

    // Generate triangles for the rings
    m = 1;            // first vertex in current ring,begins at 1 to skip top point
    n = wNumSections; // triangle being generated, skip the top cap 
        
    for( i = 0; i < wNumRings; i++ )
    {
        for( j = 0; j < (wNumSections); j++ )
        {
            m_Indices[3*n+0] = m + j;
            m_Indices[3*n+1] = m + wNumSections + j;
            m_Indices[3*n+2] = m + wNumSections + ((j + 1) % wNumSections);
            
            m_Indices[3*(n+1)+0] = m_Indices[3*n+0];
            m_Indices[3*(n+1)+1] = m_Indices[3*n+2];
            m_Indices[3*(n+1)+2] = m + ((j + 1) % wNumSections);
            
            n += 2;
        }
      
        m += wNumSections;
    }

	// Create named constants for this mesh
	NVMaterialResource* pMaterial = new NVMaterialResource;
	pMaterial->AddValue("diffuse", NVValue(NVV_VECTOR4, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f)));
	pMaterial->AddValue("ambient", NVValue(NVV_VECTOR4, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f)));
	pMaterial->AddValue("specular", NVValue(NVV_VECTOR4, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f)));
	pMaterial->AddValue("power", NVValue(NVV_VECTOR4, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 30.0f)));
	

	// No sections in a .m file
	NVComplexMeshSection Attrib;
	Attrib.m_dwAttribId = 0;
	Attrib.m_dwIndexStart = 0;
	Attrib.m_dwIndexCount = m_Indices.size();
	Attrib.m_dwVertexStart = 0;
	Attrib.m_dwVertexCount = dwNumVertices;
	Attrib.m_Material = NVRESOURCEMANAGER.AddResource(pMaterial);
	m_Sections.push_back(Attrib);

    return true;
}

bool NVComplexMesh::Translate(const D3DXVECTOR3& Translation)
{
	DWORD i = 0;
	NVVertexData* pPositionData = FindVertexData(NVVERT_POSITION);
	if (!pPositionData || (pPositionData->GetDataType() != D3DDATATYPE_FLOAT3))
	{
		NVASSERT(0, "No position data in mesh, or wrong format");
		return false;
	}

	D3DXVECTOR3* pPosition = GetDataPointer<D3DXVECTOR3, D3DDATATYPE_FLOAT3>(pPositionData);
	while (i < pPositionData->size())
	{
		pPosition[i] += Translation;
		i++;
	}
	return true;
}
bool NVComplexMesh::Scale(float fScale)
{
	DWORD i = 0;
	NVVertexData* pPositionData = FindVertexData(NVVERT_POSITION);
	if (!pPositionData || (pPositionData->GetDataType() != D3DDATATYPE_FLOAT3))
	{
		NVASSERT(0, "No position data in mesh, or wrong format");
		return false;
	}

	D3DXVECTOR3* pPosition = GetDataPointer<D3DXVECTOR3, D3DDATATYPE_FLOAT3>(pPositionData);
	while (i < pPositionData->size())
	{
		pPosition[i] *= fScale;
		i++;
	}
	
	return true;
}

bool NVComplexMesh::Transform(const D3DXMATRIX& Transform)
{
	DWORD i = 0;
	NVVertexData* pPositionData = FindVertexData(NVVERT_POSITION);
	if (!pPositionData || (pPositionData->GetDataType() != D3DDATATYPE_FLOAT3))
	{
		NVASSERT(0, "No position data in mesh, or wrong format");
		return false;
	}

	D3DXVECTOR3* pPosition = GetDataPointer<D3DXVECTOR3, D3DDATATYPE_FLOAT3>(pPositionData);
	while (i < pPositionData->size())
	{
		D3DXVec3TransformCoord(&pPosition[i], &pPosition[i], &Transform);
		i++;
	}
	
	return true;
}


bool NVComplexMesh::ComputeBounds(NVAABounds* pBounds)
{
	pBounds->m_vecCenter = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	pBounds->m_fRadius = 0.0f;
	pBounds->m_vecMinExtents = D3DXVECTOR3(FLT_MAX, FLT_MAX, FLT_MAX);
	pBounds->m_vecMaxExtents = D3DXVECTOR3(-FLT_MAX, -FLT_MAX, -FLT_MAX);

	DWORD i = 0;
   	NVVertexData* pPositionData = FindVertexData(NVVERT_POSITION);
   	if (!pPositionData || (pPositionData->GetDataType() != D3DDATATYPE_FLOAT3))
   	{
   		NVASSERT(0, "No position data in mesh or wrong format");
   		return false;
   	}
   
   	D3DXVECTOR3* pPosition = GetDataPointer<D3DXVECTOR3, D3DDATATYPE_FLOAT3>(pPositionData);
	while (i < pPositionData->size())
	{
   		float x = pPosition[i].x;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -