void JSONSerializer::SerializeStaticMeshNode(rapidjson::Value& nodeValue, const shared_ptr<StaticMeshNode>& node) { const shared_ptr<Mesh>& mesh = node->GetMesh(); ASSERT(mesh->mRawVertexData != nullptr); nodeValue.AddMember("format", mesh->mFormat->mBinaryFormat, *mAllocator); nodeValue.AddMember("vertexcount", mesh->mVertexCount, *mAllocator); nodeValue.AddMember("indexcount", mesh->mIndexCount, *mAllocator); UINT floatCount = mesh->mVertexCount * mesh->mFormat->mStride / sizeof(float); float* attribs = reinterpret_cast<float*>(mesh->mRawVertexData); rapidjson::Value attribArray(rapidjson::kArrayType); for (UINT i = 0; i < floatCount; i++) { attribArray.PushBack(double(attribs[i]), *mAllocator); } nodeValue.AddMember("vertices", attribArray, *mAllocator); if (mesh->mIndexCount > 0) { rapidjson::Value indexArray(rapidjson::kArrayType); for (UINT i = 0; i < mesh->mIndexCount; i++) { indexArray.PushBack(UINT(mesh->mIndexData[i]), *mAllocator); } nodeValue.AddMember("indices", indexArray, *mAllocator); } }
bool MyDynamicManyRectsBase::Create(ID3D11Device* pD3DDevice, UINT rectCount, UINT strideInBytes, const void* pInitialData) { _ASSERTE(m_pVertexBuffer == nullptr); _ASSERTE(m_pIndexBuffer == nullptr); _ASSERTE(pD3DDevice != nullptr); _ASSERTE(pInitialData != nullptr); // 頂点バッファ初期化データに NULL 指定は不可。テクスチャの生成のときや、OpenGL とは違う。 _ASSERTE(rectCount > 0); _ASSERTE(strideInBytes > 0); HRESULT hr = E_FAIL; const UINT vertexCount = rectCount * 4; D3D11_BUFFER_DESC vbDesc = {}; vbDesc.ByteWidth = vertexCount * strideInBytes; vbDesc.Usage = D3D11_USAGE_DYNAMIC; vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; D3D11_SUBRESOURCE_DATA vbSubrData = {}; vbSubrData.pSysMem = pInitialData; hr = pD3DDevice->CreateBuffer(&vbDesc, &vbSubrData, m_pVertexBuffer.ReleaseAndGetAddressOf()); if (FAILED(hr)) { return false; } std::vector<TIndex> indexArray(rectCount * 6); for (size_t i = 0; i < rectCount; ++i) { // CCW indexArray[i * 6 + 0] = TIndex(0 + (i * 4)); indexArray[i * 6 + 1] = TIndex(2 + (i * 4)); indexArray[i * 6 + 2] = TIndex(1 + (i * 4)); indexArray[i * 6 + 3] = TIndex(1 + (i * 4)); indexArray[i * 6 + 4] = TIndex(2 + (i * 4)); indexArray[i * 6 + 5] = TIndex(3 + (i * 4)); } D3D11_BUFFER_DESC ibDesc = {}; ibDesc.ByteWidth = UINT(indexArray.size() * sizeof(TIndex)); ibDesc.Usage = D3D11_USAGE_DEFAULT; ibDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA ibSubrData = {}; ibSubrData.pSysMem = &indexArray[0]; hr = pD3DDevice->CreateBuffer(&ibDesc, &ibSubrData, m_pIndexBuffer.ReleaseAndGetAddressOf()); if (FAILED(hr)) { return false; } m_rectCount = rectCount; m_vertexBufferSizeInBytes = vbDesc.ByteWidth; return true; }
const StaticMesh* MeshManager::GetMesh(const std::string& meshName) { auto meshIterator = m_MeshMap.find(meshName); if (m_MeshMap.end() == meshIterator) { // Attempt to load from the database. int offset = m_MeshDBIndex.OffsetOfMesh(meshName); if (-1 == offset) { return m_DefaultMesh.get(); } else { // We have the offset, we can now load the mesh from the HDD, and initialize its GPU form fseek(m_MeshDatabase, static_cast<long>(offset), SEEK_SET); StoredStaticMesh storedStaticMesh; storedStaticMesh.Load(m_MeshDatabase); std::unique_ptr<float[]> vertexArray(storedStaticMesh.GetVertexArray()); std::unique_ptr<float[]> texCoordArray(storedStaticMesh.GetTexCoordArray()); std::unique_ptr<float[]> normalArray(storedStaticMesh.GetNormalArray()); std::unique_ptr<uint32_t[]> indexArray(storedStaticMesh.GetIndexArray()); auto newMesh = new StaticMesh(storedStaticMesh.GetNumVertices(), std::move(vertexArray), std::move(texCoordArray), std::move(normalArray), storedStaticMesh.GetNumIndices(), std::move(indexArray)); std::unique_ptr<StaticMesh> staticMesh(newMesh); m_MeshMap.insert(std::make_pair(meshName, std::move(staticMesh))); return newMesh; } } else { return m_DefaultMesh.get(); } }
void CalculateTangent(Mesh3DS_t *Mesh) { int i, j, k, Count, Vertex=0, Result=0; index_t VertexIndex; long (*TriangleRefs)[32]; float *FaceTangent, *FaceBinormal, *FaceNormal; float v0[3], v1[3], uv0[2], uv1[2]; float s[3], t[3], n[3], r; Mesh->Tangent=(float *)malloc(sizeof(float)*3*Mesh->NumVertex); if(Mesh->Tangent==NULL) return; memset(Mesh->Tangent, 0, sizeof(float)*3*Mesh->NumVertex); Mesh->Binormal=(float *)malloc(sizeof(float)*3*Mesh->NumVertex); if(Mesh->Binormal==NULL) return; memset(Mesh->Binormal, 0, sizeof(float)*3*Mesh->NumVertex); Mesh->Normal=(float *)malloc(sizeof(float)*3*Mesh->NumVertex); if(Mesh->Normal==NULL) return; memset(Mesh->Normal, 0, sizeof(float)*3*Mesh->NumVertex); if(Mesh->Smooth==NULL) { for(i=0;i<Mesh->NumFace;i++) { unsigned short i1=Mesh->Face[3*i+0]; unsigned short i2=Mesh->Face[3*i+1]; unsigned short i3=Mesh->Face[3*i+2]; v0[0]=Mesh->Vertex[3*i2+0]-Mesh->Vertex[3*i1+0]; v0[1]=Mesh->Vertex[3*i2+1]-Mesh->Vertex[3*i1+1]; v0[2]=Mesh->Vertex[3*i2+2]-Mesh->Vertex[3*i1+2]; uv0[0]=Mesh->UV[2*i2+0]-Mesh->UV[2*i1+0]; uv0[1]=Mesh->UV[2*i2+1]-Mesh->UV[2*i1+1]; v1[0]=Mesh->Vertex[3*i3+0]-Mesh->Vertex[3*i1+0]; v1[1]=Mesh->Vertex[3*i3+1]-Mesh->Vertex[3*i1+1]; v1[2]=Mesh->Vertex[3*i3+2]-Mesh->Vertex[3*i1+2]; uv1[0]=Mesh->UV[2*i3+0]-Mesh->UV[2*i1+0]; uv1[1]=Mesh->UV[2*i3+1]-Mesh->UV[2*i1+1]; r=1.0f/(uv0[0]*uv1[1]-uv1[0]*uv0[1]); s[0]=(uv1[1]*v0[0]-uv0[1]*v1[0])*r; s[1]=(uv1[1]*v0[1]-uv0[1]*v1[1])*r; s[2]=(uv1[1]*v0[2]-uv0[1]*v1[2])*r; Normalize(s); Mesh->Tangent[3*i1+0]+=s[0]; Mesh->Tangent[3*i1+1]+=s[1]; Mesh->Tangent[3*i1+2]+=s[2]; Mesh->Tangent[3*i2+0]+=s[0]; Mesh->Tangent[3*i2+1]+=s[1]; Mesh->Tangent[3*i2+2]+=s[2]; Mesh->Tangent[3*i3+0]+=s[0]; Mesh->Tangent[3*i3+1]+=s[1]; Mesh->Tangent[3*i3+2]+=s[2]; t[0]=(uv0[0]*v1[0]-uv1[0]*v0[0])*r; t[1]=(uv0[0]*v1[1]-uv1[0]*v0[1])*r; t[2]=(uv0[0]*v1[2]-uv1[0]*v0[2])*r; Normalize(t); Mesh->Binormal[3*i1+0]-=t[0]; Mesh->Binormal[3*i1+1]-=t[1]; Mesh->Binormal[3*i1+2]-=t[2]; Mesh->Binormal[3*i2+0]-=t[0]; Mesh->Binormal[3*i2+1]-=t[1]; Mesh->Binormal[3*i2+2]-=t[2]; Mesh->Binormal[3*i3+0]-=t[0]; Mesh->Binormal[3*i3+1]-=t[1]; Mesh->Binormal[3*i3+2]-=t[2]; Cross(v0, v1, n); Normalize(n); Mesh->Normal[3*i1+0]+=n[0]; Mesh->Normal[3*i1+1]+=n[1]; Mesh->Normal[3*i1+2]+=n[2]; Mesh->Normal[3*i2+0]+=n[0]; Mesh->Normal[3*i2+1]+=n[1]; Mesh->Normal[3*i2+2]+=n[2]; Mesh->Normal[3*i3+0]+=n[0]; Mesh->Normal[3*i3+1]+=n[1]; Mesh->Normal[3*i3+2]+=n[2]; } return; } indexArray(&VertexIndex, (char *)Mesh->Vertex, sizeof(float)*3, Mesh->NumVertex, (sortFunc_t)ComparePosition); TriangleRefs=(long (*)[32])malloc(sizeof(long)*32*VertexIndex.count); if(TriangleRefs==NULL) return; memset(TriangleRefs, 0, sizeof(long)*32*VertexIndex.count); for(i=0;i<Mesh->NumFace;i++) { Vertex=indexFind(&VertexIndex, &Mesh->Vertex[3*Mesh->Face[3*i+0]], &Result); if(TriangleRefs[Vertex][0]<48) { TriangleRefs[Vertex][0]++; TriangleRefs[Vertex][TriangleRefs[Vertex][0]]=i; } Vertex=indexFind(&VertexIndex, &Mesh->Vertex[3*Mesh->Face[3*i+1]], &Result); if(TriangleRefs[Vertex][0]<48) { TriangleRefs[Vertex][0]++; TriangleRefs[Vertex][TriangleRefs[Vertex][0]]=i; } Vertex=indexFind(&VertexIndex, &Mesh->Vertex[3*Mesh->Face[3*i+2]], &Result); if(TriangleRefs[Vertex][0]<48) { TriangleRefs[Vertex][0]++; TriangleRefs[Vertex][TriangleRefs[Vertex][0]]=i; } } FaceTangent=(float *)malloc(sizeof(float)*3*Mesh->NumFace); if(FaceTangent==NULL) return; memset(FaceTangent, 0, sizeof(float)*3*Mesh->NumFace); FaceBinormal=(float *)malloc(sizeof(float)*3*Mesh->NumFace); if(FaceBinormal==NULL) return; memset(FaceBinormal, 0, sizeof(float)*3*Mesh->NumFace); FaceNormal=(float *)malloc(sizeof(float)*3*Mesh->NumFace); if(FaceNormal==NULL) return; memset(FaceNormal, 0, sizeof(float)*3*Mesh->NumFace); for(i=0;i<Mesh->NumFace;i++) { unsigned short i1=Mesh->Face[3*i+0]; unsigned short i2=Mesh->Face[3*i+1]; unsigned short i3=Mesh->Face[3*i+2]; v0[0]=Mesh->Vertex[3*i2+0]-Mesh->Vertex[3*i1+0]; v0[1]=Mesh->Vertex[3*i2+1]-Mesh->Vertex[3*i1+1]; v0[2]=Mesh->Vertex[3*i2+2]-Mesh->Vertex[3*i1+2]; uv0[0]=Mesh->UV[2*i2+0]-Mesh->UV[2*i1+0]; uv0[1]=Mesh->UV[2*i2+1]-Mesh->UV[2*i1+1]; v1[0]=Mesh->Vertex[3*i3+0]-Mesh->Vertex[3*i1+0]; v1[1]=Mesh->Vertex[3*i3+1]-Mesh->Vertex[3*i1+1]; v1[2]=Mesh->Vertex[3*i3+2]-Mesh->Vertex[3*i1+2]; uv1[0]=Mesh->UV[2*i3+0]-Mesh->UV[2*i1+0]; uv1[1]=Mesh->UV[2*i3+1]-Mesh->UV[2*i1+1]; r=1.0f/(uv0[0]*uv1[1]-uv1[0]*uv0[1]); FaceTangent[3*i+0]=(uv1[1]*v0[0]-uv0[1]*v1[0])*r; FaceTangent[3*i+1]=(uv1[1]*v0[1]-uv0[1]*v1[1])*r; FaceTangent[3*i+2]=(uv1[1]*v0[2]-uv0[1]*v1[2])*r; Normalize(&FaceTangent[3*i]); FaceBinormal[3*i+0]=-(uv0[0]*v1[0]-uv1[0]*v0[0])*r; FaceBinormal[3*i+1]=-(uv0[0]*v1[1]-uv1[0]*v0[1])*r; FaceBinormal[3*i+2]=-(uv0[0]*v1[2]-uv1[0]*v0[2])*r; Normalize(&FaceBinormal[3*i]); Cross(v0, v1, &FaceNormal[3*i]); Normalize(&FaceNormal[3*i]); } for(i=0;i<Mesh->NumFace;i++) { for(j=0;j<3;j++) { Vertex=indexFind(&VertexIndex, (void *)&Mesh->Vertex[3*Mesh->Face[3*i+j]], &Result); Count=0; for(k=1;k<=TriangleRefs[Vertex][0];k++) { if(Mesh->Smooth[i]==Mesh->Smooth[TriangleRefs[Vertex][k]]) { Mesh->Tangent[3*Mesh->Face[3*i+j]+0]+=FaceTangent[3*TriangleRefs[Vertex][k]+0]; Mesh->Tangent[3*Mesh->Face[3*i+j]+1]+=FaceTangent[3*TriangleRefs[Vertex][k]+1]; Mesh->Tangent[3*Mesh->Face[3*i+j]+2]+=FaceTangent[3*TriangleRefs[Vertex][k]+2]; Mesh->Binormal[3*Mesh->Face[3*i+j]+0]+=FaceBinormal[3*TriangleRefs[Vertex][k]+0]; Mesh->Binormal[3*Mesh->Face[3*i+j]+1]+=FaceBinormal[3*TriangleRefs[Vertex][k]+1]; Mesh->Binormal[3*Mesh->Face[3*i+j]+2]+=FaceBinormal[3*TriangleRefs[Vertex][k]+2]; Mesh->Normal[3*Mesh->Face[3*i+j]+0]+=FaceNormal[3*TriangleRefs[Vertex][k]+0]; Mesh->Normal[3*Mesh->Face[3*i+j]+1]+=FaceNormal[3*TriangleRefs[Vertex][k]+1]; Mesh->Normal[3*Mesh->Face[3*i+j]+2]+=FaceNormal[3*TriangleRefs[Vertex][k]+2]; Count++; } } Mesh->Tangent[3*Mesh->Face[3*i+j]+0]/=(float)Count; Mesh->Tangent[3*Mesh->Face[3*i+j]+1]/=(float)Count; Mesh->Tangent[3*Mesh->Face[3*i+j]+2]/=(float)Count; Mesh->Binormal[3*Mesh->Face[3*i+j]+0]/=(float)Count; Mesh->Binormal[3*Mesh->Face[3*i+j]+1]/=(float)Count; Mesh->Binormal[3*Mesh->Face[3*i+j]+2]/=(float)Count; Mesh->Normal[3*Mesh->Face[3*i+j]+0]/=(float)Count; Mesh->Normal[3*Mesh->Face[3*i+j]+1]/=(float)Count; Mesh->Normal[3*Mesh->Face[3*i+j]+2]/=(float)Count; } } indexFree(&VertexIndex); for(i=0;i<Mesh->NumVertex;i++) { Normalize(&Mesh->Tangent[3*i]); Normalize(&Mesh->Binormal[3*i]); Normalize(&Mesh->Normal[3*i]); } FREE(TriangleRefs); FREE(FaceTangent); FREE(FaceBinormal); FREE(FaceNormal); }
void MeshManager::CreateDefaultMesh() { unsigned int numVertices = 24; std::unique_ptr<float[]> vertexArray(new float[24 * 3] { // Front face. -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, // Right face. 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, // Back face. 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, // Left face. -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, // Top face. -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // Bottom face. -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f }); std::unique_ptr<float[]> texCoordArray(new float[24 * 2] { // Front face. 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // Right face. 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // Back face. 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // Left face. 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // Top face. 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // Bottom face. 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, }); std::unique_ptr<float[]> normalArray(new float[24 * 3] { // Front face. 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Right face. 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Back face. 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, // Left face. -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // Top face. 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom face. 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f }); std::unique_ptr<uint32_t[]> indexArray(new uint32_t[36] { // Front face. 0, 1, 3, 1, 2, 3, // Right face. 4, 5, 7, 5, 6, 7, // Back face. 8, 9, 11, 9, 10, 11, // Left face. 12, 13, 15, 13, 14, 15, // Top face. 16, 17, 19, 17, 18, 19, // Bottom face. 20, 21, 23, 21, 22, 23 }); m_DefaultMesh = std::unique_ptr<StaticMesh>(new StaticMesh(numVertices, std::move(vertexArray), std::move(texCoordArray), std::move(normalArray), 36, std::move(indexArray))); }
void dgPolygonSoupDatabaseBuilder::Optimize(bool optimize) { #define DG_PATITION_SIZE (1024 * 4) if (optimize && (m_faceCount > DG_PATITION_SIZE)) { dgBigVector median (hacd::HaF32 (0.0f), hacd::HaF32 (0.0f), hacd::HaF32 (0.0f), hacd::HaF32 (0.0f)); dgBigVector varian (hacd::HaF32 (0.0f), hacd::HaF32 (0.0f), hacd::HaF32 (0.0f), hacd::HaF32 (0.0f)); dgStack<dgVector> pool (1024 * 2); dgStack<hacd::HaI32> indexArray (1024 * 2); hacd::HaI32 polygonIndex = 0; for (hacd::HaI32 i = 0; i < m_faceCount; i ++) { dgBigVector p0 (hacd::HaF32 ( 1.0e10f), hacd::HaF32 ( 1.0e10f), hacd::HaF32 ( 1.0e10f), hacd::HaF32 (0.0f)); dgBigVector p1 (hacd::HaF32 (-1.0e10f), hacd::HaF32 (-1.0e10f), hacd::HaF32 (-1.0e10f), hacd::HaF32 (0.0f)); hacd::HaI32 count = m_faceVertexCount[i]; for (hacd::HaI32 j = 1; j < count; j ++) { hacd::HaI32 k = m_vertexIndex[polygonIndex + j]; p0.m_x = GetMin (p0.m_x, hacd::HaF64 (m_vertexPoints[k].m_x)); p0.m_y = GetMin (p0.m_y, hacd::HaF64 (m_vertexPoints[k].m_y)); p0.m_z = GetMin (p0.m_z, hacd::HaF64 (m_vertexPoints[k].m_z)); p1.m_x = GetMax (p1.m_x, hacd::HaF64 (m_vertexPoints[k].m_x)); p1.m_y = GetMax (p1.m_y, hacd::HaF64 (m_vertexPoints[k].m_y)); p1.m_z = GetMax (p1.m_z, hacd::HaF64 (m_vertexPoints[k].m_z)); } dgBigVector p ((p0 + p1).Scale (0.5f)); median += p; varian += p.CompProduct (p); polygonIndex += count; } varian = varian.Scale (hacd::HaF32 (m_faceCount)) - median.CompProduct(median); hacd::HaI32 axis = 0; hacd::HaF32 maxVarian = hacd::HaF32 (-1.0e10f); for (hacd::HaI32 i = 0; i < 3; i ++) { if (varian[i] > maxVarian) { axis = i; maxVarian = hacd::HaF32 (varian[i]); } } dgBigVector center = median.Scale (hacd::HaF32 (1.0f) / hacd::HaF32 (m_faceCount)); hacd::HaF64 axisVal = center[axis]; dgPolygonSoupDatabaseBuilder left; dgPolygonSoupDatabaseBuilder right; left.Begin(); right.Begin(); polygonIndex = 0; for (hacd::HaI32 i = 0; i < m_faceCount; i ++) { hacd::HaI32 side = 0; hacd::HaI32 count = m_faceVertexCount[i]; for (hacd::HaI32 j = 1; j < count; j ++) { hacd::HaI32 k; k = m_vertexIndex[polygonIndex + j]; dgVector p (&m_vertexPoints[k].m_x); if (p[axis] > axisVal) { side = 1; break; } } hacd::HaI32 faceArray = count - 1; hacd::HaI32 faceTagsData = m_vertexIndex[polygonIndex]; for (hacd::HaI32 j = 1; j < count; j ++) { hacd::HaI32 k = m_vertexIndex[polygonIndex + j]; pool[j - 1] = m_vertexPoints[k]; indexArray[j - 1] = j - 1; } if (!side) { left.AddMesh (&pool[0].m_x, count - 1, sizeof (dgVector), 1, &faceArray, &indexArray[0], &faceTagsData, dgGetIdentityMatrix()); } else { right.AddMesh (&pool[0].m_x, count - 1, sizeof (dgVector), 1, &faceArray, &indexArray[0], &faceTagsData, dgGetIdentityMatrix()); } polygonIndex += count; } left.Optimize(optimize); right.Optimize(optimize); m_faceCount = 0; m_indexCount = 0; m_vertexCount = 0; m_normalCount = 0; polygonIndex = 0; for (hacd::HaI32 i = 0; i < left.m_faceCount; i ++) { hacd::HaI32 count = left.m_faceVertexCount[i]; hacd::HaI32 faceArray = count - 1; hacd::HaI32 faceTagsData = left.m_vertexIndex[polygonIndex]; for (hacd::HaI32 j = 1; j < count; j ++) { hacd::HaI32 k = left.m_vertexIndex[polygonIndex + j]; pool[j - 1] = left.m_vertexPoints[k]; indexArray[j - 1] = j - 1; } AddMesh (&pool[0].m_x, count - 1, sizeof (dgVector), 1, &faceArray, &indexArray[0], &faceTagsData, dgGetIdentityMatrix()); polygonIndex += count; } polygonIndex = 0; for (hacd::HaI32 i = 0; i < right.m_faceCount; i ++) { hacd::HaI32 count = right.m_faceVertexCount[i]; hacd::HaI32 faceArray = count - 1; hacd::HaI32 faceTagsData = right.m_vertexIndex[polygonIndex]; for (hacd::HaI32 j = 1; j < count; j ++) { hacd::HaI32 k = right.m_vertexIndex[polygonIndex + j]; pool[j - 1] = right.m_vertexPoints[k]; indexArray[j - 1] = j - 1; } AddMesh (&pool[0].m_x, count - 1, sizeof (dgVector), 1, &faceArray, &indexArray[0], &faceTagsData, dgGetIdentityMatrix()); polygonIndex += count; } if (m_faceCount < DG_PATITION_SIZE) { EndAndOptimize(optimize); } else { EndAndOptimize(false); } } else { EndAndOptimize(optimize); } }
dgCollisionDeformableMesh::dgCollisionDeformableMesh(dgWorld* const world, dgMeshEffect* const mesh, dgCollisionID collsionID) :dgCollisionConvex (mesh->GetAllocator(), 0, collsionID) ,m_particles (mesh->GetVertexCount ()) ,m_visualSegments(mesh->GetAllocator()) ,m_skinThickness(DG_DEFORMABLE_DEFAULT_SKIN_THICKNESS) ,m_nodesCount(0) ,m_trianglesCount(0) ,m_visualVertexCount(0) ,m_world (world) ,m_myBody(NULL) ,m_indexList(NULL) ,m_faceNormals(NULL) ,m_rootNode(NULL) ,m_nodesMemory(NULL) ,m_visualVertexData(NULL) ,m_onDebugDisplay(NULL) ,m_isdoubleSided(false) { m_rtti |= dgCollisionDeformableMesh_RTTI; dgDeformableBodiesUpdate& softBodyList = *m_world; softBodyList.AddShape (this); dgMeshEffect meshCopy (*mesh); meshCopy.Triangulate(); m_trianglesCount = meshCopy.GetTotalFaceCount (); m_nodesMemory = (dgDeformableNode*) dgMallocStack((m_trianglesCount * 2 - 1) * sizeof (dgDeformableNode)); m_indexList = (dgInt32*) dgMallocStack (3 * m_trianglesCount * sizeof (dgInt32)); m_faceNormals = (dgVector*) dgMallocStack (m_trianglesCount * sizeof (dgVector)); dgInt32 stride = meshCopy.GetVertexStrideInByte() / sizeof (dgFloat64); dgFloat64* const vertex = meshCopy.GetVertexPool(); for (dgInt32 i = 0; i < m_particles.m_count; i ++) { m_particles.m_unitMass[i] = dgFloat32 (1.0f); m_particles.m_veloc[i] = dgVector (dgFloat32 (0.0f)); m_particles.m_posit[i] = dgVector (&vertex[i * stride]) & dgVector::m_triplexMask; } dgInt32 indexCount = meshCopy.GetTotalIndexCount (); dgStack<dgInt32> faceArray (m_trianglesCount); dgStack<dgInt32> materials (m_trianglesCount); dgStack<void*>indexArray (indexCount); meshCopy.GetFaces (&faceArray[0], &materials[0], &indexArray[0]); for (dgInt32 i = 0; i < m_trianglesCount; i ++) { dgInt32 count = faceArray[i]; dgAssert (faceArray[i]); for (dgInt32 j = 0; j < count; j ++) { dgInt32 k = meshCopy.GetVertexIndex(indexArray[i * 3 + j]); m_indexList[i * 3 + j] = k; } //dgTrace (("%d %d %d\n", m_indexList[i * 3 + 0], m_indexList[i * 3 + 1], m_indexList[i * 3 + 2])); dgDeformableNode& node = m_nodesMemory[i]; node.m_left = NULL; node.m_right = NULL; node.m_parent = NULL; node.m_indexStart = i * 3; node.CalculateBox(m_particles.m_posit, &m_indexList[i * 3]); } m_nodesCount = m_trianglesCount; m_rootNode = BuildTopDown (m_nodesCount, m_nodesMemory, NULL); ImproveTotalFitness(); SetCollisionBBox (m_rootNode->m_minBox, m_rootNode->m_maxBox); // create visual vertex data m_visualVertexCount = meshCopy.GetPropertiesCount(); m_visualVertexData = (dgVisualVertexData*) dgMallocStack(m_visualVertexCount * sizeof (dgVisualVertexData)); for (dgInt32 i = 0; i < m_visualVertexCount; i ++) { dgMeshEffect::dgVertexAtribute& attribute = meshCopy.GetAttribute (i); m_visualVertexData[i].m_uv0[0] = dgFloat32 (attribute.m_u0); m_visualVertexData[i].m_uv0[1] = dgFloat32 (attribute.m_v0); } for (void* point = meshCopy.GetFirstPoint(); point; point = meshCopy.GetNextPoint(point)) { dgInt32 pointIndex = meshCopy.GetPointIndex (point); dgInt32 vertexIndex = meshCopy.GetVertexIndexFromPoint (point); m_visualVertexData[pointIndex].m_vertexIndex = vertexIndex; } for (dgInt32 i = 0; i < m_trianglesCount; i ++) { dgInt32 mat = materials[i]; if (mat != -1) { dgInt32 count = 0; for (dgInt32 j = i; j < m_trianglesCount; j ++) { dgInt32 mat1 = materials[j]; if (mat == mat1) { materials[j] = -1; count ++; } } dgMeshSegment& segment = m_visualSegments.Append()->GetInfo(); segment.m_material = mat; segment.m_indexCount = count * 3; segment.m_indexList = (dgInt32*) dgMallocStack( 2 * segment.m_indexCount * sizeof (dgInt32)); dgInt32 index0 = 0; dgInt32 index1 = m_trianglesCount * 3; for (dgInt32 j = i; j < m_trianglesCount; j ++) { if (materials[j] == -1) { dgInt32 m0 = meshCopy.GetPointIndex(indexArray[j * 3 + 0]); dgInt32 m1 = meshCopy.GetPointIndex(indexArray[j * 3 + 1]); dgInt32 m2 = meshCopy.GetPointIndex(indexArray[j * 3 + 2]); segment.m_indexList[index0 + 0] = dgInt16 (m0); segment.m_indexList[index0 + 1] = dgInt16 (m1); segment.m_indexList[index0 + 2] = dgInt16 (m2); index0 += 3; segment.m_indexList[index1 + 0] = dgInt16 (m0); segment.m_indexList[index1 + 1] = dgInt16 (m2); segment.m_indexList[index1 + 2] = dgInt16 (m1); index1 += 3; } } } } // SetVolumeAndCG (); }
void CopyTensorPotentialToEpetraMatrix(Epetra_FECrsMatrix_Ptr epetraMatrix, blitz::Array<cplx, Rank> potentialData, list pyLocalBasisPairs, blitz::TinyVector<int, Rank> globalStrides, double cutoff) { blitz::Array<int, 2> indexArray; indexArray.resize(4 * potentialData.size(), 2); indexArray = -100; double sqrCutoff = sqr(cutoff); //Setup structures for calculating matrix row/col indices from the //basis pairs in the tensor potential blitz::TinyVector< blitz::Array<int, 2>, Rank > localBasisPairs; for (int rank=0; rank<Rank; rank++) { localBasisPairs(rank).reference( boost::python::extract< blitz::Array<int, 2> >(pyLocalBasisPairs[rank]) ); } //Iterate over all items in potentialData typename blitz::Array<cplx, Rank>::iterator it = potentialData.begin(); for (int linearCount=0; linearCount<potentialData.size(); linearCount++) { int globalRow = 0; int globalCol = 0; for (int rank=0; rank<Rank; rank++) { int rankPos = it.position()(rank); globalRow += globalStrides(rank) * localBasisPairs(rank)(rankPos, 0); globalCol += globalStrides(rank) * localBasisPairs(rank)(rankPos, 1); } double realVal = real(*it); double imagVal = imag(*it); //Skip padded elements (they have negative row/col index) if ((globalRow < 0) || (globalCol < 0)) { it++; continue; } /* * Because epetra does not support complex natively, * each matrix element is a 2x2 block * * (A_r -A_i ) (c_r) = (A_r + i A_i) * (c_r + i c_i) = A * c * (A_i A_r ) (c_i) * * Detect if A_i or A_r is zero to avoid redundant elements */ //Insert values into matrix if (sqr(realVal) > sqrCutoff) { int r,c; r = 2*globalRow; c = 2*globalCol; indexArray(4*linearCount, 0) = r; indexArray(4*linearCount, 1) = c; epetraMatrix->InsertGlobalValues(r, 1, &realVal, &c); r++; c++; epetraMatrix->InsertGlobalValues(r, 1, &realVal, &c); indexArray(4*linearCount+1, 0) = r; indexArray(4*linearCount+1, 1) = c; } if (sqr(imagVal) > sqrCutoff) { int r,c; //Upper row, A_i with minus sign r = 2*globalRow; c = 2*globalCol+1; indexArray(4*linearCount+2, 0) = r; indexArray(4*linearCount+2, 1) = c; imagVal = -imagVal; epetraMatrix->InsertGlobalValues(r, 1, &imagVal, &c); //Lower row, A_i without minus sign imagVal = -imagVal; epetraMatrix->InsertGlobalValues(c, 1, &imagVal, &r); indexArray(4*linearCount+3, 0) = c; indexArray(4*linearCount+3, 1) = r; } ++it; } }