PhysX SDK 3.2 - A simple cloth

Hi guys, I’m new to the forums, so I’ll try and fit in.

I’m currently having this issue with a basic cloth, the actual setup of Physx works fine, as I’m able to create some simple bouncing boxes, so it’s another issue. What happens is that the cloth i create basically flickers all the time (visually) for some weird reason, I suspect that the setup isn’t correct, though I might be wrong.

What I have so far: (Please keep in mind that the purpose of this piece of code isn’t optimization yet…)

PhysicalMeshes.push_back(CEPHYSICSHOLDER());

	PxClothMeshDesc clothDesc;
	clothDesc.setToDefault();

	clothDesc.points.count = mesh->VertexCount;        
	clothDesc.points.stride = sizeof(PxClothParticle);  
	clothDesc.points.data= (PxClothParticle*)malloc(sizeof(PxClothParticle)*mesh->VertexCount);    

	clothDesc.triangles.count = mesh->IndexCount/3;  
	clothDesc.triangles.stride = 3*sizeof(PxU32);  
	clothDesc.triangles.data= (PxU32*)malloc(sizeof(PxU32)*mesh->IndexCount);

	clothDesc.edgeFlags = 0;

	PxClothParticle* Vertices = (PxClothParticle*)clothDesc.points.data;
	PxU32* Indices = (PxU32*)clothDesc.triangles.data;

	until(mesh->VertexCount)
	{
		PxClothParticle p;
		p.pos = PxVec3(mesh->Vertices[i].X, mesh->Vertices[i].Y, mesh->Vertices[i].Z);
		p.invWeight = 1.0f/1.0f;

		Vertices[i] = p;
	}

	until(mesh->IndexCount)
		Indices[i] = PxU32(mesh->Indices[i]);

	//Make sure everything is fine so far
	if(!(clothDesc.isValid()))
		CE_ERROR("Mesh invalid", "Fatal Error");

	PxTransform transform( PxVec3(mesh->position.x, mesh->position.y, mesh->position.z), PxQuat::createIdentity());

	PxToolkit::MemoryOutputStream buf;
	bool status = mCooking->cookClothFabric(clothDesc, PxVec3(0, -1, 0), buf);
	if(!status) {
		CE_ERROR("Px Cooking failed in the creation of cloth", "Fatal Error");
	}

	PxToolkit::MemoryInputData rb(buf.getData(), buf.getSize());
	PxClothFabric* fabric = mPhysics->createClothFabric(rb);

	PxClothCollisionData cd;
	cd.setToDefault();

	cd.numSpheres=1;
	cd.pairIndexBuffer=0;

	PxClothCollisionSphere box_collider;
	box_collider.pos= PxVec3(0.0f,2.0f,0.0f);
	box_collider.radius=1;
	cd.spheres=&box_collider;

	PxCloth* cloth = mPhysics->createCloth(transform,*fabric, Vertices, cd, PxClothFlags());

	if(cloth) { 
		PxClothPhaseSolverConfig bendCfg;  
		bendCfg.solverType= PxClothPhaseSolverConfig::eFAST;
		bendCfg.stiffness = 1;
		bendCfg.stretchStiffness = 0.5; 

		cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eBENDING,  bendCfg) ; 
		cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eSTRETCHING, bendCfg) ; 
		cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eSHEARING, bendCfg) ; 
		cloth->setPhaseSolverConfig(PxClothFabricPhaseType::eSTRETCHING_HORIZONTAL, bendCfg) ;

		cloth->setDampingCoefficient(0.125f);    
		cloth->setSolverFrequency(240.0f);

		mScene->addActor(*cloth); 
	}
	else
	{
		CE_ERROR("Cannot create cloth", "Fatal Error");
	}

	// Prepare the holder
	PhysicalMeshes.back().actor = cloth;
	PhysicalMeshes.back().ptr = mesh;
	PhysicalMeshes.back().isDynamic = true;
	PhysicalMeshes.back().isCloth = true;
	PhysicalMeshes.back().clothSphereCollider = box_collider;

	CEPxActor r;
	r._m_pActor = cloth;
	r._m_pMesh = mesh;

	return r;

And how I update my vertices in the main loop:

//update the cloth data
PxClothReadData* pData = cloth->lockClothReadData();
PxClothParticle* pParticles = const_cast<PxClothParticle*>(pData->particles);

int vCount = mesh->VertexCount;

//update the positions
_until(index, vCount)
{
	PxVec3 pos = pData->particles[index].pos;

	mesh->Vertices[index].X = pos.x;
	mesh->Vertices[index].Y = pos.y;
	mesh->Vertices[index].Z = pos.z;
}
pData->unlock();

//update normals
for(size_t i=0;i < mesh->IndexCount;i+=3) {
	PxVec3 p1 = PxVec3(ToPxVec3(mesh->Vertices[mesh->Indices[i]]));
	PxVec3 p2 = PxVec3(ToPxVec3(mesh->Vertices[mesh->Indices[i+1]]));
	PxVec3 p3 = PxVec3(ToPxVec3(mesh->Vertices[mesh->Indices[i+2]]));
	PxVec3 n  = (p2-p1).cross(p3-p1);

	PxVec3 newNorm = n/3.0f;

	MESH_STRUCT *m = &mesh->Vertices[mesh->Indices[i]];
	MESH_STRUCT *m1 = &mesh->Vertices[mesh->Indices[i+1]];
	MESH_STRUCT *m2 = &mesh->Vertices[mesh->Indices[i+2]];

	m->Normal.x    += newNorm.x/3.0f ; 
	m->Normal.y    += newNorm.y/3.0f ; 
	m->Normal.z    += newNorm.z/3.0f ;  
	m1->Normal.x   += newNorm.x/3.0f ; 
	m1->Normal.y   += newNorm.y/3.0f ; 
	m1->Normal.z   += newNorm.z/3.0f ;  
	m2->Normal.x   += newNorm.x/3.0f ; 
	m2->Normal.y   += newNorm.y/3.0f ; 
	m2->Normal.z   += newNorm.z/3.0f ;  

	D3DXVec3Normalize(&m->Normal, &m->Normal);
	D3DXVec3Normalize(&m1->Normal, &m1->Normal);
	D3DXVec3Normalize(&m2->Normal, &m2->Normal);
}

// Just an internal function for updating the vertex buffer, nothing special here...
CDK::UpdateVertexBuffer(dev, devcon, (CDK::Buffer)mesh->UMeshVBuffer, &mesh->Vertices, mesh->VertexCount);

Could you post a video and a PhysX Visual Debugger capture?
–Mike