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