Physics_Cloth::~Physics_Cloth()
{
	// Release allocated memory
	ReleasePtr(m_pMesh);
	ReleasePtrArray(m_pParticles);
}
bool Physics_Cloth::ResetCloth()
{
	// Clear Memory
	ReleaseCloth();
	ReleaseSelected();
	m_contraints.clear();
	m_nextIndex = 0;

	if (m_initialisedParticles == false)
	{
		ReleasePtr(m_pMesh);
		ReleasePtrArray(m_pParticles);

		// Create memory for all the particles
		m_particleCount = m_particlesWidthCount * m_particlesHeightCount;
		m_pParticles = new Physics_Particle[m_particleCount];
		m_pVertices = new TVertexColor[m_particleCount];		

		// Calculate how many indices there are with be based on how many particles there are using line list
		int immediateConstraintCount = (m_particlesWidthCount - 1) * (m_particlesHeightCount - 1) * 4 + (m_particlesWidthCount - 1) + (m_particlesHeightCount - 1);
		int secondaryConstraintCount = 0;
		if (m_complexWeave == true)
		{
			// Calculate the secondary indices count only if the weave is set to complex
			secondaryConstraintCount = (m_particlesWidthCount - 2) * (m_particlesHeightCount - 2) * 4 + ((m_particlesWidthCount - 2) * 2) + ((m_particlesHeightCount - 2) * 2);
		}
		
		// Create the indices buffer with the amount of calculated constraints
		m_indexCount = (immediateConstraintCount + secondaryConstraintCount) * 2;
		m_pIndices = new DWORD[m_indexCount];
	}
	
	// Cycle through all the particles
	for (int col = 0; col < m_particlesWidthCount; col++)
	{
		for (int row = 0; row < m_particlesHeightCount; row++)
		{
			// Calculate the position based on the particles row and column
			v3float pos;
			pos.x = m_width * (col / (float)m_width) - ((float)m_width / 2.0f);
			pos.y = -m_height * (row / (float)m_height) + ((float)m_height / 2.0f);
			pos.z = 0.0f;
			int index = row * m_particlesWidthCount + col;

			if (m_initialisedParticles == false)
			{
				// First time. Initialise			
				m_pVertices[index] = { { pos.x, pos.y, pos.z }, d3dxColors::White };
				VALIDATE(m_pParticles[index].Initialise(index, &m_pVertices[index], pos, m_timeStep, m_damping));
			}
			else
			{
				// Particle has already been initialized so just reset the position
				m_pParticles[index].Reset();
				m_pParticles[index].SetPosition(pos, true);
				m_pVertices[index].color = d3dxColors::White;
			}
		}
	}

	// Connect Particles that are immediately to the right and below (include diagonals)
	for (int col = 0; col < m_particlesWidthCount; col++)
	{
		for (int row = 0; row < m_particlesHeightCount; row++)
		{
			// Particle to the Right exists
			if (col < m_particlesWidthCount - 1)
			{
				VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 1, row), true));
				
				// Add the constraint index to each attached particle
				GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col + 1, row)->AddContraintIndex(m_contraints.size() - 1);
			}
	
			// Particle below exists
			if (row < m_particlesHeightCount - 1)
			{
				VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col, row + 1), true));

				// Add the constraint index to each attached particle
				GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col, row + 1)->AddContraintIndex(m_contraints.size() - 1);
			}
	
			// Particle to the right and below exists
			if ((col < m_particlesWidthCount - 1) && (row < m_particlesHeightCount - 1))
			{
				VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 1, row + 1), true));

				// Add the constraint index to each attached particle
				GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col + 1, row + 1)->AddContraintIndex(m_contraints.size() - 1);

				VALIDATE(MakeConstraint(GetParticleIndex(col + 1, row), GetParticleIndex(col, row + 1), true));

				// Add the constraint index to each attached particle
				GetParticle(col + 1, row)->AddContraintIndex(m_contraints.size() - 1);
				GetParticle(col, row + 1)->AddContraintIndex(m_contraints.size() - 1);
			}
		}
	}

	if (m_complexWeave == true)
	{
		// Connect Particles the are one step further away than previous loop
		for (int col = 0; col < m_particlesWidthCount; col++)
		{
			for (int row = 0; row < m_particlesHeightCount; row++)
			{
				// Particle to the Right exists
				if (col < m_particlesWidthCount - 2)
				{
					VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 2, row), false));

					// Add the constraint index to each attached particle
					GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col + 2, row)->AddContraintIndex(m_contraints.size() - 1);
				}

				// Particle below exists
				if (row < m_particlesHeightCount - 2)
				{
					VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col, row + 2), false));

					// Add the constraint index to each attached particle
					GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col, row + 2)->AddContraintIndex(m_contraints.size() - 1);
				}

				// Particle to the right and below exists
				if ((col < m_particlesWidthCount - 2) && (row < m_particlesHeightCount - 2))
				{
					VALIDATE(MakeConstraint(GetParticleIndex(col, row), GetParticleIndex(col + 2, row + 2), false));

					// Add the constraint index to each attached particle
					GetParticle(col, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col + 2, row + 2)->AddContraintIndex(m_contraints.size() - 1);

					VALIDATE(MakeConstraint(GetParticleIndex(col + 2, row), GetParticleIndex(col, row + 2), false));

					// Add the constraint index to each attached particle
					GetParticle(col + 2, row)->AddContraintIndex(m_contraints.size() - 1);
					GetParticle(col, row + 2)->AddContraintIndex(m_contraints.size() - 1);
				}
			}
		}
	}
	
	if (m_initialisedParticles == false)
	{
		// Create a new Cloth Mesh
		m_pMesh = new DX10_Mesh();
		VALIDATE(m_pMesh->InitialiseCloth(m_pRenderer, m_pVertices, m_pIndices, m_particleCount, m_indexCount, sizeof(TVertexColor), D3D10_PRIMITIVE_TOPOLOGY_LINELIST, D3D10_USAGE_DYNAMIC, D3D10_USAGE_DYNAMIC));
	}

	// Create the hooks and pin the cloth
	CreateHooks();

	// Add a wind force of 1 down the Z axis to settle the cloth
	AddForce({ 0.0f, 0.0f, 1.0f }, FT_GENERIC, false);
	Process(CT_NONE);

	m_initialisedParticles = true;
	return true;
}
Beispiel #3
0
void Glulxe::unparse_glk_args(dispatch_splot_t *splot, const char **proto, int depth,
                              int *argnumptr, uint subaddress, int subpassout) {
	const char *cx;
	int ix, argx;
	int gargnum, numwanted;
	void *opref;
	gluniversal_t *garglist;
	uint *varglist;

	garglist = splot->garglist;
	varglist = splot->varglist;
	gargnum = *argnumptr;
	cx = *proto;

	numwanted = 0;
	while (*cx >= '0' && *cx <= '9') {
		numwanted = 10 * numwanted + (*cx - '0');
		cx++;
	}

	for (argx = 0, ix = 0; argx < numwanted; argx++, ix++) {
		char typeclass;
		int skipval;
		int isref, passin, passout, nullok, isarray, isretained, isreturn;
		cx = read_prefix(cx, &isref, &isarray, &passin, &passout, &nullok,
		                 &isretained, &isreturn);

		typeclass = *cx;
		cx++;

		skipval = false;
		if (isref) {
			if (!isreturn && varglist[ix] == 0) {
				if (!nullok)
					error("Zero passed invalidly to Glk function.");
				garglist[gargnum]._ptrflag = false;
				gargnum++;
				skipval = true;
			} else {
				garglist[gargnum]._ptrflag = true;
				gargnum++;
			}
		}
		if (!skipval) {
			uint thisval = 0;

			if (typeclass == '[') {

				unparse_glk_args(splot, &cx, depth + 1, &gargnum, varglist[ix], passout);

			} else if (isarray) {
				/* definitely isref */

				switch (typeclass) {
				case 'C':
					ReleaseCArray((char *)garglist[gargnum]._array, varglist[ix], varglist[ix + 1], passout);
					gargnum++;
					ix++;
					gargnum++;
					cx++;
					break;
				case 'I':
					ReleaseIArray((uint *)garglist[gargnum]._array, varglist[ix], varglist[ix + 1], passout);
					gargnum++;
					ix++;
					gargnum++;
					cx++;
					break;
				case 'Q':
					ReleasePtrArray((void **)garglist[gargnum]._array, varglist[ix], varglist[ix + 1], (*cx - 'a'), passout);
					gargnum++;
					ix++;
					gargnum++;
					cx++;
					break;
				default:
					error("Illegal format string.");
					break;
				}
			} else {
				/* a plain value or a reference to one. */

				if (isreturn || (depth > 0 && subpassout) || (isref && passout)) {
					skipval = false;
				} else {
					skipval = true;
				}

				switch (typeclass) {
				case 'I':
					if (!skipval) {
						if (*cx == 'u')
							thisval = (uint)garglist[gargnum]._uint;
						else if (*cx == 's')
							thisval = (uint)garglist[gargnum]._sint;
						else
							error("Illegal format string.");
					}
					gargnum++;
					cx++;
					break;
				case 'Q':
					if (!skipval) {
						opref = garglist[gargnum]._opaqueref;
						if (opref) {
							gidispatch_rock_t objrock = gidispatch_get_objrock(opref, *cx - 'a');
							assert(objrock.ptr);
							thisval = ((classref_t *)objrock.ptr)->id;
						} else {
							thisval = 0;
						}
					}
					gargnum++;
					cx++;
					break;
				case 'C':
					if (!skipval) {
						if (*cx == 'u')
							thisval = (uint)garglist[gargnum]._uch;
						else if (*cx == 's')
							thisval = (uint)garglist[gargnum]._sch;
						else if (*cx == 'n')
							thisval = (uint)garglist[gargnum]._ch;
						else
							error("Illegal format string.");
					}
					gargnum++;
					cx++;
					break;
				case 'S':
					if (garglist[gargnum]._charstr)
						ReleaseVMString(garglist[gargnum]._charstr);
					gargnum++;
					break;
#ifdef GLK_MODULE_UNICODE
				case 'U':
					if (garglist[gargnum]._unicharstr)
						ReleaseVMUstring(garglist[gargnum]._unicharstr);
					gargnum++;
					break;
#endif /* GLK_MODULE_UNICODE */
				default:
					error("Illegal format string.");
					break;
				}

				if (isreturn) {
					*(splot->retval) = thisval;
				} else if (depth > 0) {
					/* Definitely not isref or isarray. */
					if (subpassout)
						WriteStructField(subaddress, ix, thisval);
				} else if (isref) {
					if (passout)
						WriteMemory(varglist[ix], thisval);
				}
			}
		} else {
			/* We got a null reference, so we have to skip the format element. */
			if (typeclass == '[') {
				int numsubwanted, refdepth;
				numsubwanted = 0;
				while (*cx >= '0' && *cx <= '9') {
					numsubwanted = 10 * numsubwanted + (*cx - '0');
					cx++;
				}
				refdepth = 1;
				while (refdepth > 0) {
					if (*cx == '[')
						refdepth++;
					else if (*cx == ']')
						refdepth--;
					cx++;
				}
			} else if (typeclass == 'S' || typeclass == 'U') {
				/* leave it */
			} else {
				cx++;
				if (isarray)
					ix++;
			}
		}
	}

	if (depth > 0) {
		if (*cx != ']')
			error("Illegal format string.");
		cx++;
	} else {
		if (*cx != ':' && *cx != '\0')
			error("Illegal format string.");
	}

	*proto = cx;
	*argnumptr = gargnum;
}