void CrowdSim::init() { // Init random generator //srand( (unsigned int)time( NULL ) ); srand( 99777 ); // Use fixed value for better performance comparisons // Load character with walk animation H3DRes characterRes = h3dAddResource( H3DResTypes::SceneGraph, "models/man/man.scene.xml", 0 ); H3DRes characterWalkRes = h3dAddResource( H3DResTypes::Animation, "animations/man.anim", 0 ); h3dutLoadResourcesFromDisk( _contentDir.c_str() ); // Add characters for( unsigned int i = 0; i < 100; ++i ) { Particle p; // Add character to scene and apply animation p.node = h3dAddNodes( H3DRootNode, characterRes ); h3dSetupModelAnimStage( p.node, 0, characterWalkRes, 0, "", false ); // Characters start in a circle formation p.px = sinf( (i / 100.0f) * 6.28f ) * 10.0f; p.pz = cosf( (i / 100.0f) * 6.28f ) * 10.0f; chooseDestination( p ); h3dSetNodeTransform( p.node, p.px, 0.02f, p.pz, 0, 0, 0, 1, 1, 1 ); _particles.push_back( p ); } }
//! [1] ImageComposer::ImageComposer() { sourceButton = new QToolButton; sourceButton->setIconSize(resultSize); operatorComboBox = new QComboBox; addOp(QPainter::CompositionMode_SourceOver, tr("SourceOver")); addOp(QPainter::CompositionMode_DestinationOver, tr("DestinationOver")); addOp(QPainter::CompositionMode_Clear, tr("Clear")); addOp(QPainter::CompositionMode_Source, tr("Source")); addOp(QPainter::CompositionMode_Destination, tr("Destination")); addOp(QPainter::CompositionMode_SourceIn, tr("SourceIn")); addOp(QPainter::CompositionMode_DestinationIn, tr("DestinationIn")); addOp(QPainter::CompositionMode_SourceOut, tr("SourceOut")); addOp(QPainter::CompositionMode_DestinationOut, tr("DestinationOut")); addOp(QPainter::CompositionMode_SourceAtop, tr("SourceAtop")); addOp(QPainter::CompositionMode_DestinationAtop, tr("DestinationAtop")); addOp(QPainter::CompositionMode_Xor, tr("Xor")); //! [1] //! [2] destinationButton = new QToolButton; destinationButton->setIconSize(resultSize); equalLabel = new QLabel(tr("=")); resultLabel = new QLabel; resultLabel->setMinimumWidth(resultSize.width()); //! [2] //! [3] connect(sourceButton, SIGNAL(clicked()), this, SLOT(chooseSource())); connect(operatorComboBox, SIGNAL(activated(int)), this, SLOT(recalculateResult())); connect(destinationButton, SIGNAL(clicked()), this, SLOT(chooseDestination())); //! [3] //! [4] QGridLayout *mainLayout = new QGridLayout; mainLayout->addWidget(sourceButton, 0, 0, 3, 1); mainLayout->addWidget(operatorComboBox, 1, 1); mainLayout->addWidget(destinationButton, 0, 2, 3, 1); mainLayout->addWidget(equalLabel, 1, 3); mainLayout->addWidget(resultLabel, 0, 4, 3, 1); mainLayout->setSizeConstraint(QLayout::SetFixedSize); setLayout(mainLayout); //! [4] //! [5] resultImage = QImage(resultSize, QImage::Format_ARGB32_Premultiplied); loadImage(":/images/butterfly.png", &sourceImage, sourceButton); loadImage(":/images/checker.png", &destinationImage, destinationButton); setWindowTitle(tr("Image Composition")); }
int ImageComposer::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QWidget::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: chooseSource(); break; case 1: chooseDestination(); break; case 2: recalculateResult(); break; default: ; } _id -= 3; } return _id; }
void CrowdSim::update( float fps ) { // Parameters for three repulsion zones float d1 = 0.25f, d2 = 2.0f, d3 = 4.5f; float f1 = 3.0f, f2 = 1.0f, f3 = 0.1f; for( unsigned int i = 0; i < _particles.size(); ++i ) { Particle &p = _particles[i]; // Reset force p.fx = 0; p.fz = 0; // Calculate distance to destination float dist = sqrtf( (p.dx - p.px)*(p.dx - p.px) + (p.dz - p.pz)*(p.dz - p.pz) ); // If destination not reached walk to destination if( dist > 3.0f ) { // Calculate normalized attraction force to destination float afx = (p.dx - p.px) / dist; float afz = (p.dz - p.pz) / dist; p.fx += afx * 0.035f; p.fz += afz * 0.035f; // Repulsion forces from other particles for( unsigned int j = 0; j < _particles.size(); ++j ) { if( j == i ) continue; Particle &p2 = _particles[j]; float dist2 = sqrtf( (p.px - p2.px)*(p.px - p2.px) + (p.pz - p2.pz)*(p.pz - p2.pz) ); float strength = 0; float rfx = (p.px - p2.px) / dist2; float rfz = (p.pz - p2.pz) / dist2; // Use three zones with different repulsion strengths if( dist2 <= d3 && dist2 > d2 ) { float m = (f3 - 0) / (d2 - d3); float t = 0 - m * d3; strength = m * dist2 + t; } else if( dist2 <= d2 && dist2 > d1 ) { float m = (f2 - f3) / (d1 - d2); float t = f3 - m * d2; strength = m * dist2 + t; } else if( dist2 <= d1 ) { float m = (f1 - f2) / (0 - d1); float t = f2 - m * d1; strength = m * dist2 + t; } p.fx += rfx * strength; p.fz += rfz * strength; } } else { // Choose new destination chooseDestination( p ); } // Make movement framerate independent p.fx *= (30 / fps); p.fz *= (30 / fps); float vel = sqrtf( p.fx * p.fx + p.fz * p.fz ); // Set new position p.px += p.fx; p.pz += p.fz; // Calculate orientation p.ox = (p.ox + p.fx) / 2; p.oz = (p.oz + p.fz) / 2; // Get rotation from orientation float ry = 0; if( p.oz != 0 ) ry = atan2( p.ox, p.oz ); ry *= 180 / 3.1415f; // Convert from radians to degrees // Update character scene node position h3dSetNodeTransform( p.node, p.px, 0.02f, p.pz, 0, ry, 0, 1, 1, 1 ); // Update animation p.animTime += vel * 35.0f; h3dSetModelAnimParams( p.node, 0, p.animTime, 1.0f ); h3dUpdateModel( p.node, H3DModelUpdateFlags::Animation | H3DModelUpdateFlags::Geometry ); } }
bool Virus::chooseDestination() { bool success = false; Tile *myTile = map->getTile(position); unsigned int myFrameStamp = myTile->getFrameStamp(owner); std::vector<Tile *> candidates; for (unsigned int i = 0; i < data->allyCandidates.size(); i++) { if (data->allyCandidates[i] != myTile) { unsigned int frameStamp = data->allyCandidates[i]->getFrameStamp(owner); if (command == VIRUSCOMMAND_ADVANCE) { if (frameStamp >= myFrameStamp) { candidates.push_back(data->allyCandidates[i]); } } else if (command == VIRUSCOMMAND_RETREAT) { if (frameStamp <= myFrameStamp) { candidates.push_back(data->allyCandidates[i]); } } } } for (unsigned int i = 0; i < data->neutralCandidates.size(); i++) { if (data->neutralCandidates[i] != myTile) { unsigned int frameStamp = data->neutralCandidates[i]->getFrameStamp(owner); if (command == VIRUSCOMMAND_ADVANCE) { if (frameStamp >= myFrameStamp) { candidates.push_back(data->neutralCandidates[i]); } } else if (command == VIRUSCOMMAND_RETREAT) { if (frameStamp <= myFrameStamp) { candidates.push_back(data->neutralCandidates[i]); } } } } for (unsigned int i = 0; i < data->enemyCandidates.size(); i++) { if (data->enemyCandidates[i] != myTile) { unsigned int frameStamp = data->enemyCandidates[i]->getFrameStamp(owner); if (command == VIRUSCOMMAND_ADVANCE) { if (frameStamp >= myFrameStamp) { candidates.push_back(data->enemyCandidates[i]); } } else if (command == VIRUSCOMMAND_RETREAT) { if (frameStamp <= myFrameStamp) { candidates.push_back(data->enemyCandidates[i]); } } } } if (candidates.size() > 0) { chooseDestination(candidates, data->parent); success = true; } return success; }
void Virus::executeCurrentCommand() { bool success = false; switch (command) { case VIRUSCOMMAND_EXPAND: if (owner == FACTION_ENEMY) { if (data->neutralCandidates.size() > 0) { chooseDestination(data->neutralCandidates, data->parent); } else if (data->enemyCandidates.size() > 0) { chooseDestination(data->enemyCandidates, data->parent); } } else if (owner == FACTION_ALLY) { if (data->neutralCandidates.size() > 0) { chooseDestination(data->neutralCandidates, data->parent); } else if (data->allyCandidates.size() > 0) { chooseDestination(data->allyCandidates, data->parent); } } success = true; break; case VIRUSCOMMAND_WAIT: if (owner == FACTION_ENEMY) { if (data->enemyCandidates.size() > 0) { chooseDestination(data->enemyCandidates, data->parent); success = true; } } else if (owner == FACTION_ALLY) { if (data->allyCandidates.size() > 0) { chooseDestination(data->allyCandidates, data->parent); success = true; } } break; case VIRUSCOMMAND_ATTACK: if (owner == FACTION_ENEMY) { if (data->allyCandidates.size() > 0) { chooseDestination(data->allyCandidates, data->parent); } else if (data->neutralCandidates.size() > 0) { chooseDestination(data->neutralCandidates, data->parent); } else if (data->enemyCandidates.size() > 0) { chooseDestination(data->enemyCandidates, data->parent); } } else if (owner == FACTION_ALLY) { if (data->enemyCandidates.size() > 0) { chooseDestination(data->enemyCandidates, data->parent); } else if (data->neutralCandidates.size() > 0) { chooseDestination(data->neutralCandidates, data->parent); } else if (data->allyCandidates.size() > 0) { chooseDestination(data->allyCandidates, data->parent); } } success = true; break; case VIRUSCOMMAND_ADVANCE: case VIRUSCOMMAND_RETREAT: success = chooseDestination(); break; } if (!success) { command = VIRUSCOMMAND_EXPAND; } }