void CreateMeshConstantsBuffer(ID3D11Device *device)
    {
        std::vector<MeshConstants> meshConstants(GetMeshCount());

        for (int i = 0; i < GetMeshCount(); ++i)
        {
            meshConstants[i].faceCount = meshes_[i]->faceCount;
            meshConstants[i].indexOffset = meshes_[i]->indexOffset;
            meshConstants[i].vertexCount = meshes_[i]->vertexCount;
            meshConstants[i].vertexOffset = meshes_[i]->vertexOffset;
        }

        D3D11_BUFFER_DESC bufferDesc = {};
        bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
        bufferDesc.ByteWidth = static_cast<UINT>(meshConstants.size() * sizeof(MeshConstants));
        bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
        bufferDesc.StructureByteStride = sizeof(MeshConstants);
        bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;

        D3D11_SUBRESOURCE_DATA initialData;
        initialData.pSysMem = meshConstants.data();
        initialData.SysMemPitch = bufferDesc.ByteWidth;
        initialData.SysMemSlicePitch = bufferDesc.ByteWidth;

        device->CreateBuffer(&bufferDesc, &initialData, &meshConstantsBuffer_);

        SetDebugName(meshConstantsBuffer_.Get(), "Mesh constants buffer");

        for (std::vector<std::unique_ptr<StaticMesh>>::iterator it = meshes_.begin(),
                                                                end = meshes_.end();
             it != end; ++it)
        {
            (*it)->meshConstantsBuffer = meshConstantsBuffer_;
        }

        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
        srvDesc.Format = DXGI_FORMAT_UNKNOWN;
        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
        srvDesc.Buffer.ElementOffset = 0;
        srvDesc.Buffer.ElementWidth = GetMeshCount();
        device->CreateShaderResourceView(
            meshConstantsBuffer_.Get(), &srvDesc, &meshConstantsBufferView_);

        SetDebugName(meshConstantsBufferView_.Get(), "Mesh constants buffer view");
    }
	bool NvModelExtVK::InitVertexState() {
		uint32_t meshCount = GetMeshCount();
		for (uint32_t meshIndex = 0; meshIndex < meshCount; ++meshIndex)
		{
			if (!GetMesh(meshIndex)->InitVertexState())
				return false;
		}

		return true;
	}
	bool NvModelExtVK::AddInstanceData(uint32_t location, VkFormat format, uint32_t offset) {
		uint32_t meshCount = GetMeshCount();
		for (uint32_t meshIndex = 0; meshIndex < meshCount; ++meshIndex)
		{
			if (!GetMesh(meshIndex)->AddInstanceData(location, format, offset))
				return false;
		}

		return true;
	}
Esempio n. 4
0
	void NvModelExtGL::DrawElements(uint32_t instanceCount, GLint positionHandle, GLint normalHandle, GLint texcoordHandle, GLint tangentHandle)
    {
		uint32_t numMeshes = GetMeshCount();
		for (uint32_t meshIndex = 0; meshIndex < numMeshes; ++meshIndex)
		{
			Nv::NvMeshExtGL* pMesh = GetMesh(meshIndex);
			uint32_t matId = pMesh->GetMaterialID();
            ActivateMaterial(matId);
            pMesh->DrawElements(instanceCount, positionHandle, normalHandle, texcoordHandle, tangentHandle);
		}
    }
	bool NvModelExtVK::EnableInstanceData(uint32_t instanceVertSize) {
		uint32_t meshCount = GetMeshCount();
		for (uint32_t meshIndex = 0; meshIndex < meshCount; ++meshIndex)
		{
			if (!GetMesh(meshIndex)->EnableInstanceData(instanceVertSize))
				return false;
		}

		m_instanced = true;
		return true;
	}
bool KX_NavMeshObject::BuildNavMesh()
{
	if (m_navMesh)
	{
		delete m_navMesh;
		m_navMesh = NULL;
	}

	if (GetMeshCount()==0)
	{
		printf("Can't find mesh for navmesh object: %s\n", m_name.ReadPtr());
		return false;
	}

	float *vertices = NULL, *dvertices = NULL;
	unsigned short *polys = NULL, *dtris = NULL, *dmeshes = NULL;
	int nverts = 0, npolys = 0, ndvertsuniq = 0, ndtris = 0;
	int vertsPerPoly = 0;
	if (!BuildVertIndArrays(vertices, nverts, polys, npolys, 
							dmeshes, dvertices, ndvertsuniq, dtris, ndtris, vertsPerPoly ) 
			|| vertsPerPoly<3)
	{
		printf("Can't build navigation mesh data for object:%s\n", m_name.ReadPtr());
		if (vertices) delete[] vertices;
		return false;
	}
	
	MT_Point3 pos;
	if (dmeshes==NULL)
	{
		for (int i=0; i<nverts; i++)
		{
			flipAxes(&vertices[i*3]);
		}
		for (int i=0; i<ndvertsuniq; i++)
		{
			flipAxes(&dvertices[i*3]);
		}
	}

	buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly);
	
	float cs = 0.2f;

	if (!nverts || !npolys)
	{
		if (vertices) delete[] vertices;
		return false;
	}

	float bmin[3], bmax[3];
	calcMeshBounds(vertices, nverts, bmin, bmax);
	//quantize vertex pos
	unsigned short* vertsi = new unsigned short[3*nverts];
	float ics = 1.f/cs;
	for (int i=0; i<nverts; i++)
	{
		vertsi[3*i+0] = static_cast<unsigned short>((vertices[3*i+0]-bmin[0])*ics);
		vertsi[3*i+1] = static_cast<unsigned short>((vertices[3*i+1]-bmin[1])*ics);
		vertsi[3*i+2] = static_cast<unsigned short>((vertices[3*i+2]-bmin[2])*ics);
	}

	// Calculate data size
	const int headerSize = sizeof(dtStatNavMeshHeader);
	const int vertsSize = sizeof(float)*3*nverts;
	const int polysSize = sizeof(dtStatPoly)*npolys;
	const int nodesSize = sizeof(dtStatBVNode)*npolys*2;
	const int detailMeshesSize = sizeof(dtStatPolyDetail)*npolys;
	const int detailVertsSize = sizeof(float)*3*ndvertsuniq;
	const int detailTrisSize = sizeof(unsigned char)*4*ndtris;

	const int dataSize = headerSize + vertsSize + polysSize + nodesSize +
		detailMeshesSize + detailVertsSize + detailTrisSize;
	unsigned char* data = new unsigned char[dataSize];
	if (!data)
		return false;
	memset(data, 0, dataSize);

	unsigned char* d = data;
	dtStatNavMeshHeader* header = (dtStatNavMeshHeader*)d; d += headerSize;
	float* navVerts = (float*)d; d += vertsSize;
	dtStatPoly* navPolys = (dtStatPoly*)d; d += polysSize;
	dtStatBVNode* navNodes = (dtStatBVNode*)d; d += nodesSize;
	dtStatPolyDetail* navDMeshes = (dtStatPolyDetail*)d; d += detailMeshesSize;
	float* navDVerts = (float*)d; d += detailVertsSize;
	unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize;

	// Store header
	header->magic = DT_STAT_NAVMESH_MAGIC;
	header->version = DT_STAT_NAVMESH_VERSION;
	header->npolys = npolys;
	header->nverts = nverts;
	header->cs = cs;
	header->bmin[0] = bmin[0];
	header->bmin[1] = bmin[1];
	header->bmin[2] = bmin[2];
	header->bmax[0] = bmax[0];
	header->bmax[1] = bmax[1];
	header->bmax[2] = bmax[2];
	header->ndmeshes = npolys;
	header->ndverts = ndvertsuniq;
	header->ndtris = ndtris;

	// Store vertices
	for (int i = 0; i < nverts; ++i)
	{
		const unsigned short* iv = &vertsi[i*3];
		float* v = &navVerts[i*3];
		v[0] = bmin[0] + iv[0] * cs;
		v[1] = bmin[1] + iv[1] * cs;
		v[2] = bmin[2] + iv[2] * cs;
	}
	//memcpy(navVerts, vertices, nverts*3*sizeof(float));

	// Store polygons
	const unsigned short* src = polys;
	for (int i = 0; i < npolys; ++i)
	{
		dtStatPoly* p = &navPolys[i];
		p->nv = 0;
		for (int j = 0; j < vertsPerPoly; ++j)
		{
			if (src[j] == 0xffff) break;
			p->v[j] = src[j];
			p->n[j] = src[vertsPerPoly+j]+1;
			p->nv++;
		}
		src += vertsPerPoly*2;
	}

	header->nnodes = createBVTree(vertsi, nverts, polys, npolys, vertsPerPoly,
								cs, cs, npolys*2, navNodes);
	
	
	if (dmeshes==NULL)
	{
		//create fake detail meshes
		for (int i = 0; i < npolys; ++i)
		{
			dtStatPolyDetail& dtl = navDMeshes[i];
			dtl.vbase = 0;
			dtl.nverts = 0;
			dtl.tbase = i;
			dtl.ntris = 1;
		}
		// setup triangles.
		unsigned char* tri = navDTris;
		for (size_t i=0; i<ndtris; i++)
		{
			for (size_t j=0; j<3; j++)
				tri[4*i+j] = j;
		}
	}
	else
	{
		//verts
		memcpy(navDVerts, dvertices, ndvertsuniq*3*sizeof(float));
		//tris
		unsigned char* tri = navDTris;
		for (size_t i=0; i<ndtris; i++)
		{
			for (size_t j=0; j<3; j++)
				tri[4*i+j] = dtris[6*i+j];
		}
		//detailed meshes
		for (int i = 0; i < npolys; ++i)
		{
			dtStatPolyDetail& dtl = navDMeshes[i];
			dtl.vbase = dmeshes[i*4+0];
			dtl.nverts = dmeshes[i*4+1];
			dtl.tbase = dmeshes[i*4+2];
			dtl.ntris = dmeshes[i*4+3];
		}
	}

	m_navMesh = new dtStatNavMesh;
	m_navMesh->init(data, dataSize, true);

	delete [] vertices;

	/* navmesh conversion is using C guarded alloc for memory allocaitons */
	MEM_freeN(polys);
	if (dmeshes) MEM_freeN(dmeshes);
	if (dtris) MEM_freeN(dtris);

	if (dvertices)
		delete [] dvertices;

	if (vertsi)
		delete [] vertsi;

	return true;
}