//implementing postprocessing to every group of movable points void Cloth::handle_slop_connected( const std::vector<int>& edgePoints, const std::vector<XY>& connected, const std::vector< std::vector<int> >& neibors, const std::vector<double>& heightvals) { std::vector<bool> visited(connected.size(), false); std::queue<int> que; for (size_t i = 0; i < edgePoints.size(); i++) { que.push(edgePoints[i]); visited[edgePoints[i]] = true; } while (!que.empty()) { int index = que.front(); que.pop(); //ÅжÏÖܱߵãÊÇ·ñÐèÒª´¦Àí int index_center = connected[index].y*num_particles_width + connected[index].x; for (size_t i = 0; i < neibors[index].size(); i++) { int index_neibor = connected[neibors[index][i]].y*num_particles_width + connected[neibors[index][i]].x; if (fabs(heightvals[index_center] - heightvals[index_neibor]) < smoothThreshold && fabs(particles[index_neibor].pos.y - heightvals[index_neibor]) < heightThreshold) { Vec3 offsetVec(0, heightvals[index_neibor] - particles[index_neibor].pos.y, 0); particles[index_neibor].offsetPos(offsetVec); particles[index_neibor].makeUnmovable(); if (visited[neibors[index][i]] == false) { que.push(neibors[index][i]); visited[neibors[index][i]] = true; } } } } }
END_CLASS /* ================ idAI_Vagary::Event_ChooseObjectToThrow ================ */ void idAI_Vagary::Event_ChooseObjectToThrow( const idVec3 &mins, const idVec3 &maxs, float speed, float minDist, float offset ) { idEntity * ent; idEntity * entityList[ MAX_GENTITIES ]; int numListedEntities; int i, index; float dist; idVec3 vel; idVec3 offsetVec( 0, 0, offset ); idEntity *enemyEnt = enemy.GetEntity(); if ( !enemyEnt ) { idThread::ReturnEntity( NULL ); } idVec3 enemyEyePos = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset; const idBounds &myBounds = physicsObj.GetAbsBounds(); idBounds checkBounds( mins, maxs ); checkBounds.TranslateSelf( physicsObj.GetOrigin() ); numListedEntities = gameLocal.clip.EntitiesTouchingBounds( checkBounds, -1, entityList, MAX_GENTITIES ); index = gameLocal.random.RandomInt( numListedEntities ); for ( i = 0; i < numListedEntities; i++, index++ ) { if ( index >= numListedEntities ) { index = 0; } ent = entityList[ index ]; if ( !ent->IsType( idMoveable::Type ) ) { continue; } if ( ent->fl.hidden ) { // don't throw hidden objects continue; } idPhysics *entPhys = ent->GetPhysics(); const idVec3 &entOrg = entPhys->GetOrigin(); dist = ( entOrg - enemyEyePos ).LengthFast(); if ( dist < minDist ) { continue; } idBounds expandedBounds = myBounds.Expand( entPhys->GetBounds().GetRadius() ); if ( expandedBounds.LineIntersection( entOrg, enemyEyePos ) ) { // ignore objects that are behind us continue; } if ( PredictTrajectory( entPhys->GetOrigin() + offsetVec, enemyEyePos, speed, entPhys->GetGravity(), entPhys->GetClipModel(), entPhys->GetClipMask(), MAX_WORLD_SIZE, NULL, enemyEnt, ai_debugTrajectory.GetBool() ? 4000 : 0, vel ) ) { idThread::ReturnEntity( ent ); return; } } idThread::ReturnEntity( NULL ); }
void Cloth::findUnmovablePoint( const std::vector<XY>& connected, const std::vector<double>& heightvals, std::vector<int>& edgePoints) { for (size_t i = 0; i < connected.size(); i++) { int x = connected[i].x; int y = connected[i].y; int index = y*num_particles_width + x; Particle& ptc = getParticle(x, y); if (x > 0) { const Particle& ptc_x = getParticle(x - 1, y); if (!ptc_x.isMovable()) { int index_ref = y*num_particles_width + x - 1; if (fabs(heightvals[index] - heightvals[index_ref]) < smoothThreshold && ptc.pos.y - heightvals[index] < heightThreshold) { Vec3 offsetVec(0, heightvals[index] - ptc.pos.y, 0); particles[index].offsetPos(offsetVec); ptc.makeUnmovable(); edgePoints.push_back(static_cast<int>(i)); continue; } } } if (x < num_particles_width - 1) { const Particle& ptc_x = getParticle(x + 1, y); if (!ptc_x.isMovable()) { int index_ref = y*num_particles_width + x + 1; if (fabs(heightvals[index] - heightvals[index_ref]) < smoothThreshold && ptc.pos.y - heightvals[index] < heightThreshold) { Vec3 offsetVec(0, heightvals[index] - ptc.pos.y, 0); particles[index].offsetPos(offsetVec); ptc.makeUnmovable(); edgePoints.push_back(static_cast<int>(i)); continue; } } } if (y > 0) { const Particle& ptc_y = getParticle(x, y - 1); if (!ptc_y.isMovable()) { int index_ref = (y - 1)*num_particles_width + x; if (fabs(heightvals[index] - heightvals[index_ref]) < smoothThreshold && ptc.pos.y - heightvals[index] < heightThreshold) { Vec3 offsetVec(0, heightvals[index] - ptc.pos.y, 0); particles[index].offsetPos(offsetVec); ptc.makeUnmovable(); edgePoints.push_back(static_cast<int>(i)); continue; } } } if (y < num_particles_height - 1) { const Particle& ptc_y = getParticle(x, y + 1); if (!ptc_y.isMovable()) { int index_ref = (y + 1)*num_particles_width + x; if (fabs(heightvals[index] - heightvals[index_ref]) < smoothThreshold && ptc.pos.y - heightvals[index] < heightThreshold) { Vec3 offsetVec(0, heightvals[index] - ptc.pos.y, 0); particles[index].offsetPos(offsetVec); ptc.makeUnmovable(); edgePoints.push_back(static_cast<int>(i)); continue; } } } } }