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; }
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; }