/** ******************************************************************************* @file /gui/engine/SceneGeom.h @brief Datove struktury pro geometrii sceny, vrcholy, site polygonu. @author Vajicek @version 0.1 ******************************************************************************/ #ifndef SCENEGEOM_H #define SCENEGEOM_H // #include "common/types.h" #include "common/mm.h" #include "gui/common/mymath.h" // #include namespace gui{ /****************************************************************************** nove struktury pro reprezentaci sceny chceme: -jak zachytit topologii? -chce to mit data tak aby se daly pouzit gl...Pointer funkce.. tzn pole v pravidelnych odstupech ******************************************************************************/ /// Uzivatelsky data. typedef void* UDATA; /// Typ pro barvu. typedef DWORD COL; /// Material ID typedef int MATID; #define NOMATERIAL -1 /** Zakladni struktura pro geometrii. size = (3+3+2+2)*4+4+4 = 48B na vrchol, scena tak 100000 * 5(vrchol nesdilenej) => 26MB DULEZITE: zakladni struktura vhodna k vykreslovani je pole TVertex */ struct TVertex { P3F position; P3F normal; P2F texture; P2F lightmap; COL color; UDATA udata; }; /// Pointer na vrcholy. typedef TVertex* PVertex; /// Vertex ID. typedef int VID; /// Material ID. typedef int LMAP; //FVD struct TMesh; /** Stroktora pro ukladani polygonu, nejcasteji trojuhelniku. */ struct TPolygon { P3F normal; MATID submat; LMAP lmap_id; // UDATA udata; // VID first, last; // TMesh* mesh; ///< odkaz na mesh }; /// Ukazatel na polygon. typedef TPolygon* PPolygon; /// Polygon ID. typedef int PID; //Mesh, material, index do seznamu polygonu #define MESHFLAG_TRINAGLES_ONLY 1 #define MESHFLAG_QUADS_ONLY 2 #define MESHFLAG_ANYGEOMETRY 4 #define MESHFLAG_NORMAL 8 #define MESHFLAG_VERTEX 16 #define MESHFLAG_TEXTURECOORD 32 #define MESHFLAG_COLOR 64 #define MESHFLAG_POINTS_ONLY 128 //FWD struct T3DObject; /** Mesh. */ struct TMesh { PID first, last; int iFlag; ///< jak/co se ma vykreslovat MATID mat; T3DObject* obj; HWID display_list; }; /// Pointer na mesh. typedef TMesh* PMesh; /** Objekt, databaze vsecho. */ struct T3DObject { int mesh_c; TMesh *mesh; int vert_c; TVertex* vert; int poly_c; TPolygon* poly; }; /// Pointer na objekt typedef T3DObject* P3DObject; /*****************************************************************************/ /// @name Klonovani geometrie. //@{ /** Kopirovani meshu. @param src Zdroj. @param dest Cil. */ extern void Clone(TMesh* src,TMesh* dest); /** Kopirovani objektu. @param src Zdroj. @param dest Cil. */ extern void Clone(T3DObject* src,T3DObject* dest); //@} /*****************************************************************************/ /** @name Funkce pro konstrukci geometrie. meli by fungovat stavove, pridavat vzdy k poslednimu utvaru NEVYHODA: existujici geometrie se nebude dat menit topologicky(myslim,ze nevadi) dalo by se vyresit...ale s presouvanim, preindexovanim addmesh, addpoly, addvetex,addvertex, addpoly, ver,ver,.. poly,.... */ //@{ /** Vytvoreni objektu. @return Geometrie objektu. */ extern T3DObject* Create3DObject(); /** Pridej mesh do objektu. @param o Objekt. @param flags Priznaky. @return Novy mesh. */ extern TMesh* AddMeshToObject(T3DObject* o, int flags); /** Pridej polygon do objektu. Prida do posledniho meshe. @param o Objekt. @param m Mesh. @return Novy polygon. */ extern TPolygon* AddPolygonToObject(T3DObject* o, TMesh* m); /** Pridej vrchol do Objektu. Prida do posledniho polygonu v poslednim meshi. @param o Objekt. @param x Souradnice X. @param y Souradnice Y. @param z Souradnice Z. @return Novy vrchol. */ extern TVertex* AddVertexToObject(T3DObject* o, float x, float y, float z); /** Dealokace objektu. @param obj Objekt. */ extern void Destroy3DObject(T3DObject* obj); //@} /*****************************************************************************/ /** Paprsek. */ class TRay //## { public: /// pocatecni bod paprsku P3F start; /// smerovy vektor paprsku P3F dir; /// vzdalenosti pocatku a konce paprsku od start float near_clip, far_clip; /** Nastavi pocatek a smer paprsku. @param _start Pocatek. @param _dir Smer. @param _near_clip Oriznuti ze zacatku. @param _far_clip Oriznuti od konce. */ void set(P3F _start, P3F _dir, float _near_clip, float _far_clip); /** Vzdalenost od paprsku. Za predpokladu, ze dir je znormalizovany, tak to vraci druhou mocninu vzdalenosti bodu x od paprsku. @param x Bod. @return Vzdalenost od paprsku. */ float dist2(P3F *x); /** Prusecik s rovinou. Do inter ulozi prusecik paprsku s rovinou z* = z; vraci false pokud takovy bod neexistuje. @param inter Prusecik. @param z Rovina z. */ bool zPlaneIntersect(P2F *inter, float z); /** Bod na paprsku. Do p3f da start + t * dir. @param t Parametr. @param p3f Bod na paprsku. */ void getP3F(float t, P3F *p3f); /** Konstruktor. @param sx @param sy @param sz @param dx @param dy @param dz @param _near_clip @param _far_clip */ TRay(float sx, float sy, float sz, float dx, float dy, float dz, float _near_clip, float _far_clip); /** Destruktor. */ TRay(); }; /*****************************************************************************/ /** Gradient. */ class TGrad //## { public: P3F dx, dy, dz; }; /*****************************************************************************/ /// Rovina #define PLANE_ABOVE 1 #define PLANE_BELOW 2 #define PLANE_IN 0 /** Rovina. */ class TPlane //## { public: P4F dat; ///< rovina /** Urci rovinu podle bodu, ktery v ni lezi a normaly @param vert Vrchol. @param norm Normala. */ void set(P3F vert, P3F norm); /** Urci rovinu primo. @param a Parametr roviny. @param b @param c @param d */ void set(float a, float b, float c, float d); /** Pozice bodu vzhledem k rovine @return PLANE_ABOVE, PLANE_BELOW, PLANE_IN */ int Collision(P3F *p3f); /** Vraci zda poloprimka protina plochu, do t da parametr paprsku pruseciku. @param[in] ray Paprsek. @param[out] t Parametr. */ bool Collision(TRay *ray, float *t); }; /*****************************************************************************/ /** Axis aligned bounding box. */ class TAABB //## { public: P3F aabbCenter; ///< Stred kvadru. P3F aabbDim; ///< Rozmery kvadru. P3F mins; ///< nejmensi souradnice vrcholu AABB P3F maxs; ///< nejvetsi souradnice vrcholu AABB /** Spojeni s kvadrem. @param aabb Druhy kvadr. */ void addAABB(TAABB* aabb); /** Zkopirovani kvadru. @param aabb Zdroj kope. */ void copyAABB(TAABB* aabb); /** Pro pretizeni v potomcich. */ virtual void calculateAABB(); /** Vykresleni pro testovaci ucely. */ void drawAABB(); /** Zjisti zda dva AABB maji neprazdny prunik. @param aabb Kolidovany aabb. @return Zda doslo ke kolizi. */ bool Collision(TAABB *aabb); /** Zjisti zda dva AABB maji neprazdny prunik a do rati da pomer Vol(Prunik)/Vol(this). @param aabb Kolidovany aabb. @param[out] ratio Pomer. @return Zda doslo ke kolizi. */ bool Collision(TAABB *aabb, float *ratio); /** Zjisti, zda p3f lezi uvnitr aabbb @param p3f Bod. @return Zda lezi uvnitr. */ bool isIn(P3F *p3f); /** Zjisti zda ray prochazi timto AABB a do t pripadne ulozi nejmensi parametr, ze start+t*dir je bod z AABB. @param ray Paprsek. @param[out] t Parametr.. @return Zda dochazi ke kolizi. */ virtual bool Collision(TRay* ray, float *t); /** Z vektoru aabbCenter a aabbDim spocita vektory mins a maxs. */ void calculateMinsMaxs(); }; /*****************************************************************************/ /** Pohledovy jehlan, neni kolizni objekt. */ class TFrustum: public TAABB { private: /** Transformace do souradnic obrazovky. transformuje bod ze svetovych souradnic do souradnic obrazovky (-1,1)x(-1,1) x(near_clip,far_clip). Pokud lezi vertex za kamerou, vraci false, jinak true @param[in] vert Pozice. @param[out] pos Transformovana Pozice. @return Zda se nachazi pred, nebo za kamerou. */ bool Vertex2Frustum(P3F *pos, P3F *vert); public: /// pozice kamrey (vrcholu jehlanu) P3F pos; /// jednotkovy smeovy vektor prochazejici stredem podstavy jehlan P3F dir; /// vektory kolme na vektor dir, jejich delky jsou relativni P3F up, down, left, right; /// vzdalenost predni orezavaci roviny od vrcholu float near_clip; /// vzdalenost zadni orezavaci roviny od vrcholu float far_clip; /// alternativni definice frusta pomoci sesti rovin TPlane planes[6]; /** Zjisti, zda bod p3f je uvnitr jehlanu kamery. @param p3f Testovany bod. @return Zda se nachazi uvnitr. */ inline bool IsIn(P3F *p3f); /** Zjisti, zda bounding box ma s frustem neprazdny prunik. @param aabb Testovany AABB. @return Zda se nachazi pred, nebo za kamerou. */ bool IsIn(TAABB *aabb); /** Spocita AABB. @see TAABB */ virtual void calculateAABB(); /** Spocita roviny frusta */ void calculatePlanes(); }; /*****************************************************************************/ /// @name Kolize. //@{ /** Kolize paprsku s objektem. @param o Objekt. @param r Paprsek. @param[out] intersect Prusecik. @param[out] p Polygon. @return Zda protina objekt.. */ extern int Collide(T3DObject* o,TRay* r,P3F* intersect,TPolygon** p); /** Kolize paprsku s meshem. @param m Mesh. @param r Paprsek. @param[out] intersect Prusecik. @param[out] p Poligon. @return Zda protina mesh. */ extern int CollideMesh(TMesh* m,TRay* r,P3F* intersect,TPolygon** p); //@} }//namespace #endif /*****************************************************************************/