Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Framework] ODFAEG

Pour la création de jeux vidéos

    25 octobre 2024 à 20:10:11

    Avec les compilateurs plus récent que la version 10 de gcc j'ai des erreurs avec le fichier random.h
    • Partager sur Facebook
    • Partager sur Twitter
      4 novembre 2024 à 17:12:42

      J'ai continué le support pour vulkan! J'en ai profiter pour modifier les classes de la SFML et j'ai trouvé pourquoi rien ne s'affichait sur ma texture de rendu.

      Je n'ai pas encore fait par contre le support pour vulkan pour les "renderers" de ODFAEG parce que là je fais de l'indirect rendering, de l'instancing et du bindless texturing et j'ai pas encore trouvé de tutoriel pour faire ça avec vulkan.

      Voici ce que ça donne niveau implémentation :

      VkSettup vkSettup;
          Device vkDevice(vkSettup);
          RenderWindow window(sf::VideoMode(800, 600), "Test vulkan",vkDevice);
          window.getView().move(400, 300, 0);
          RenderTexture rt(vkDevice);
          rt.create(800, 600);
          Texture texture(vkDevice);
          texture.loadFromFile("tilesets/eau.png");
          VertexArray va;
          va.append(Vertex(sf::Vector3f(0, 0, 0), sf::Color::White, sf::Vector2f(0, 0)));
          va.append(Vertex(sf::Vector3f(100, 0, 0), sf::Color::White, sf::Vector2f(1, 0)));
          va.append(Vertex(sf::Vector3f(100, 50, 0), sf::Color::White, sf::Vector2f(1, 1)));
          va.append(Vertex(sf::Vector3f(0, 50, 0), sf::Color::White, sf::Vector2f(0, 1)));
          VertexArray va2;
          va2.append(Vertex(sf::Vector3f(0, 0, 0), sf::Color::White, sf::Vector2f(0, 0)));
          va2.append(Vertex(sf::Vector3f(800, 0, 0), sf::Color::White, sf::Vector2f(1, 0)));
          va2.append(Vertex(sf::Vector3f(800, 600, 0), sf::Color::White, sf::Vector2f(1, 1)));
          va2.append(Vertex(sf::Vector3f(0, 600, 0), sf::Color::White, sf::Vector2f(0, 1)));
          while (true) {
              RenderStates states;
              states.texture = &texture;
              rt.draw(va, states);
              rt.display();
              states.texture = &rt.getTexture();
              window.draw(va2, states);
              window.display();
          }

      Le principe est similaire à part qu'au lieu de passer un contexte comme avec opengl je crée un objet VkSettup pour créer la vkInstance et Device pour créer le physical et logical device.

      -
      Edité par OmbreNoire 4 novembre 2024 à 17:14:17

      • Partager sur Facebook
      • Partager sur Twitter
        6 novembre 2024 à 14:02:03

        Salut! Vulkan c'est bien mais ça sera pour plus tard lorsque je ferai la version 2 de ODFAEG Creator ma priorité est de finir la version 1 de odfaeg creator et de créer un jeux.

        Je vais me concentrer sur la 2D pour l'instant la 3D sera pour plus tard mais odfaeg permet de générer un sol 3D et importer des modèles 3D mais se sera implémenté plus tard dans ODFAEG creator.

        Je ne peux malheureusement plus faire de vidéos sur l'utilisation de ODFAEG Creator car le logiciel que j'utilise pour filmer est devenu payant.

        • Partager sur Facebook
        • Partager sur Twitter
          8 novembre 2024 à 20:52:05

          Salut! J'ai corrigé des bugs avec le framework et l'éditeur.
          • Partager sur Facebook
          • Partager sur Twitter
            9 novembre 2024 à 22:27:28

            Salut! Nouvelle fonction ajoutée pour calculer la position en fonction de la physique. (gravité, force, grimpage, collisions, etc...)

            Voici la fonction commentée en question mais je n'ai pas encore pu tester.

            math::Vec3f Scene::physicallyBasedComputePos (Entity* entity, math::Vec3f oldCenter, math::Vec3f size, math::Vec3f velocity, float climbCapacity) {
                        float newFootHeight, newHeadHeight;
                        //La nouvelle position du joueur suivant les tests de la physique du jeux.
                        math::Vec3f newCenter = entity->getCenter();
                        //Position du pied et de la tête du joueur suivant la 2D ou la 3D.
                        if (size.z == 0)
                           newFootHeight = newCenter.y - size.y * 0.5f;
                        else
                           newFootHeight = newCenter.z - size.z * 0.5f;
                        //On applique la force sur la nouvelle position du joueur soit le joueur monter ou descend.
                        newCenter = entity->getCenter() - velocity;
                        //On cherche d'abord les collisions par rapport aux plateformes.
                        //On récupère toutes les plateformes.
                        std::vector<Entity*> platforms = getRootEntities("E_BIGTILE");
                        /*Si le joueur descend, il faut rechercher la plateforme sur laquelle le joueur se trouve.
                        Si le joueur n'est pas en dessous de la plateforme on le remet sur la plateforme et ensuite en regarde
                        si le joueur peut escalader la pente ou monter sur la nouvelle plateforme.*/
            
                        if (newCenter.z < oldCenter.z) {
                            //Si il y a plusieurs plateformes il faut rechercher sur laquelle le joueur se trouve, c'est à dire la plus proche en dessous.
                            float minDist;
                            unsigned int index;
                            for (unsigned int i = 0; i< platforms.size(); i++) {
                                //Hauteur de la plateforme ou le joueur se trouvait.
                                float height;
                                bool isOnPlateform = platforms[i]->getHeight(math::Vec2f(newCenter.x, newCenter.y), height);
                                //Distance entre le pied du joueur et la plateforme.
                                float dist = newFootHeight - height;
                                //Si le joueur n'est pas en dessous de la plateforme on initialise minDist et on sort de la boucle.
                                if (dist >= 0 && isOnPlateform) {
                                    minDist = dist;
                                    index = i;
                                    break;
                                }
                            }
                            Entity* newPlatform = nullptr;
                            //Il faut refaire une boucle si il y a plusieurs plateforme en dessous du joueur il faut trouver la plus proche.
                            for (unsigned int i = index; i < platforms.size(); i++) {
                                //Hauteur de la plateforme ou le joueur se trouvait.
                                float height;
                                bool isOnPlatform = platforms[i]->getHeight(math::Vec2f(newCenter.x, newCenter.y), height);
                                //Distance entre le pied du joueur et la plateforme.
                                float dist = newFootHeight - height;
                                //Si le joueur n'est pas en dessous de la plateforme et que la plateforme est la plus proche on initialise la plateforme et la distance minimum et la plateforme.
                                if (dist >= minDist && isOnPlatform) {
                                    minDist = dist;
                                    newPlatform = platforms[i];
                                }
                            }
            
                            //Attention le joueur ne peut pas se trouver en dessous de la nouvelle plateforme!
                            if (newPlatform != nullptr) {
                                float height;
                                bool isOnPlateform = newPlatform->getHeight(math::Vec2f(newCenter.x, newCenter.y), height);
                                //Si il est en dessous de la plateforme on le remet sur la plateforme, sinon on le laisse descendre.
                                if (newFootHeight < height) {
                                   if (size.z = 0) {
                                        newCenter.x = newCenter.x;
                                        newCenter.y = height + size.y * 0.5f;
                                        newCenter.z = newCenter.y;
                                    } else {
                                        newCenter.x = newCenter.x;
                                        newCenter.y = newCenter.y;
                                        newCenter.z = height + size.z * 0.5f;
                                    }
                                }
                            }
                            //Maintenant il faut tester si le joueur peut monter sur la pente, si pas, on revient à la position de départ.
                            float climbValue = newCenter.z - oldCenter.z;
                            if (climbValue > climbCapacity) {
                                newCenter = oldCenter;
                            }
                            /*Si le joueur monte il faut rechercher la plateforme en dessous de laquelle le joueur se trouve
                             et si il est plus haut que cette plateforme, le faire redescendre.*/
                        } else if (newCenter.z > oldCenter.z) {
                            //Il faut aussi rechercher la plateforme du dessus.
                            //Si il y a plusieurs plateformes il faut rechercher la plateforme du dessus la plus proche.
                            float minDist;
                            unsigned int index;
                            for (unsigned int i = 0; i < platforms.size(); i++) {
                                //Hauteur de la plateforme ou le joueur se trouve.
                                float height;
                                bool isOnPlateform = platforms[i]->getHeight(math::Vec2f(newCenter.x, newCenter.y), height);
                                //Distance entre le pied du joueur et la plateforme.
                                float dist = newFootHeight - height;
                                //Si le joueur n'est pas en dessous de la plateforme on initialise minDist et on sort de la boucle.
                                if (dist <= 0 && isOnPlateform) {
                                    minDist = dist;
                                    index = i;
                                    break;
                                }
                            }
                            Entity* newPlatform = nullptr;
                            //Il faut refaire une boucle si il y a plusieurs plateforme au dessus du joueur il faut trouver la plus proche.
                            for (unsigned int i = index; i < platforms.size(); i++) {
                                //Hauteur de la plateforme ou le joueur se trouve.
                                float height;
                                bool isOnPlateform = platforms[i]->getHeight(math::Vec2f(newCenter.x, newCenter.y), height);
                                //Distance entre le pied du joueur et la plateforme.
                                float dist = newFootHeight - height;
                                //Si le joueur n'est pas en dessous de la plateforme et que la plateforme est la plus proche on initialise la nouvelle position et la distance minimum et la plateforme.
                                if (dist <= minDist && isOnPlateform) {
                                    minDist = dist;
                                    newPlatform = platforms[i];
                                }
                            }
                            if (newPlatform != nullptr) {
                                float height;
                                bool isOnPlateform = newPlatform->getHeight(math::Vec2f(newCenter.x, newCenter.y), height);
                                //Si le joueur est au dessus de la plateforme on descend.
                                if (newFootHeight < height) {
                                    newCenter = oldCenter;
                                }
                            }
                        }
                        //Ensuite on recherche les collisions par rapports aux volumes englobants.
                        //Rayon de déplacement du perso.
                        math::Ray ray (oldCenter, entity->getCenter());
                        //On a besoin d'informations sur la collision, le minimal transition vector.
                        physic::CollisionResultSet cinfos;
                        //Si pas de volume englobant, on recherche si on est dans une case sur laquelle on ne peut pas passer, si oui, on retorune l'ancienne position sinon la nouvelle.
            
                        if (entity->getCollisionVolume() == nullptr) {
                            if (collide(entity, ray, cinfos)) {
                                newCenter = oldCenter;
                                return newCenter;
                            } else {
                                return newCenter;
                            }
                        }
                        //Si il n'y a pas de collision on retourne la nouvelle position sinon il faut rechercher l'endroit ou à lieu la collision.
                        math::Vec3f collisionPoint;
                        if (!collide(entity, ray, cinfos)) {
                            return newCenter;
                        } else {
                            collisionPoint = newCenter + cinfos.popCollisionInfo().mtu;
                            //Si on descend on recherche si on est plus bas que le point de collision, si oui on remonte à l'endroit de la collision.
                            if (newCenter.z < oldCenter.z) {
                                if (newCenter.z < collisionPoint.z) {
                                    if (size.z == 0) {
                                        newCenter.y = collisionPoint.z;
                                        newCenter.z = newCenter.y;
                                    } else {
                                        newCenter.z = collisionPoint.z;
                                    }
                                }
                                //Il faut ensuite vérifier si on peut grimper sur le volume de collision, si pas, on revient à la position de départ.
                                float climbValue = newCenter.z - collisionPoint.z;
                                if (climbValue > climbCapacity) {
                                    newCenter = oldCenter;
                                }
                                return newCenter;
                                //Si on monte et qu'on est plus haut que le volume de collision, il faut redescendre.
                            } else if (newCenter.z > oldCenter.z) {
                                if (newCenter.z < collisionPoint.z) {
                                    if (size.z == 0) {
                                        newCenter.y = collisionPoint.z;
                                        newCenter.z = newCenter.y;
                                    } else {
                                        newCenter.z = collisionPoint.z;
                                    }
                                    return newCenter;
                                }
                            }
                            return newCenter;
                        }
                    }

            Ceci permet de grimper sur un pont ou un escalier, de sauter, de tomber, etc...

            Édit : j'ai corrigé la fonction c'est difficile il faut gérer tout les cas si le joueur est en collision avec une plateforme ou un volume englobant si le joueur grimpe, vole, chute, etc... Je dois faire des tests pour voir si ça fonctionne car c'est compliqué.

            J'ai également modifier la fonction de test d'intersection pour gérer les collections entre hiérarchie de volumes englobant.

            -
            Edité par OmbreNoire 10 novembre 2024 à 20:15:08

            • Partager sur Facebook
            • Partager sur Twitter
              11 novembre 2024 à 15:05:29

              Salut je suis entrain de passer le moteur à la version 2. La version 2 utilisera un système ecs avec la librairie entt. Le code de odfaeg creator et du jeux seront modifiés également ça fera pas mal de boulot. La version 1 utilisait un système d'héritage d'une classe de base et j'ai remarqué que utiliser un système ecs augmente les performances. J'ai aussi commencé comme je vous l'avais expliquer à implémenter vulkan mais on pourra toujours utiliser opengl.
              • Partager sur Facebook
              • Partager sur Twitter
                16 novembre 2024 à 12:50:30

                Salut! J'ai fait des tests et avec un système ECS j'ai le même FPS que avec l'héritage.

                Ca ne vaut donc pas le coup de changer tout le code...

                • Partager sur Facebook
                • Partager sur Twitter
                  19 novembre 2024 à 12:26:51

                  Salut ! J'ai commencé à créer une Map avec odfaeg creator et ça marche plutôt bien mais j'ai encore des choses à faire ajouter la possibilité de créer des volumes englobant enfants avec l'éditeur. La question que je me posais c'était comment faire des tests plus précis sans impacter les performances parce que les tests entre polygone sont plutôt lent. La solution que j'ai trouvé c'est de créer une hiérarchie de boîtes englobantes.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 novembre 2024 à 18:48:10

                    Salut! J'ai corrigé quelques bugs de ODFAEG Creator entre autre lors de la suppression d'entités, la sauvegarde d'émiteurs, etc... et j'ai améliorer le système de collision de ODFAEG Creator pour placer des hiérarchies de volumes englobant sur les entités.

                    Il me reste encore à tester les ombres, les lumières et la modification d'objets externes à ODFAEG à l'aide du plugin et je crois que je vais m'arrêter là pour la 2D après je dois modifier le code source du jeux pour qu'il charge les maps créées avec ODFAEG Creator.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      24 novembre 2024 à 13:41:11

                      Salut! Ca y est j'ai réussi à faire tourner une entité grâce à un widget, en fait je dessine un cercle autour de l'entité et quand je tourne avec la souris dans le cercle ça fait tourner mon entité  comme les widgets dans blender.

                      J'ai eu énormément de mal à la faire soit ça ne tournait pas dans le bon sens ou alors l'angle de rotation renvoyé par les deux vecteurs était toujours positif parce que pas la bonne normale. Avec les angles c'était assez casse tête mais j'ai réussi!

                      Et en 2D c'est encore facile parce que l'axe de rotation c'est toujours z mais en 3D ça va être dur pour faire tourner un objet entre un angle et un axe quelconque. Je dois faire pivoter l'axe de rotation et le cerle de rotation du widget avec la souris donc là encore je devrais me casser la tête avec les vecteurs et les angles. Mais ça sera pour plus tard là je vais essayer de faire des widgets pour la translation et le changement d'échelle et c'est agréable à faire!!! Je me suis amusé à faire un widget de rotation whouhou!!!

                      • Partager sur Facebook
                      • Partager sur Twitter
                        26 novembre 2024 à 13:37:03

                        Salut! J'ai terminé les widgets de translation et de rotation :

                        Il y a un fond vert sur les objets sélectionnés donc c'est normal qu'il y ai un fond vert autour de la maison, le stencil buffer est vraiment pratique pour mettre un cadre autour des entités sélectionnées et je trouve que faire des widgets comme sur blender pour transformer les objets n'est pas une mauvaise idée et c'est amusant à faire.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          28 novembre 2024 à 12:12:07

                          Bonjour odfaeg creator est presque fini pour la 2d je n'ai plus qu'à faire quelques tests et corriger quelques bugs. Une fois ça de fait j'arrête le développement du moteur et je me concentre sur le développement du jeux j'espère que mon moteur attirera plus de monde comme ça.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            28 novembre 2024 à 15:26:07

                            Au sujet de ta hiérarchie de boîtes englobantes, je ne sais pas quel algorithme tu as utilisé, pour les collisions le plus efficace c'est les "kd-trees" (ce qu'utilisent en général les moteurs physiques)

                            Pour ton premier jeu commence par un truc simple, ça suffit pour attirer l'attention du public.

                            • Partager sur Facebook
                            • Partager sur Twitter
                              28 novembre 2024 à 16:20:51

                              houellebecqonfray a écrit:

                              Au sujet de ta hiérarchie de boîtes englobantes, je ne sais pas quel algorithme tu as utilisé, pour les collisions le plus efficace c'est les "kd-trees" (ce qu'utilisent en général les moteurs physiques)

                              Pour ton premier jeu commence par un truc simple, ça suffit pour attirer l'attention du public.


                              Salut, je n'ai pas fait comme ça j'ai fait un algorithme tout simple :

                              bool intersects(BaseInterface& other, CollisionResultSet::Info& info) {
                                              if (getChildren().size() == 0 && other.getChildren().size() == 0) {
                                                  //Si on arrive à la fin de la hiérarchie des deux arbres et que il y a collision on renvoie vrai.
                                                  if(onIntersects(other, info)){
                                                      return true;
                                                  }
                                              }
                                              //Si le volume englobant 2 seulement à des enfants.
                                              if (getChildren().size() == 0 && other.getChildren().size() != 0) {
                                                    //Si les volumes englobants parents ne sont pas en collision alors les volumes englobants enfants non plus, il n'y a pas collision.
                                                    if (!onIntersects(other, info))
                                                      return false;
                                                    bool intersectsOne = false;
                                                    //Recherche si au moins un volume englobant enfant est en collision avec l'autre il y a collision.
                                                    for (unsigned int i = 0; i < other.getChildren().size(); i++) {
                                                       //Si le volume englobant est en collision avec l'enfant on réitère. (test plus précis)
                                                       if (onIntersects(*other.getChildren()[i], info)) {
                                                          bool inter = intersects(*other.getChildren()[i], info);
                                                          //Il faut faire attention de ne pas remettre intersectsOne à false si un volume englobant enfant suivant  le volume englobant enfant en collision n'est pas en collision.
                                                          if (!intersectsOne && inter)
                                                              intersectsOne = true;
                                                       }
                                                    }
                                                    return intersectsOne;
                                              }
                                              //Si le volument englobant 1 seulement à des enfants.
                                              if (getChildren().size() != 0 && other.getChildren().size() == 0) {
                                                  //Si les volumes englobants parents ne sont pas en collision alors les volumes englobants enfants non plus, il n'y a pas collision.
                                                  if (!onIntersects(other, info))
                                                      return false;
                                                  bool intersectsOne = false;
                                                  //Si au moins un volume englobant enfant est en collision avec l'autre il y a collision sinon non.
                                                  for (unsigned int i = 0; i < getChildren().size(); i++) {
                                                      //Si le volume englobant est en collision avec l'enfant on réitère. (test plus précis)
                                                      if (getChildren()[i]->onIntersects(other, info)) {
                                                          bool inter = getChildren()[i]->intersects(other, info);
                                                          //Il faut faire attention de ne pas remettre intersectsOne à false si un volume englobant enfant suivant  le volume englobant enfant en collision n'est pas en collision.
                                                          if (!intersectsOne && inter)
                                                              intersectsOne = true;
                                                      }
                                                  }
                                                  return intersectsOne;
                                              }
                                              //Si les deux volumes de collisions ont des enfants.
                                              if (getChildren().size() != 0 && other.getChildren().size() != 0) {
                                                  //Si les volumes englobants parents ne sont pas en collision alors les volumes englobants enfants non plus, il n'y a pas collision.
                                                  if (!onIntersects(other, info))
                                                      return false;
                                                  bool intersectsOne = false;
                                                  //Si au moins un volume englobant enfant est en collision avec un autre volume englobant enfant il y a collision sinon non.
                                                  for (unsigned int i = 0; i < getChildren().size(); i++) {
                                                      for (unsigned int j = 0; j < other.getChildren().size(); j++) {
                                                          //Si le volume englobant enfant est en collision avec l'enfant de l'autre on réitère. (test plus précis)
                                                          if (getChildren()[i]->onIntersects(*other.getChildren()[j], info)) {
                                                              bool inter = getChildren()[i]->intersects(*other.getChildren()[j], info);
                                                              //Il faut faire attention de ne pas remettre intersectsOne à false si un volume englobant enfant suivant  le volume englobant enfant en collision n'est pas en collision.
                                                              if (!intersectsOne && inter)
                                                                  intersectsOne = true;
                                                          }
                                                      }
                                                  }
                                                  return intersectsOne;
                                              }
                                              //Si il n'y a pas d'enfants et que les volumes ne sont pas en collision on retourne faux.
                                              return false;
                                          }

                              Les bsp-tree c'est bien mais si un élément change il faut recréer tout l'arbre.

                              -
                              Edité par OmbreNoire 28 novembre 2024 à 16:21:09

                              • Partager sur Facebook
                              • Partager sur Twitter
                                28 novembre 2024 à 17:52:31

                                Attention de ne pas confondre le nom des algorithmes, c'est comme si tu confondais les théorèmes de thalès et pythagore. Le kd-tree est un cas particulier du bsp-tree avec les plans axis-aligned, le cas général du bsp avec les plans inclinés ça sert à générer un graph d'occlusion culling et z-ordering.

                                Parcourir un kd-tree sera un peu plus simple que ta fonction avec les BBox (donc plus rapide), par contre avant il faut le construire au chargement de map (https://fr.wikipedia.org/wiki/Arbre_kd).

                                Et comme tu l'as dit les arbres spatiaux c'est mieux adapté pour les polygones immobiles, donc tu construis ton kd-tree uniquement pour les polygones qui ne peuvent pas bouger.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  28 novembre 2024 à 18:05:14

                                  houellebecqonfray a écrit:

                                  Attention de ne pas confondre le nom des algorithmes, c'est comme si tu confondais les théorèmes de thalès et pythagore. Le kd-tree est un cas particulier du bsp-tree avec les plans axis-aligned, le cas général du bsp avec les plans inclinés ça sert à générer un graph d'occlusion culling et z-ordering.

                                  Parcourir un kd-tree sera un peu plus simple que ta fonction avec les BBox (donc plus rapide), par contre avant il faut le construire au chargement de map (https://fr.wikipedia.org/wiki/Arbre_kd).

                                  Et comme tu l'as dit les arbres spatiaux c'est mieux adapté pour les polygones immobiles, donc tu construis ton kd-tree uniquement pour les polygones qui ne peuvent pas bouger.

                                  Oui mais mes polygônes peuvent bouger et la map je la construit avec un éditeur avec lequel je peux faire bouger les polygônes. Et si je veux tests des polygônes qui ne bougent pas avec le polygône du personnage qui bouge ce ne sera pas très adapté d'utiliser un arbre je pense. Pour les gameobjets j'utilise une grille et quand le personnage bouge je le retire des cases de la grille, je le transforme et je le replace dans la grille sans avoir à recréer la grille. Et mes volumes de collision son sur les entités de la grille donc ils sont récupérés grâce aux entités. 

                                  De plus ma grille fonctionne un comme un std::vector, si l'entité est en dehors de la grille, mon algorithme créer des nouvelles cases pour que l'entité soit dans la grille, pareil lors de la suppression je supprime les cases ou il n'y a plus d'entités sans que je n'ai besoin de recréer toute la grille lors de la transformation, de l'ajout ou de la suppression des entités, je ne fais juste que recopier les entités dans la grille. C'est plus rapide et plus efficace. Même chose pour récupérer les entités dans la vue du personnage, je n'ai qu'à récupérer les cases de la grille qui se trouvent en position (x,y) fisant une boucle et en ajoutant la moitié de la taille d'une case de la grille à chaque fois.

                                  -
                                  Edité par OmbreNoire 28 novembre 2024 à 18:07:28

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    29 novembre 2024 à 8:47:17

                                    Une scène de jeux est optimisée en séparant les polygones immobiles des polygones qui bougent.

                                    Si tu ne veux pas apprendre à le faire, ton jeu sera lent.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      Hier à 11:30

                                      En fait même pour les polygones qui bougent, le kd-tree est utilisé pour tous les solides concaves, y'a que les convex qu'on pouvait optimiser avec les vieux calculs de quake qui marchent pas en gpu.

                                      C'est pas difficile à faire un kd-tree t'as même pas besoin des produits scalaires ni des produits en croix, c'est juste des soustractions puisque les distances point-plan sont sur les axes x y z. Des maths niveau école primaire donc. Cherche sur google en quelques heures de lecture tu auras compris comment construire un kd-tree.

                                      Je ne connais pas d'autres techniques pour optimiser les collisions cpu, désolé.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        Il y a environ 10 heures

                                        Ca ne marche que sur les volumes englobants aligné sur les axes non ?
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        [Framework] ODFAEG

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        • Editeur
                                        • Markdown