Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Firefly_3D
Dark storm Hors ligne Labélisateur Points: 11641 Défis: 176 Message

Firefly_3D

Posté le 16/03/2014 20:14

Bonjour à tous ! Comme vous le savez tous (enfin, j'espère), Limachi code depuis plus de 2 ans son moteur 3D pour créer un Minecraft en C/C++.
Toutefois, ce n'est pas le seul à vouloir maîtriser la 3D, je me suis également lancé dans l'aventure.

Voici donc Firefly_3D, mon propre moteur 3D, qui gérera des objets composés def faces triangulaires, eux même composés de segments composés de points.

Voici le code source du moteur, qui fonctionne pour le moment avec une caméra "simple" (origine 0, 0, 0, direction 0, 0, 0).
Ce moteur utilise MonochromeLib et Fixed, tout deux dispo sur le site.

Firefly.c
Firefly.h

Donnez moi votre avis, j'utiliserai ce moteur pour Arcuz, si il est suffisamment performant

Je la diffuse sous la license CeCILL (équivalent de la GNU GPL 3 pour la France).


Dark storm Hors ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 05/04/2014 15:36 | #


Bon, on en a parlé sur le chat, mais voilà, j'en profite pour demander de l'aide ici.

Pour le calcul de tri des faces, j'ai deux listes (n le nombre de faces) : distance_camera[n] et id_face[n]
Comment trier id_face selon les valeurs de distance_camera ?

C'est à dire pour passer de ça :
150, 0
35, 1
75, 2
180, 3
...

à ça :
180, 3
150, 0
75, 2
35, 1
...

Vous avez le droit de proposer un algo qui "détruit" la liste distance_camera, il ne me faut que id_face

Mon code actuel (de complexité O(N^2)) :
int i, j;

    for(i=start; i<end-1; i++)
    {
        for(j=start; j<end-1; j++)
        {
            if(table_ref[j] < table_ref[j+1])
            {
                FF_exchange(&(table_ref[j]), &(table_ref[j+1])); // inverse les deux variables
                FF_exchange(&(table_sort[j]), &(table_sort[j+1]));
            }
        }
    }

Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Alex_1186 Hors ligne Membre Points: 1215 Défis: 46 Message

Citer : Posté le 05/04/2014 15:42 | #


Ah en fait c'est un tri à bulles! Mais tu peux optimiser: au lieu de faire
for i=1 to n
for j=1 to n

tu fais;
for i=n downto 1
for j=1 to i

Comme ça à chaque itération du for relatif au j, le max de la liste se retrouve en position i, tu n'as plus à tester la fin de la liste! (de i+1 à n)
Il faut peut-être décaler les indices de 1, un truc comme ça...
Projets que je soutiens
Projets que je soutiens
Robscape 2 de Ray
Les tests vidéo de Marmotti
Mes projets
Mes projets
Une dizaine de projets top secrets...

Timeless Remix Airwolf
"And the dream will never die..."
Ninestars Hors ligne Membre Points: 2462 Défis: 24 Message

Citer : Posté le 05/04/2014 16:45 | #


Le tri à bulles s'optimise comme ça :
for(i=start; i<end-1; i++)
    {
        for(j=start; j<i; j++)
Alex_1186 Hors ligne Membre Points: 1215 Défis: 46 Message

Citer : Posté le 05/04/2014 16:47 | #


Euh... T'es sûr?
Moi je l'ai toujours fait dans l'autre sens, ça me paraît plus logique, non?
Tu fais un passage sur le tableau entier, puis tout sauf le dernier, puis tout sauf les deux derniers, etc...
Projets que je soutiens
Projets que je soutiens
Robscape 2 de Ray
Les tests vidéo de Marmotti
Mes projets
Mes projets
Une dizaine de projets top secrets...

Timeless Remix Airwolf
"And the dream will never die..."
Ninestars Hors ligne Membre Points: 2462 Défis: 24 Message

Citer : Posté le 05/04/2014 18:16 | #


C'est dans mon cours d'info
En python :
def trier(tab):
    """ trie tab dans l'ordre croissant par trie à bulle """
    n = len(tab)-1
    for i in range(0, n, 1):
        for j in range(0, n-i, 1):
            if tab[j] > tab[j+1]:
                tab[j], tab[j+1] = tab[j+1], tab[j]
    return tab
Dark storm Hors ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 05/04/2014 18:50 | #


Bon, dernier problème en vue (c'est pas dit que ce soit le der des der, mais bon ) :

ML_filled_polygon(), en plus d'être horriblement lente pour mon usage (faite pour des polygones quelconques), laisse un trou entre la ligne tracée avec Breshenham [ML_line()] entre les deux sommets et les deux sommets reliés par le polygon...

Du coup, je cherche un algo performant pour le remplissage de triangles (3 sommets distincts). De quel coté me conseillez-vous de fouiller ?
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Alex_1186 Hors ligne Membre Points: 1215 Défis: 46 Message

Citer : Posté le 05/04/2014 19:55 | #


@Dark Storm: Euh là par contre je sais pas... Nous on fait que des trucs abstraits! Remplir des polygones c'est bien trop concret!

@Ninestars: Ah...
Mais déjà, tu auras une erreur: quand i=0, j peut aller jusqu'à n-i=n, et tu testes tab[j+1] (out of bounds!)
Mais en fait, là je suis d'accord avec toi! C'est bien le même truc que moi, et ça ne correspond pas à ce que tu avais mis dans le code en C plus haut.
(j faisait 0 - 0,1 - 0,1,2 ... et là il fait bien 0,...,n - 0,...,(n-1) - 0,...,(n-2) etc... )
Bref, tout va bien.
Projets que je soutiens
Projets que je soutiens
Robscape 2 de Ray
Les tests vidéo de Marmotti
Mes projets
Mes projets
Une dizaine de projets top secrets...

Timeless Remix Airwolf
"And the dream will never die..."
Ninestars Hors ligne Membre Points: 2462 Défis: 24 Message

Citer : Posté le 05/04/2014 23:05 | #


Ah oui t'as raison pour le j+1, mince j'ai écrit ça dans le DM ^^' J'ai pas eu de bug alors j'ai pas vérifié minutieusement les indices :/
Après il y a une version encore plus optimisée avec un for et un while, voir wikipédia
Smashmaster Hors ligne Ancien modérateur Points: 4561 Défis: 253 Message

Citer : Posté le 06/04/2014 17:54 | # | Fichier joint


@Dark storm : Utilise l'algorithme du "pot de peinture" si tes triangles sont complètements vides :

Fonction PotDePeinture(x : entier, y : entier)
Début
    PlacerPixel(x,y)
    
    si non PixelAllumé(x-1,y) alors
        PotDePeinture(x-1,y)
    finSi
    
    si non PixelAllumé(x+1,y) alors
        PotDePeinture(x+1,y)
    finsi
    
    si non PixelAllumé(x,y+1) alors
        PotDePeinture(x,y+1)
    finSi

    si non PixelAllumé(x,y-1) alors
        PotDePeinture(x,y-1)
    finsi
FIN


Mais si tu te retrouves dans cette situation :
Cliquez pour découvrir
Cliquez pour recouvrir

Alors là je ne pourrais pas t'aider désolé :/
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 08/04/2014 19:19 | #


J'aurais une idée pour compléter celle de Smashmaster dans le cas embêtant qu'il cite.
Le principe serait de créer un tableau de char de 128*64 (ça fait juste de 8000 à 9000 octets), et d'attribuer à chaque point de l'écran une valeur, en fonction de la face à laquelle il appartient.

Virtuellement, on aurait ceci :



Et si je modifie un peu l'algorithme ça donne ça :
Fonction PotDePeinture(x : entier, y : entier,valeur : entier)
Début
    PlacerPixel(x,y,valeur) //j'écris ça pour faire simple, normalement la gestion de "valeur" ce fait avec le tableau attribué
    
    si Pixel(x-1,y)≠valeur alors
        PotDePeinture(x-1,y,valeur)
    finSi
    
    si Pixel(x+1,y)≠valeur alors
        PotDePeinture(x+1,y,valeur)
    finsi
    
    si non Pixel(x,y+1)≠valeur alors
        PotDePeinture(x,y+1,valeur)
    finSi

    si non Pixel(x,y-1)≠valeur alors
        PotDePeinture(x,y-1,valeur)
    finsi
FIN

Ce qui permettrait de remplir une zone définie par des côtés d'une valeur choisie.

Bien sûr vous me direz que ce n'est pas aussi simple que cela, car les points appartiennent à plusieurs faces à la fois. La gestion des valeurs sera plus complexe.
Limachi Hors ligne Youtuber Points: 2798 Défis: 67 Message

Citer : Posté le 08/04/2014 19:43 | #


si tu pense que c'est réalisable, autant faire un Z-Buffer, autrement dit: chaque char du tableau de 128*64 seras la distance séparant le point de la caméra, si un point devrait être affiché sur un autre point, on regarde la distance, si elle est inférieure, alors on prend le nouveau point, sinon on laisse tel quel (et vu qu'il y a pas seulement du noir, on peut réserver un bit pour la couleur du pixel, et utiliser les 7 autres pour la distance, ça laisse 128 unités de distance sur 7 bit)
Mes Programmes
Cliquer pour enrouler
-en basic: un programme nommé PICFMLIM convertissant une picture en code basic.
-en C:
-Un pong.
-Un projet en pause. Je compte le reprendre de temps en temps: Summer Cursed


-mon tuto sur les Str


Mes calto: G25+, G75
Mon minecraft en dévelopement


Projets et Programmes que je soutiens (sur une idée de Marmotti)
Cliquer pour enrouler
-Pokemon Jade de Dodormeur
-Portal2D de JavierXD
-CalCraft de Wime
-GeekBros du groupe GeekBrothers (Eiyeron,Siapran,KevKevVTT,Adbook,LIMachi)
Dark storm Hors ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 08/04/2014 20:47 | #


C'est ce que j'allais dire : autant faire un Z-buffer.
Faut que je teste, savoir si c'est assez rapide.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Positon Hors ligne Rédacteur Points: 2396 Défis: 57 Message

Citer : Posté le 08/04/2014 21:05 | #


Si vous le dites
Bon, ,je m'y connais pas trop, mais l'idée m'était venue en réfléchissant au problème du pot de peinture...
Limachi Hors ligne Youtuber Points: 2798 Défis: 67 Message

Citer : Posté le 09/04/2014 11:14 | #


normalement, le Z-Buffer est des dizaines a centaines de fois plus lent que le calcul d'ordre d'affichage des faces, mais il offre bien plus de possibilités pour des faces ce coupant entre elles.
le plus dur est de calculer la distance d'un point a afficher par rapport a la caméra, ça prend beaucoup de temps de calcul, ce qui n'est pas un pb pour un ordi, mais a un impact très important sur une calculatrice, sans parler que la taille du tableau (128*64 octets) n'est pas négligeable.

Mes Programmes
Cliquer pour enrouler
-en basic: un programme nommé PICFMLIM convertissant une picture en code basic.
-en C:
-Un pong.
-Un projet en pause. Je compte le reprendre de temps en temps: Summer Cursed


-mon tuto sur les Str


Mes calto: G25+, G75
Mon minecraft en dévelopement


Projets et Programmes que je soutiens (sur une idée de Marmotti)
Cliquer pour enrouler
-Pokemon Jade de Dodormeur
-Portal2D de JavierXD
-CalCraft de Wime
-GeekBros du groupe GeekBrothers (Eiyeron,Siapran,KevKevVTT,Adbook,LIMachi)
Lephenixnoir Hors ligne Administrateur Points: 24563 Défis: 170 Message

Citer : Posté le 09/04/2014 12:34 | #


Mais pourquoi ne pas utiliser un algorithme comme ML_filled_ploygon adapté pour le triangle ? Ou tout simplement réécrire cette fonction en la simplifiant par la constante 3 ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm Hors ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 09/04/2014 15:59 | #


Parce que je pige rien dans la fonction
Faudrait que PLL passe par là et me la commente, que je puisse refaire la mienne

Ajouté le 11/05/2014 à 11:17 :
Ca me fait penser qu'il faudrait que je poste le moteur, vu qu'il a bien avancé. Par contre, j'ai pas fini d'optimiser l'algo de remplissage de triangles.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Limachi Hors ligne Youtuber Points: 2798 Défis: 67 Message

Citer : Posté le 11/05/2014 21:14 | #


Dark Storm a écrit :
Parce que je pige rien dans la fonction
Faudrait que PLL passe par là et me la commente, que je puisse refaire la mienne

je vais tenter de te donner les détails de ce que j'ai compris de cette fonction:
-la fonction commence par classifier les points du polygone a remplir (je suis pas sur de l'ordre exact)
-puis elle trace "points par points" les lignes qui forment la bordure du polygone, et a la place d'afficher un pixel, la fonction garde les coordonnées qu'elle utilise pour tracer des lignes horizontales entre deux points a la même hauteur

disons que tu entre {{0,0},{7,10},{10,5}}, il va classifier comme ça (pour l'exemple, je suis pas sur si il met la pointe en bas ou en haut) {{0,0},{10,5},{7,10}}, puis va commencer une boucle partant de la plus petite valeur de Y des coordonnées jusqu'à la plus grande valeur de Y des coordonnées (utilisons i variant de 0 à 10 dans cet exemple), et va chercher les deux points sur les droites {{0,0},{10,5}}, {{0,0},{7,10}} et {{10,5},{7,10}} qui ont Y =i et on va tracer un ligne horizontale entre les deux.

je suis pas vraiment bon a enseigner a l'écrit, j'espère que tu parviendras quand même a voir ce que j'ai voulu dire.
Mes Programmes
Cliquer pour enrouler
-en basic: un programme nommé PICFMLIM convertissant une picture en code basic.
-en C:
-Un pong.
-Un projet en pause. Je compte le reprendre de temps en temps: Summer Cursed


-mon tuto sur les Str


Mes calto: G25+, G75
Mon minecraft en dévelopement


Projets et Programmes que je soutiens (sur une idée de Marmotti)
Cliquer pour enrouler
-Pokemon Jade de Dodormeur
-Portal2D de JavierXD
-CalCraft de Wime
-GeekBros du groupe GeekBrothers (Eiyeron,Siapran,KevKevVTT,Adbook,LIMachi)
Palra Hors ligne Membre Points: 276 Défis: 0 Message

Citer : Posté le 16/05/2014 00:01 | #


Et moi qui allait poster un sujet pour avoir de l'aide sur un projet de moteur 3D
Je me suis personellement inspiré d'OpenGL pour ce moteur, il est encore en construction et dispo ici https://github.com/palra/CasGL . Il est très différent du tien car il utilise des matrices de transformation pour effectuer toutes les translations, rotations et homothéties, après je ne sais pas quel est l'impact sur les performances de l'utilisation de matrices. Je viens de finir d'implémenter une caméra, mais j'ai une erreur de compilation que je ne comprends pas, mais en parler ici serait hors sujet
Calculatrice : Graph 35+ modée
Système d'exploitations : Apricity OS - Windows 10
Xavier59 Hors ligne Membre de CreativeCalc Points: 1337 Défis: 12 Message

Citer : Posté le 16/05/2014 07:47 | #


Alors je suis un peu en HS mais ...
Pendant que tu fais une lib 3D, pourquoi ne pas sortir une écriture en 3D ? :')
1337
Darkysun Hors ligne Membre Points: 1747 Défis: 52 Message

Citer : Posté le 16/05/2014 08:03 | #


bah une fois qu'il a fait sa lib 3d il pourra afficher tout ce qu'il veut
Si je ne réponds pas à un post depuis trop longtemps : envoyez-moi un message pour me le rappeler !




Dark storm Hors ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 16/05/2014 22:45 | #


Une écriture en 3D ?
Avec mon moteur 3D, tu peux afficher n'importe quelle forme 3D composée de faces planes
Après, la complexité d'un objet est croissante, genre initialiser un cube prend plus de 40 lignes : 8 sommets, 12 arêtes, 16 faces (2*8 triangles)
Finir est souvent bien plus difficile que commencer. — Jack Beauregard

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 184 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd