Pysique, un moteur 3D simpliste !

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Hellow !

(Suite aux changements que je vois s'opérer sur OCR petit à petit, je préfère dorénavant faire mes topics de présentation de projet(s) ici :D)

Donc je me présente, Folaefolc / Lubzorg / Artz / Loodoor / Onsànfoù (que de pseudos !), 16 ans, étudiant en 1ère S :)

J'adore Python (3) et tout ce qui touche à la programmation plus généralement :D

Le projet

Ici je vous présente Pysique, un petit moteur 3D sans physique pour le moment, mais tournant correctement (environ 90 FPS pour 40 objets).

Ce moteur se base sur Pygame (pour Python 3.4) et une partie du code de Codentronix (sans lui, je n'aurais pas pu définir aussi facilement tous les objets disponibles actuellement)

Genèse

Je voulais me lancer dans la 3D, mais Opengl (pour python) n'était disponible que pour Python 2.7

Du coup, j'ai commencé à écrire mon mini moteur (je dois dire que ce qui m'a le plus donné envie de le faire est le projet Nazarra de Lynix)

Avancement

Pour le moment, j'arrive à afficher des cubes, pyramides, sphères / cercles, carrés dans un espace 3D. Je travaille encore sur le système de rotation groupée / déplacement groupé (dans un plan donc)

On peut choisir d'en afficher uniquement les points, ou bien les arrêtes, ou encore de les remplir

Objectif

A terme, voici les fonctionnalités que j'aimerai supporter :

  • la déformation des objets (carré -> parallélépipède)

  • le triangle (dans un espace 3D)

  • la gestion groupée des objets (donc dans un plan)

  • la gestion de la physique 2D (avec z fixé lors des calculs) :

    • ressorts

    • saut

    • gravité

    • accélération // décélération

    • attraction gravitationnelle (sensiblement pareil à la gravité en fait, sauf que l'on a une déviation de trajectoire pour un objet en mouvement ici)

    • le rebond (ressemble aussi au saut effectivement)

    • les collisions

  • le raycast en 2D

  • le raycast en 3D

  • la gestion de vecteurs 2D

  • la gestion de vecteurs 3D

  • le shading

  • le texturing

Actuellement, la création de 4 objets tous différents prend 0.61 secondes

Et la création de 40 objets en prend 0.63 :D

Sinon je travaille encore sur la réduction du radius des sphères en fonction de la distance ;)

Images

affichage des points

affichage des faces (à retravailler je sais :) )

affichage des arrêtes

Liens

Mon Github :)

Voilà voilà :)

Édité par Cithoran

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+9 -0
Auteur du sujet

Content de voir des intéressés :)

Je suis en train de m'attaquer au texturing à l'aide du code source de Gh0stenstein :)

Je vais simplifier le moteur, et le recoder surement entièrement, il est assez dégueu (celui de gh0st) :) puis faire une scene de démo pour tester tout ca ;) !

Édité par Cithoran

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+1 -0
Auteur du sujet

holà !

j'ai réécrit (sur papier) le systeme de raycasting et d'affichage de textures

et sans me vanter, je pense (avec quelques prises de tete surement) pouvoir gerer des maps à la wolfenstein mais avec plusieurs niveaux !

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+0 -0

yop, sympa ton projet =)

j'ai lu un peu tes sources, et j'aimerais te faire part d'un truc sur ta class Point3D dans engine.py

tes 4 méthodes tu retournes un nouvel objet Point3D alors que tu pourrais simplement modifier l'instance de ta class avec les nouvelles coordonnées calculé nan ?

1
2
3
4
5
6
7
8
def rotateX(self, angle):
        """ Rotates the point around the X axis by the given angle in degrees. """
        rad = math.radians(angle)
        cosa = math.cos(rad)
        sina = math.sin(rad)
        y = self.y * cosa - self.z * sina
        z = self.y * sina + self.z * cosa
        return Point3D(self.x, y, z)

deviendrais

1
2
3
4
5
6
7
def rotateX(self, angle):
        """ Rotates the point around the X axis by the given angle in degrees. """
        rad = math.radians(angle)
        cosa = math.cos(rad)
        sina = math.sin(rad)
        self.y = self.y * cosa - self.z * sina
        self.z = self.y * sina + self.z * cosa

à mon avis tu gagnerais en terme de perf memoire puisque tu évites l’instanciation d'un nouvel objet

j'ai pas eu le temps de lire toute tes sources mais si tu veux je peux y jeter un coup d’oeil plus tard =)

Édité par djavrell

+2 -0
Auteur du sujet

c'est vrai que c'est pas une bete idée, mais pas non plus une bonne ^^

je m'explique :

1
2
def rotateX(self, dir=1):
        self.angleX += dir

c'est du code ligne 425, dans la class Pyramide.

Si j'appliquais ta méthode, 1 mon angle de rotation ne serait pas récupérable après avoir fait une nouvelle rotation (enfin techniquement si, mais ca demande du code en plus, un peu degueu meme), et 2, mes objets tourneraient de plus en vite, selon un rapport de rotation / secondes qui serait égal à FPS * angleX (ou Y, ou Z), et angle X (ou Y ou Z) augmenterai de x toutes les secondes ^^'

du coup au bout de 90 FPS, on aura une vitesse de 90 ** 2 (en supposant que je veuille une rotation de 1 à chaque fois) si je ne me trompe pas.

et je souhaite tout de meme avoir une vitesse constante !

sinon, c'est possible comme tu l'entends je pense, mais il faudrait plutot diminuer l'angle de rotation à chaque appel :/

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+0 -0

je vois pas pourquoi tes objets tourneraient de plus en plus vite, je fais exactement la même chose que toi, j'évite juste la création d'une nouvelle class en modifiant l'instance courant du point en question

autre chose, qu'elle est le rapport entre ta fonction ligne 425 ou tu modifie une variable et ta class Point3D ?

de plus, avec ta méthode, pour prendre en compte le changement, le code doit ressembler à ca vu que tu retourne une instance

1
2
p = Point3D(1, 1, 1)
p = p.rotateX(10)

alors qu'avec ma méthode, tu obtiens:

1
2
p = Point3D(1, 1, 1)
p.rotateX(10)

si tu veux réduire la taille de ton code, je te conseille aussi de faire de l'héritage sur tes class Pyramide & cie, tu peux gagner environ 20 lignes par class

+1 -0

Cette réponse a aidé l'auteur du sujet

je peux pas t'en vouloir de dire des chose fausses, tu as l'aire d'apprendre seul alors que je suis en 3ème année d'école informatique (epitech) ;)

pour l'héritage je te conseil ca, ton code n'en sera que plus claire après et si tu doit apporter une modification, tu n'aurais qu'un endroit à modifier ;)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class BaseObject():
    def __init__(self, /*tes arguments*/)
        self.angleX, self.angleY, self.angleZ = 0, 0, 0
        self.xpos = xpos
        self.ypos = ypos
        self.zpos = zpos

    def draw(self):
        pass

    def set_default(self):
        pass

    def rotateX(self, dir=1):
        self.angleX += dir

    def rotateY(self, dir=1):
        self.angleY += dir

    def rotateZ(self, dir=1):
        self.angleZ += dir

    def moveX(self, dir=1):
        self.xpos += dir

    def moveY(self, dir=1):
        self.ypos += dir

    def moveZ(self, dir=1):
        self.zpos += dir

class Sphere(BaseObject):
    # le reste de ton code
    pass
+4 -0

— Je coupe un peut votre conversation ^^

L'objectif c'est donc d’expérimenter la création d'un moteur 3D avec python ? En terme de perf ça reste toujours intéressant ? La t'es encore au début mais si on souhaite afficher une grosse scène j'entends, ça va pas être "lent" ? Je pose la question en tant que Artiste 3D, côté perf. et autre je n'ai aucune idée.

Auteur du sujet

oui, c'est un peu ça ;)

niveau perf, pour le moment, avec 10 cubes (en rotation) j'ai environ 150-200 FPS

avec 100 cubes, j'en ai environ 30 xD

donc il me reste de l'optimisation à faire, surtout avec les objets qui ne sont pas visibles :)

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+0 -0
Auteur du sujet

yop tout le monde !

Le projet continue hein ^^

Et les ajouts du jour sont :

  • une class "mère" Scene pour lancer … une scene ! Et y ajouter des objets bien entendu :)

  • un nouvel objet créé juste pour le fun : l'hypercube

  • un objet Line

mon chtiot hypercube !

pour ce qui du code, y a maintenant un fichier basis.py qui contient mes définitions de points, de vecteurs 2D, de Camera ; un autre fichier constants.py dans lequel je n'ai pour le moment que des couleurs :) … et un fichier engine.py, le coeur de la bete !

Sinon, je vais aller optimiser le bousin je pense, pour n'afficher que les objets étant dans la scène

Édité par Cithoran

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte