//--------------------------------------------------------------------------- #ifndef Model3dH #define Model3dH #include "opengl/glew.h" #include "Parser.h" #include "dumb3d.h" using namespace Math3D; #include "Float3d.h" #include "VBO.h" struct GLVERTEX { vector3 Point; vector3 Normal; float tu,tv; }; class TStringPack { char *data; //+0 - 4 bajty: typ kromki //+4 - 4 bajty: długość łącznie z nagłówkiem //+8 - obszar łańcuchów znakowych, każdy zakończony zerem int *index; //+0 - 4 bajty: typ kromki //+4 - 4 bajty: długość łącznie z nagłówkiem //+8 - tabela indeksów public: char* String(int n); char* StringAt(int n) {return data+9+n;}; __fastcall TStringPack() {data=NULL; index=NULL;}; void __fastcall Init(char *d) {data=d;}; void __fastcall InitIndex(int *i) {index=i;}; }; class TMaterialColor { public: __fastcall TMaterialColor() {}; __fastcall TMaterialColor(char V) { r=g=b=V; }; // __fastcall TMaterialColor(double R, double G, double B) __fastcall TMaterialColor(char R, char G, char B) { r=R; g=G; b=B; }; char r,g,b; }; /* struct TMaterial { int ID; AnsiString Name; //McZapkie-240702: lepiej uzywac wartosci float do opisu koloru bo funkcje opengl chyba tego na ogol uzywaja float Ambient[4]; float Diffuse[4]; float Specular[4]; float Transparency; GLuint TextureID; }; */ /* struct THitBoxContainer { TPlane Planes[6]; int Index; inline void __fastcall Reset() { Planes[0]= TPlane(vector3(0,0,0),0.0f); }; inline bool __fastcall Inside(vector3 Point) { bool Hit= true; if (Planes[0].Defined()) for (int i=0; i<6; i++) { if (Planes[i].GetSide(Point)>0) { Hit= false; break; }; } else return(false); return(Hit); }; }; */ /* Ra: tego nie będziemy już używać, bo można wycisnąć więcej typedef enum {smt_Unknown, //nieznany smt_Mesh, //siatka smt_Point, smt_FreeSpotLight, //punkt świetlny smt_Text, //generator tekstu smt_Stars //wiele punktów świetlnych } TSubModelType; */ //Ra: specjalne typy submodeli, poza tym GL_TRIANGLES itp. const int TP_ROTATOR=256; const int TP_FREESPOTLIGHT=257; const int TP_STARS=258; const int TP_TEXT=259; enum TAnimType //rodzaj animacji {at_None, //brak at_Rotate, //obrót względem wektora o kąt at_RotateXYZ, //obrót względem osi o kąty at_Translate, //przesunięcie at_SecondsJump, //sekundy z przeskokiem at_MinutesJump, //minuty z przeskokiem at_HoursJump, //godziny z przeskokiem 12h/360° at_Hours24Jump, //godziny z przeskokiem 24h/360° at_Seconds, //sekundy płynnie at_Minutes, //minuty płynnie at_Hours, //godziny płynnie 12h/360° at_Hours24, //godziny płynnie 24h/360° at_Billboard, //obrót w pionie do kamery at_Wind, //ruch pod wpływem wiatru at_Sky, //animacja nieba at_IK=0x100, //odwrotna kinematyka - submodel sterujący (np. staw skokowy) at_IK11=0x101, //odwrotna kinematyka - submodel nadrzędny do sterowango (np. stopa) at_IK21=0x102, //odwrotna kinematyka - submodel nadrzędny do sterowango (np. podudzie) at_IK22=0x103, //odwrotna kinematyka - submodel nadrzędny do nadrzędnego sterowango (np. udo) at_Digital=0x200, //dziesięciocyfrowy licznik mechaniczny (z cylindrami) at_DigiClk=0x201, //zegar cyfrowy jako licznik na dziesięciościanach at_Undefined=0x800000FF //animacja chwilowo nieokreślona }; class TModel3d; class TSubModelInfo; class TSubModel {//klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów //Ra: ta klasa ma mieć wielkość 256 bajtów, aby pokryła się z formatem binarnym //Ra: nie przestawiać zmiennych, bo wczytują się z pliku binarnego! private: TSubModel *Next; TSubModel *Child; int eType; //Ra: modele binarne dają więcej możliwości niż mesh złożony z trójkątów int iName; //numer łańcucha z nazwą submodelu, albo -1 gdy anonimowy public: //chwilowo TAnimType b_Anim; private: int iFlags; //flagi informacyjne: //bit 0: =1 faza rysowania zależy od wymiennej tekstury 0 //bit 1: =1 faza rysowania zależy od wymiennej tekstury 1 //bit 2: =1 faza rysowania zależy od wymiennej tekstury 2 //bit 3: =1 faza rysowania zależy od wymiennej tekstury 3 //bit 4: =1 rysowany w fazie nieprzezroczystych (stała tekstura albo brak) //bit 5: =1 rysowany w fazie przezroczystych (stała tekstura) //bit 7: =1 ta sama tekstura, co poprzedni albo nadrzędny //bit 8: =1 wierzchołki wyświetlane z indeksów //bit 9: =1 wczytano z pliku tekstowego (jest właścicielem tablic) //bit 13: =1 wystarczy przesunięcie zamiast mnożenia macierzy (trzy jedynki) //bit 14: =1 wymagane przechowanie macierzy (animacje) //bit 15: =1 wymagane przechowanie macierzy (transform niejedynkowy) union {//transform, nie każdy submodel musi mieć float4x4 *fMatrix; //pojedyncza precyzja wystarcza //matrix4x4 *dMatrix; //do testu macierz podwójnej precyzji int iMatrix; //w pliku binarnym jest numer matrycy }; int iNumVerts; //ilość wierzchołków (1 dla FreeSpotLight) int iVboPtr; //początek na liście wierzchołków albo indeksów int iTexture; //numer nazwy tekstury, -1 wymienna, 0 brak float fVisible; //próg jasności światła do załączenia submodelu float fLight; //próg jasności światła do zadziałania selfillum float f4Ambient[4]; float f4Diffuse[4]; //float ze względu na glMaterialfv() float f4Specular[4]; float f4Emision[4]; float fWireSize; //nie używane, ale wczytywane float fSquareMaxDist; float fSquareMinDist; //McZapkie-050702: parametry dla swiatla: float fNearAttenStart; float fNearAttenEnd; int bUseNearAtten; //te 3 zmienne okreslaja rysowanie aureoli wokol zrodla swiatla int iFarAttenDecay; //ta zmienna okresla typ zaniku natezenia swiatla (0:brak, 1,2: potega 1/R) float fFarDecayRadius; //normalizacja j.w. float fCosFalloffAngle; //cosinus kąta stożka pod którym widać światło float fCosHotspotAngle; //cosinus kąta stożka pod którym widać aureolę i zwiększone natężenie światła float fCosViewAngle; //cos kata pod jakim sie teraz patrzy //Ra: dalej są zmienne robocze, można je przestawiać z zachowaniem rozmiaru klasy int TextureID; //numer tekstury, -1 wymienna, 0 brak int bWire; //nie używane, ale wczytywane //short TexAlpha; //Ra: nie używane już GLuint uiDisplayList; //roboczy numer listy wyświetlania float Opacity; //nie używane, ale wczytywane //ABu: te same zmienne, ale zdublowane dla Render i RenderAlpha, //bo sie chrzanilo przemieszczanie obiektow. //Ra: już się nie chrzani float f_Angle; float3 v_RotateAxis; float3 v_Angles; public: //chwilowo float3 v_TransVector; float8 *Vertices; //roboczy wskaźnik - wczytanie T3D do VBO int iAnimOwner; //roboczy numer egzemplarza, który ustawił animację TAnimType b_aAnim; //kody animacji oddzielnie, bo zerowane public: float4x4 *mAnimMatrix; //macierz do animacji kwaternionowych (należy do AnimContainer) char space[8]; //wolne miejsce na przyszłe zmienne (zmniejszyć w miarę potrzeby) public: TSubModel **smLetter; //wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D) TSubModel *Parent; //nadrzędny, np. do wymnażania macierzy int iVisible; //roboczy stan widoczności //AnsiString asTexture; //robocza nazwa tekstury do zapisania w pliku binarnym //AnsiString asName; //robocza nazwa char *pTexture; //robocza nazwa tekstury do zapisania w pliku binarnym char *pName; //robocza nazwa private: //int __fastcall SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3 *pt,GLVERTEX *Vertices); int __fastcall SeekFaceNormal(DWORD *Masks,int f,DWORD dwMask,float3 *pt,float8 *Vertices); void __fastcall RaAnimation(TAnimType a); public: static int iInstance; //identyfikator egzemplarza, który aktualnie renderuje model static GLuint *ReplacableSkinId; static int iAlpha; //maska bitowa dla danego przebiegu static double fSquareDist; static TModel3d* pRoot; static AnsiString* pasText; //tekst dla wyświetlacza (!!!! do przemyślenia) __fastcall TSubModel(); __fastcall ~TSubModel(); void __fastcall FirstInit(); int __fastcall Load(cParser& Parser, TModel3d *Model,int Pos,bool dynamic); void __fastcall ChildAdd(TSubModel *SubModel); void __fastcall NextAdd(TSubModel *SubModel); TSubModel* __fastcall NextGet() {return Next;}; TSubModel* __fastcall ChildGet() {return Child;}; int __fastcall TriangleAdd(TModel3d *m,int tex,int tri); float8* __fastcall TrianglePtr(int tex,int pos,int *la,int *ld,int*ls); //float8* __fastcall TrianglePtr(const char *tex,int tri); //void __fastcall SetRotate(vector3 vNewRotateAxis,float fNewAngle); void __fastcall SetRotate(float3 vNewRotateAxis,float fNewAngle); void __fastcall SetRotateXYZ(vector3 vNewAngles); void __fastcall SetRotateXYZ(float3 vNewAngles); void __fastcall SetTranslate(vector3 vNewTransVector); void __fastcall SetTranslate(float3 vNewTransVector); void __fastcall SetRotateIK1(float3 vNewAngles); TSubModel* __fastcall GetFromName(AnsiString search,bool i=true); TSubModel* __fastcall GetFromName(char *search,bool i=true); void __fastcall RenderDL(); void __fastcall RenderAlphaDL(); void __fastcall RenderVBO(); void __fastcall RenderAlphaVBO(); //inline matrix4x4* __fastcall GetMatrix() {return dMatrix;}; inline float4x4* __fastcall GetMatrix() {return fMatrix;}; //matrix4x4* __fastcall GetTransform() {return Matrix;}; inline void __fastcall Hide() {iVisible=0;}; void __fastcall RaArrayFill(CVertNormTex *Vert); //void __fastcall Render(); int __fastcall FlagsCheck(); void __fastcall WillBeAnimated() {if (this) iFlags|=0x4000;}; void __fastcall InitialRotate(bool doit); void __fastcall DisplayLists(); void __fastcall Info(); void __fastcall InfoSet(TSubModelInfo *info); void __fastcall BinInit(TSubModel *s,float4x4 *m,float8 *v,TStringPack *t,TStringPack *n=NULL,bool dynamic=false); void __fastcall ReplacableSet(GLuint *r,int a) {ReplacableSkinId=r; iAlpha=a;}; void __fastcall TextureNameSet(const char *n); void __fastcall NameSet(const char *n); //Ra: funkcje do budowania terenu z E3D int __fastcall Flags() {return iFlags;}; void __fastcall UnFlagNext() {iFlags&=0x00FFFFFF;}; void __fastcall ColorsSet(int *a,int *d,int*s); inline float3 Translation1Get() {return fMatrix?*(fMatrix->TranslationGet())+v_TransVector:v_TransVector;} inline float3 Translation2Get() {return *(fMatrix->TranslationGet())+Child->Translation1Get();} void __fastcall ParentMatrix(float4x4 *m); float __fastcall MaxY(const float4x4 &m); void __fastcall AdjustDist(); }; class TSubModelInfo {//klasa z informacjami o submodelach, do tworzenia pliku binarnego public: TSubModel *pSubModel; //wskaźnik na submodel int iTransform; //numer transformu (-1 gdy brak) int iName; //numer nazwy int iTexture; //numer tekstury int iNameLen; //długość nazwy int iTextureLen; //długość tekstury int iNext,iChild; //numer następnego i potomnego static int iTotalTransforms; //ilość transformów static int iTotalNames; //ilość nazw static int iTotalTextures; //ilość tekstur static int iCurrent; //aktualny obiekt static TSubModelInfo* pTable; //tabele obiektów pomocniczych __fastcall TSubModelInfo() {pSubModel=NULL; iTransform=iName=iTexture=iNext=iChild=-1; //nie ma iNameLen=iTextureLen=0; } void __fastcall Reset() {pTable=this; //ustawienie wskaźnika tabeli obiektów iTotalTransforms=iTotalNames=iTotalTextures=iCurrent=0; //zerowanie liczników } __fastcall ~TSubModelInfo() {}; }; class TModel3d : public CMesh { private: //TMaterial *Materials; //int MaterialsCount; //Ra: nie używane //bool TractionPart; //Ra: nie używane TSubModel *Root; //drzewo submodeli int iFlags; //Ra: czy submodele mają przezroczyste tekstury public: //Ra: tymczasowo int iNumVerts; //ilość wierzchołków (gdy nie ma VBO, to m_nVertexCount=0) private: TStringPack Textures; //nazwy tekstur TStringPack Names; //nazwy submodeli int *iModel; //zawartość pliku binarnego int iSubModelsCount; //Ra: używane do tworzenia binarnych AnsiString asBinary; //nazwa pod którą zapisać model binarny public: inline TSubModel* __fastcall GetSMRoot() {return(Root);}; //double Radius; //Ra: nie używane __fastcall TModel3d(); __fastcall TModel3d(char *FileName); __fastcall ~TModel3d(); TSubModel* __fastcall GetFromName(const char *sName); //TMaterial* __fastcall GetMaterialFromName(char *sName); TSubModel* __fastcall AddToNamed(const char *Name, TSubModel *SubModel); void __fastcall AddTo(TSubModel *tmp,TSubModel *SubModel); void __fastcall LoadFromTextFile(char *FileName,bool dynamic); void __fastcall LoadFromBinFile(char *FileName,bool dynamic); bool __fastcall LoadFromFile(char *FileName,bool dynamic); void __fastcall SaveToBinFile(char *FileName); void __fastcall BreakHierarhy(); //renderowanie specjalne void __fastcall Render(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RenderAlpha(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RaRender(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RaRenderAlpha(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); //jeden kąt obrotu void __fastcall Render(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RenderAlpha(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RaRender(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RaRenderAlpha(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); //trzy kąty obrotu void __fastcall Render(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RenderAlpha(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RaRender(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); void __fastcall RaRenderAlpha(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030); //inline int __fastcall GetSubModelsCount() { return (SubModelsCount); }; int __fastcall Flags() {return iFlags;}; void __fastcall Init(); char* __fastcall NameGet() {return Root?Root->pName:NULL;}; int __fastcall TerrainCount(); TSubModel* __fastcall TerrainSquare(int n); void __fastcall TerrainRenderVBO(int n); }; //--------------------------------------------------------------------------- #endif