Beispiel #1
0
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();
		}
	}
Beispiel #4
0
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 ();
}
Beispiel #8
0
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;	
	}
}