Nouveau framework et moteur 3D
Schéma d'un moteur 3D simple à appréhender, fonctionnel (objets procéduraux - metaball, terrains -, effets type post-prod, rendus hiérarchiques - personnages -, GUI 3D, films en tant que textures, particules. Il faut rassembler toutes les idées qui surgissent.
Plusieurs Scene3D gérées par un moteur de gestion d'objets (faut-il plusieurs moteur 3D ?). Chaque objets à une interface de rendu qui prépare ses données spécifiquement pour un moteur de rendu, géré par Renderer appelé par le moteur. Un objet 3D est rattaché à une scène et un viewport est rattaché à un moteur 3D. Une scène peut être rattachée à plusieurs viewport. Un objet 3D contient sa description 3D qu'il peut communiquer sous certaines formes à son renderer via son interface de rendu. S'il y a n objets il y a approximativement log(n) interfaces de rendus présentes en run-time. Une interface de rendu peut être : objet classique (géo+topo+texture), objet procédural, moteur de particule etc. Des sous renderer pourront gérer les films au sein de textures. La hiérarchie est gérée par le moteur haut-niveau, la position et l'orientation d'un objet sont contenues dans l'objet lui-même.
A faire de toute urgence donc.
J'ai rassemblé ci-dessous des notes C++ représentant les axiomes de bases implémentées par le framework pour toutes les utilisations auxquelles je le destine.
class BaseObject
{
private:
BaseObject(); //On ne peut pas faire de new Engine() par exemple
~BaseObject(); //Seul une factory peut effacer réellement un objet, sinon il est collecté lors d'un remove
friend class Factory();
public:
//Fonctions génériques de (dé)sérialisations et d'import/export XML
HCODE toXML(XMLElement* dest);
HCODE toXML(String& dest);
HCODE fromXML(const XMLElement* obj); //Initialise l'objet courant depuis une description XML
HCODE fromXML(const String& obj); //Initialise l'objet courant depuis une description XML
HCODE serialize(Flow& output);
HCODE unserialize(Flow& input);
//Fonctions communiquant avec d'autres objets
HCODE send(ObjectId dest, Message& msg)
HCODE getNextMessage(Message& msg);
HCODE flushMessage();
//Thread management de l'objet
//Gestion des propriétés de l'objet : ses données / champs, ses méthodes / actions
HCODE Get(const String& fieldName, Field& field); //Récupère la valeur d'un champ de l'objet courant
HCODE Set(const String& fieldName, const Field& field); //Fixe la valeur d'un champ de l'objet courant
String compName = type de l'objet
//Références maintenues par l'objet : des références
delete(); //Efface l'objet et les éventuels liens qu'il avait avec d'autres
//.............
//Ses champs
Array<Field> Fields;
ObjectId ObjectSchema; //Référence du schéma (la structure) de l'objet
uint Id; //L'Id unique de l'objet courant
};
Objets utilitaires : Field, Array, String, HashTable, Flow (pour les flux de lecture ou d'écriture, sur disque, HTTP ou autres.).
//Tous les objets sont représentés par leur Id, unique, et gérées par un singleton : Objects
class ObjectId
{
operator->(const String& funcName);
};
//Une classe qui crée des composants
class Objects
{
HCODE RegisterType() //Enregistre un type connu et ses champs
HCODE FromType //IDs de tous les objets d'un certain type
HCODE Select //Requête complète (plus complexe mais adapté à des utilisations plus pointues que FromType)
ObjectId FromId() //Renvoie l'ObjectId d'un objet donné
ObjectId createComponent(const String& compName)
{
BaseObject* NewObject = new BaseObject();
NewObject->ObjectSchema = Type[compName][\"schema\"];
}
};
//Une fonction globale pour créer des composants
ObjectId CreateComponent(const String& compName)
{
ObjectId Fact = Objects->getFactory();
if (!Fact) return LastError();
return Fact->createComponent(compName);
};
Selection d'objets
Il faut une méthode pour, avec une zone rectangulaire de sélection, sélectionner le plus rapidement possible les objets, 2D pour commencer, dont la bounding-box est interceptée. Je pense à deux range trees (ou des priority tree) pour le stockage des bbox (AABB) - un arbre pour chacune des dimensions considérées, et à deux hash-tables pour le parcours des deux arbres et l'instersection des 4 interrogations suivantes, si S est l'ensemble des objets de la scène :
L1 = { o de S tel que (o.bbox.x1 || o.bbox.x2) >= selectArea.y1 && !(o.bbox.x1 > selectArea.y2) }
L2 = L1 ∩ { o de S tel que (o.bbox.x1 || o.bbox.x2) <= selectArea.y2 && !(o.bbox.x2 < selectArea.y1) }
L3 = L2 ∩ { o de S tel que (o.bbox.y1 || o.bbox.y2) >= selectArea.y1 && !(o.bbox.y1 > selectArea.y2) }
L4 = L3 ∩ { o de S tel que (o.bbox.y1 || o.bbox.y2) >= selectArea.y2 && !(o.bbox.y2 > selectArea.y1) }
