//////////////////////////////////////////////////////////////////////// /// /// @fn void VisiteurCollision::replacerRondelle() /// /// Fonction qui replace la rondelle lorsqu'il y a un but /// /// @return Aucune. /// //////////////////////////////////////////////////////////////////////// void VisiteurCollision::replacerRondelle() { rondelle_->assignerPositionRelative(Vecteur3(0,0,0)); rondelle_->modifierVitesse(Vecteur3(0,0,0)); rondelle_->modifierAngleRotation(0.0); rondelle_->modifierRotation(0.0); }
//////////////////////////////////////////////////////////////////////// /// /// @fn VisiteurNoeudTest::testSelectionObjet() /// /// Test pour la sélection d'objets /// /// /// @return void /// //////////////////////////////////////////////////////////////////////// void VisiteurNoeudTest::testSelectionObjet() { RazerGameTree* arbre = new RazerGameTree(NULL,999,999); NoeudAbstrait *noeud1 = arbre->creerNoeud( RAZER_KEY_MALLET ), *noeud2 = arbre->creerNoeud( RAZER_KEY_PORTAL ), *noeud3 = arbre->creerNoeud( RAZER_KEY_PORTAL ), *noeud4 = arbre->creerNoeud( RAZER_KEY_MALLET ), *noeud5 = arbre->creerNoeud( RAZER_KEY_PUCK ); arbre->add(noeud1); arbre->add(noeud2); arbre->add(noeud3); arbre->add(noeud4); arbre->add(noeud5); arbre->setCanBeSelected(false); noeud1->setCanBeSelected(true); noeud2->setCanBeSelected(true); noeud3->setCanBeSelected(true); noeud4->setCanBeSelected(true); noeud5->setCanBeSelected(true); noeud1->setSelection(false); noeud2->setSelection(false); noeud3->setSelection(false); noeud4->setSelection(false); noeud5->setSelection(false); // assignation de position tres eloigné pour éviter que les boites de collisions se touchent noeud1->setPosition(Vecteur3(-500.0,500.0,0.0)); noeud2->setPosition(Vecteur3(500.0,500.0,0)); noeud3->setPosition(Vecteur3(0.0,0.0,0.0)); noeud4->setPosition(Vecteur3(-500.0,-500.0,0.0)); noeud5->setPosition(Vecteur3(500.0,-500.0,0.0)); VisiteurSelection v(Vecteur2(-500.0,500.0),Vecteur2(-500.0,500.0),false); CPPUNIT_ASSERT(v.mToggleSelection == false); arbre->acceptVisitor(v); v.faireSelection(); CPPUNIT_ASSERT(noeud1->IsSelected() == true); CPPUNIT_ASSERT(noeud2->IsSelected() == false); CPPUNIT_ASSERT(noeud3->IsSelected() == false); CPPUNIT_ASSERT(noeud4->IsSelected() == false); CPPUNIT_ASSERT(noeud5->IsSelected() == false); noeud1->setSelection(false); VisiteurSelection v2(Vecteur2(-550.0,450.0),Vecteur2(550.0,550.0),true); CPPUNIT_ASSERT(v2.mToggleSelection == true); arbre->acceptVisitor(v2); v2.faireSelection(); CPPUNIT_ASSERT(noeud1->IsSelected() == true); CPPUNIT_ASSERT(noeud2->IsSelected() == true); CPPUNIT_ASSERT(noeud3->IsSelected() == false); CPPUNIT_ASSERT(noeud4->IsSelected() == false); CPPUNIT_ASSERT(noeud5->IsSelected() == false); arbre->empty(); delete arbre; }
//////////////////////////////////////////////////////////////////////// /// /// @fn void VisiteurNoeudTest::testDeplacerObjet() /// /// Cas de test: Déplacement d'objets. /// /// @return Aucune. /// //////////////////////////////////////////////////////////////////////// void VisiteurNoeudTest::testDeplacerObjet() { NoeudAbstrait* n = new NoeudAbstrait(RAZER_KEY_NONE); n->setPosition(Vecteur3(0.0,0.0)); n->setSelection(true); VisiteurDeplacement v(Vecteur2(25.0,-10.0)); n->acceptVisitor(v); CPPUNIT_ASSERT(n->getPosition() == Vecteur3(25.0,-10.0)); }
//////////////////////////////////////////////////////////////////////// /// /// @fn void VisiteurModifierProprieteNoeud::visiterNoeudMuret( NodeWallAbstract* noeud ) /// /// Visiteur du noeud muret. /// /// @param[in] NodeWallAbstract * noeud : noeud a visiter. /// /// @return void /// //////////////////////////////////////////////////////////////////////// void VisiteurModifierProprieteNoeud::visiterNoeudMuret( NodeWallAbstract* noeud ) { /// On applique le nouveau coefficient de rebond if(noeud->IsSelected()) { if(coefRebond_!=-1) noeud->setReboundRatio(coefRebond_); if(unSeulSelect_) { const Vecteur3& oldPos = noeud->getPosition(); noeud->setPosition(position_); float oldAngle = noeud->getAngle(); noeud->setAngle((float)rotation_); Vecteur3 oldEchelle; noeud->getScale(oldEchelle); noeud->setScale(Vecteur3(echelle_*10, oldEchelle[VY], oldEchelle[VZ])); Terrain* field = noeud->getField(); // Si on arrive pas à assigner les nouvelles positions on annule les modifications et l'indique à l'usager if(!field || !field->FixCollindingNode(noeud,20)) { noeud->setPosition(oldPos); noeud->setAngle(oldAngle); noeud->setScale(oldEchelle); utilitaire::afficherErreur("Nouvelles propriétés du Muret ne sont pas valides"); } } } visiterNoeudComposite(noeud); }
void NoeudProjectile::setVitesse(double vitesseBase, Vecteur3 vitesseVaisseau) { // Simple calcul a refaire double dx = cos(utilitaire::DEG_TO_RAD(angleRotation_)); double dy = sin(utilitaire::DEG_TO_RAD(angleRotation_)); this->vitesse_ = vitesseBase*Vecteur3(dx, dy, 0) + vitesseVaisseau; }
//////////////////////////////////////////////////////////////////////// /// /// @fn void AIRenforcementTest::testDirectionPhaseDeplacement() /// /// Test de la direction lorsque la rondelle traverse la ligne du milieu, s'il commence à se déplacer /// /// /// @return void /// //////////////////////////////////////////////////////////////////////// void AIRenforcementTest::testDirectionPhaseDeplacement() { // Place le maillet NoeudMaillet* wMaillet = partie->getField()->getRightMallet(); wMaillet->setPosition(Vecteur3(55,0,0)); // Place la rondelle NoeudRondelle* wPuck = partie->getField()->getPuck(); wPuck->setPosition(Vecteur3(1,0,0)); wPuck->modifierVelocite(Vecteur3(150,0,0)); // Setup strat auto joueurVirtuel = (std::dynamic_pointer_cast<PlayerReinforcementAI>(wMaillet->getPlayer())); AIMailletRenforcement* aimaillet = (AIMailletRenforcement*)joueurVirtuel->getAiMaillet(); aimaillet->changerStrat(OFFENSIVE_LIGNE_DROITE); AIStratOffensiveRenforcement* strat = ((AIStratOffensiveRenforcement*)aimaillet->getStrategie()); //strat->setMalletTargetPos(Vecteur2()); PAS A SETTER strat->setPointImpact(Vecteur2(50,0)); strat->setPointVise(Vecteur2(-150,0)); strat->setTimeBeforeImpact(0); // pas utilisé pour le moment joueurVirtuel->obtenirDirectionAI(wMaillet); }
void VisiteurModifierProprieteNoeud::visiterNoeudNeutre( NoeudAbstrait* noeud ) { if(unSeulSelect_ && noeud->IsSelected()) { /// On fait le deplacement contenu dans position_ par rapport à l'origine /*Vecteur3 deplacement = ((position_.convertir<3>())-(noeud->getPosition())); VisiteurDeplacement visiteurDeplacement(deplacement,true); noeud->acceptVisitor(visiteurDeplacement);*/ const Vecteur3& oldPos = noeud->getPosition(); noeud->setPosition(position_); float oldAngle = noeud->getAngle(); /// On applique la nouvelle rotation VisiteurRotation rotationAFaire((float)rotation_,position_); noeud->acceptVisitor(rotationAFaire); Vecteur3 oldEchelle; noeud->getScale(oldEchelle); if(noeud->getKey() == RAZER_KEY_PORTAL) noeud->setScale(Vecteur3(echelle_, echelle_, 1)); else noeud->setScale(Vecteur3(echelle_, echelle_, echelle_)); noeud->updateMatrice(); Terrain* field = noeud->getField(); /// On regle les nouvelles collision créé if(!field || !field->FixCollindingNode(noeud,20)) { noeud->setPosition(oldPos); noeud->setAngle(oldAngle); noeud->setScale(oldEchelle); noeud->updateMatrice(); utilitaire::afficherErreur("Nouvelles propriétés du noeud ne sont pas valides"); } } }
Vecteur2 CameraPinhole::mondeVersImage(const Vecteur3 &P) const { // UVW : Dans le repere camera Vecteur3 dist = P-_position; Vecteur3 UVW = _mondeVersCamera*(dist); // Distance focale reel distance = 1; // UVW' : Projete dans le repere camera Vecteur3 UVW_ = Vecteur3(UVW._x*distance/UVW._z, UVW._y*distance/UVW._z, distance); // uv' : Projete dans le plan image Vecteur2 uv_ = Vecteur2(UVW_._x/_dU, UVW_._y/_dV); // xy : Projete dans les coordonnees image Vecteur2 xy = Vecteur2(int((uv_._u+0.5)*(1./_invNbX)), int((uv_._v+0.5)*(1./_invNbY))); return xy; }
//////////////////////////////////////////////////////////////////////// /// /// @fn NodeTableControlPoint::NodeTableControlPoint( const std::string& typeNoeud, /// float coordX, float coordY, int typePosNoeud ) /// /// Constructeur assignant les paramètres donner aux attributs de la /// classe. /// /// @param[in] const std::string & typeNoeud : le type de noeud. /// @param[in] float coordX : la coordonne en X du noeud. /// @param[in] float coordY : la coordonne en Y du noeud. /// @param[in] int typePosNoeud : un int représentant le enum du /// type de position du noeud, i.e. HG. /// /// @return void /// //////////////////////////////////////////////////////////////////////// NodeTableControlPoint::NodeTableControlPoint( float coordX, float coordY, TypePosPoint typePosNoeud) : NoeudComposite(RAZER_KEY_TABLE_CONTROL_POINT) , longueurCote_(2.0f), typePosNoeud_(typePosNoeud),mCanBeVisited(true) { /// les noeuds points ne peuvent etre supprimer mFlags.SetFlag(false,NODEFLAGS_CAN_BE_DELETED); /// affichage du noeud avec le modele du control point //setDefaultNodeKey(RAZER_KEY_CONTROL_POINT); // Assigner le rayon par défaut le plus tot possible car la suite peut en avoir besoin setDefaultRadius(DEFAULT_RADIUS); // Il ne faut aps utiliser le modificateur de position relative, car il ne faut pas affecter le modele 3D a la construction des points NoeudAbstrait::setPosition(Vecteur3(coordX,coordY, 0)); modifierPositionInitiale(mPosition); }
//////////////////////////////////////////////////////////////////////// /// /// @fn void NoeudProjectile::animer(float temps) /// /// Cette fonction effectue l'animation du noeud pour un certain /// intervalle de temps. /// /// @param[in] temps : Intervalle de temps sur lequel faire l'animation. /// /// @return Aucune. /// //////////////////////////////////////////////////////////////////////// void NoeudProjectile::animer(float temps) { if (enabled_) { // Applique la physique tout en calculant la distance parcourue par le projectile, //afin de le faire disparaitre quand une trop grand distance a été passée Vecteur3 oldPosition = this->positionRelative_; // Calculer acceleration acceleration_ += forces_; this->appliquerPhysique(temps); acceleration_ -= forces_; // Reset les forces en jeu forces_ = Vecteur3(0, 0, 0); // Orienter le projectile selon la direction NoeudAbstrait::setAngleRotation(utilitaire::RAD_TO_DEG(vitesse_.lireTheta())); // Compter le temps écoulé tempsPasse_ += temps; // Si ça fait plus de 3 secondes if (tempsPasse_ > 3.0f) { enabled_ = false; } Vecteur3 minXY, maxXY; this->obtenirBoiteEnglobante(minXY, maxXY); if (!FacadeModele::obtenirInstance()->obtenirArbreRenduINF2990()->estDansCadreDepart(minXY, maxXY)) { enabled_ = false; } // Détection des collisions VisiteurProjectile v(this); FacadeModele::obtenirInstance()->obtenirArbreRenduINF2990()->accepter(v); } }
//////////////////////////////////////////////////////////////////////// /// /// @fn VisiteurCollision::visiter(NoeudMaillet& noeud) /// /// Fonction qui permet de taiter la collision entre la /// rondelle et les maillets /// /// @param[in] typeNoeud : Le type du noeud. /// /// @return Aucune /// //////////////////////////////////////////////////////////////////////// void VisiteurCollision::visiter(NoeudMaillet& noeud) { rondelleQuitte_ = false; static Vecteur2 forceCollision; // vecteur de la force de la collision en X,Y static Vecteur3 vitesseRondelle; // vitesse de la rondelle static Vecteur3 posMaillet; // position du maillet posMaillet = noeud.obtenirPositionRelative(); vitesseRondelle = rondelle_->obtenirVitesse(); // calcul de la force de collision forceCollision = aidecollision::calculerCollisionCercle( Vecteur2(posMaillet[X], posMaillet[Y]), // position du maillet noeud.obtenirRayon(), // rayon du maillet Vecteur2(rondelle_->obtenirPositionRelative()[X], rondelle_->obtenirPositionRelative()[Y]), // position de la rondelle rondelle_->obtenirRayon(), // rayon de la rondelle noeud.obtenirCoefficientRebondissement(), 0.01, // coefficient de rebondissement et d'amortissement Vecteur2(vitesseRondelle[X], vitesseRondelle[Y])); // vitesse de la rondelle if (forceCollision[X] != 0 || forceCollision[Y] != 0) // vérifier qu'il y a bien une collision { for (int i = 0; i < 2; ++i) // faire varier la vitesse de la rondelle selon la force vitesseRondelle[i] += forceCollision[i]; // jouer un son de collision GestionnaireSon::obtenirInstance()->jouerSonCollision(ArbreRenduINF2990::NOM_MAILLET); rondelle_->modifierVitesse(vitesseRondelle); // s'il y a une collision entre la rondelle et les bordures de la table, // rondelleQuitte_ indiquera au maillet qu'il tente de pouser la rondelle hors de la table // ce qui appliquera une force sur le maillet contraire à son déplacement if (rondelle_->animerCollision()) rondelleQuitte_ = true; else rondelle_->calculerRotation(Vecteur3(forceCollision[X], forceCollision[Y], 0.0)); } }
Vecteur3 CameraPinhole::ecranVersCamera(const Vecteur2 &uv) const { return Vecteur3(uv._u*_dU, uv._v*_dV, 1); }
//////////////////////////////////////////////////////////////////////// /// /// @fn VisiteurCollision::visiter(NoeudPortail& noeud) /// /// Fonction qui permet de taiter la collision entre la /// rondelle et les portails /// /// @param[in] typeNoeud : Le type du noeud. /// /// @return Aucun /// //////////////////////////////////////////////////////////////////////// void VisiteurCollision::visiter(NoeudPortail& noeud) { /// fistances entre la rondelle et le portail GLdouble dx = noeud.obtenirPositionRelative()[X] - rondelle_->obtenirPositionRelative()[X]; GLdouble dy = noeud.obtenirPositionRelative()[Y] - rondelle_->obtenirPositionRelative()[Y]; /// vecteur de la direction qui pointe de la rondelle au portail Vecteur3 direction = Vecteur3(dx,dy,0); direction.normaliser(); /// calcul de la distance entre deux points GLdouble distance = sqrt( (dx*dx) + (dy*dy) ); /// savoir si la rondelle est dans le champs d'attraction GLdouble distAttraction = distance - noeud.obtenirRayonAttraction() - rondelle_->obtenirRayon(); /// prendre en compte les rayons de nos objets distance = distance - rondelle_->obtenirRayon(); /// si il y a collision, teleportation if (distance < 0) { size_t nombrePortails = portails_.size(); if (nombrePortails == 1.0) // il y a juste un portail { noeud.desactiverAttraction(); } else { if (noeud.obtenirAttraction()) { GestionnaireSon::obtenirInstance()->jouerSonCollision(ArbreRenduINF2990::NOM_PORTAIL); teleporter(noeud); } } } /// si il n'y a pas de collision, attirer la rondelle quand la rondelle est dans la zone d'attraction else { if (distAttraction < 0.0) { if (distance > 1.0f) noeud.varierRotation(1.0f / (GLfloat)distance * 10.0f); else noeud.varierRotation((GLfloat)distance + 1.0f); if (noeud.obtenirAttraction()) { Vecteur3 vitesse = rondelle_->obtenirVitesse(); for (int i = 0; i < 2; ++i) { vitesse[i] += direction[i] * (noeud.obtenirRayon()*FORCE_PORTAIL/distance); } rondelle_->modifierVitesse(vitesse); } } else { if (portails_.size() > 1) noeud.activerAttraction(); } } }
//////////////////////////////////////////////////////////////////////// /// /// @fn Vecteur3 NodeTableControlPoint::calculerDeplacementMax( Vecteur3 posAbsActuel, Vecteur3 deplacement ) /// /// Calcule et retourne le deplacement maximal d'un point de contrôle dans la direction du vecteur de déplacement /// Le point retourner est donc un /// /// @param[in] Vecteur3 posAbsActuel /// @param[in] Vecteur3 deplacement /// /// @return Vecteur3 /// //////////////////////////////////////////////////////////////////////// Vecteur3 NodeTableControlPoint::calculerDeplacementMax( Vecteur3 posAbsActuel, Vecteur3 deplacement ) { return Vecteur3(0,0,0); }