Advertisement
Kitomas

kttm.c in a wip refactoring state

Apr 28th, 2023
980
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.17 KB | None | 0 0
  1. extern char* fstr(const char* fmt, ...);
  2.  
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #include <SDL2/SDL.h>
  9. #include <SDL2/SDL_image.h>
  10.  
  11. #include <KIT/kmath.h>
  12. #include <KIT/kbts.h>
  13. #include <KIT/kttm.h>
  14.  
  15.  
  16. /* TTL */
  17.  
  18. #define KIT_TTL_CHECKERR(condition,errCode,doBefore) \
  19.   if(condition){ \
  20.     doBefore \
  21.     if(ttl->mats != NULL) free(ttl->mats); \
  22.     ttl->mats=NULL; \
  23.     ttl->mats_len=errCode; \
  24.     return ttl; \
  25.   }
  26. #define KIT_TTL_ASCALAR(id,attribute,ttype,tsize) \
  27.   if((ti=KIT_BTS_GetTagIndex(ttl->bts,m,*(uint32_t*)(id))) != 0xffffffff){ \
  28.     KIT_TTL_CHECKERR(block.tags[ti].size!=tsize,8,;); \
  29.     mats[m].attribute=block.tags[ti].ttype; \
  30.   }
  31. #define KIT_TTL_AARRAY(id,attribute,ttype,arrsize) \
  32.   if((ti=KIT_BTS_GetTagIndex(ttl->bts,m,*(uint32_t*)(id))) != 0xffffffff){ \
  33.     KIT_TTL_CHECKERR(block.tags[ti].size!=arrsize,9,;); \
  34.     memcpy(&mats[m].attribute, block.tags[ti].ttype, arrsize); \
  35.   }
  36. #define KIT_TTL_ATEXTURE(id,attribute) \
  37.   if((ti=KIT_BTS_GetTagIndex(ttl->bts,m,*(uint32_t*)(id)))!=0xffffffff){ \
  38.     sprintf(fileNameBuffer,"%s",block.tags[ti].chr_p); \
  39.     mats[m].attribute=IMG_LoadTexture(r,pathBuffer); \
  40.     KIT_TTL_CHECKERR(mats[m].attribute==NULL,10,;); \
  41.   }
  42. KIT_TTL* KIT_TTL_LoadFile(const char* filePath, SDL_Renderer* r){
  43.   //if ttl->mats is NULL, then mats_len is error code (0=no error)
  44.    //1=failure to open ttl
  45.    //2=fileSize < 12
  46.    //3=dataSize doesn't correlate with fileSize
  47.    //4=block_len = 0
  48.    //5=blockSize doesn't correlate with end of block's tags
  49.    //6=file signature is not "TTL"
  50.    //7=mats_len is 0
  51.    //8=incorrect size of scalar tag
  52.    //9=incorrect size of array tag
  53.    //10=failed to load texture map file (check SDL_GetError() for more info)
  54.   //general allocation and prep
  55.    //extract folder from file path
  56.    //(use relative paths for texture map file names inside the .ttl)
  57.   char pathBuffer[255], *fileNameBuffer; int folderLen;
  58.   for(folderLen=strlen(filePath); folderLen>=0; --folderLen)
  59.     if(filePath[folderLen]=='\\' || filePath[folderLen]=='/'){
  60.       sprintf(pathBuffer,"%s",filePath); break;
  61.     }
  62.   fileNameBuffer=pathBuffer+folderLen+1;
  63.   KIT_TTL* ttl=malloc(sizeof(KIT_TTL));
  64.   memset(ttl,0,sizeof(KIT_TTL));
  65.   ttl->bts=KIT_BTS_LoadFile(filePath);
  66.   KIT_TTL_CHECKERR(ttl->bts->errorCode, -ttl->bts->errorCode, ;);
  67.   KIT_TTL_CHECKERR((ttl->bts->magicNumber&0xffffff)!=0x4C5454, 6, ;);
  68.   ttl->mats_len=ttl->bts->blocks_len;
  69.   KIT_TTL_CHECKERR(ttl->mats_len==0, 7, ;);
  70.   ttl->mats=malloc(sizeof(KIT_TTL_Material)*ttl->mats_len);
  71.   memset(ttl->mats,0,sizeof(KIT_TTL_Material)*ttl->mats_len);
  72.   //interpreting the bts data
  73.   uint32_t ti; //tag index
  74.   KIT_TTL_Material* mats=ttl->mats;
  75.   for(uint32_t m=0; m<ttl->mats_len; ++m){
  76.     KIT_BTS_Block block=*(KIT_BTS_Block*)&ttl->bts->blocks[m];
  77.     mats[m].name=block.name;                            //material name
  78.     KIT_TTL_AARRAY(  " Ka", Ka,flt_p,sizeof(KIT_vec3)); //ambient color
  79.     KIT_TTL_AARRAY(  " Kd", Kd,flt_p,sizeof(KIT_vec3)); //diffuse color
  80.     KIT_TTL_AARRAY(  " Ks", Ks,flt_p,sizeof(KIT_vec3)); //specular color
  81.     KIT_TTL_ASCALAR( " Ns", Ns,flt  ,sizeof(float   )); //specular exponent
  82.     KIT_TTL_ASCALAR( " d ", d ,flt  ,sizeof(float   )); //alpha
  83.     KIT_TTL_AARRAY(  " Tf", Tf,flt_p,sizeof(KIT_vec3)); //transmission filter color
  84.     KIT_TTL_ASCALAR( " Ni", Ni,flt  ,sizeof(float   )); //optical density
  85.     KIT_TTL_ASCALAR( "ilm",ilm,u32  ,sizeof(uint32_t)); //illumination model
  86.     KIT_TTL_ATEXTURE("mKa",mKa);                        //ambient texture map
  87.     KIT_TTL_ATEXTURE("mKd",mKd);                        //diffuse texture map
  88.     KIT_TTL_ATEXTURE("mKs",mKs);                        //specular color texture map
  89.     KIT_TTL_ATEXTURE("mNs",mNs);                        //specular highlight component
  90.     KIT_TTL_ATEXTURE("md ",md );                        //alpha texture map
  91.     KIT_TTL_ATEXTURE("mbm",mbm);                        //bump map
  92.     KIT_TTL_ATEXTURE("dsp",dsp);                        //displacement map
  93.     KIT_TTL_ATEXTURE("dcl",dcl);                        //stencil decal texture
  94.     KIT_TTL_AARRAY(  " Ke", Ke,flt_p,sizeof(KIT_vec3)); //emissive color (format ext.)
  95.   }
  96.   return ttl;
  97. }
  98. void KIT_TTL_Destroy(KIT_TTL** ttl_p){
  99.   if(*ttl_p == NULL) return;
  100.   KIT_TTL* ttl=*ttl_p;
  101.   KIT_BTS_Destroy(&ttl->bts);
  102.   if(ttl->mats == NULL){ free(ttl); *ttl_p=NULL; return; }
  103.   KIT_TTL_Material* mats=ttl->mats;
  104.   for(uint32_t m=0; m<ttl->mats_len; ++m){
  105.     if(mats[m].mKa) SDL_DestroyTexture(mats[m].mKa);
  106.     if(mats[m].mKd) SDL_DestroyTexture(mats[m].mKd);
  107.     if(mats[m].mKs) SDL_DestroyTexture(mats[m].mKs);
  108.     if(mats[m].mNs) SDL_DestroyTexture(mats[m].mNs);
  109.     if(mats[m].md ) SDL_DestroyTexture(mats[m].md );
  110.     if(mats[m].mbm) SDL_DestroyTexture(mats[m].mbm);
  111.     if(mats[m].dsp) SDL_DestroyTexture(mats[m].dsp);
  112.     if(mats[m].dcl) SDL_DestroyTexture(mats[m].dcl);
  113.   }
  114.   if(ttl->mats){ free(ttl->mats); ttl->mats=NULL; }
  115.   if(ttl      ){ free(ttl      );    *ttl_p=NULL; }
  116. }
  117.  
  118.  
  119. /* TTM */
  120.  
  121.  
  122.  
  123. #define KIT_TTM_CHECKERR(condition,errCode,doBefore) \
  124.   if(condition){ \
  125.     doBefore \
  126.     if(ttm->objects){ free(ttm->objects); ttm->objects=NULL; } \
  127.     ttm->objects_len=errCode; return ttm; \
  128.   }
  129. KIT_TTM* KIT_TTM_LoadFile(const char* filePath, SDL_Renderer* r){
  130.   //if ttm->objects is NULL, then ttm->objects_len is error code (0=no error)
  131.    // 1->10=(see ttl error codes)
  132.    //11=failed to open ttm
  133.    //12=ttm's filesize < 12
  134.    //13=ttm's dataSize doesn't correlate with fileSize
  135.    //14=ttm's block_len = 0
  136.    //15=ttm's blockSize doesn't correlate with end of block's tags
  137.    //16=filePath is NULL
  138.    //17=file signature is not "TTM"
  139.    //18=block count is < 2 (must have at least _vertices_ and 1 object tag)
  140.    //19=missing "_vertices_" block
  141.    //20=missing "_vertices_":" v "
  142.    //21=missing "_vertices_":" vt"
  143.    //22=missing "_vertices_":" vn"
  144.    //23=tag " v " data type is not float*
  145.    //24=tag " vt" data type is not float*
  146.    //25=tag " vn" data type is not float*
  147.    //26=tagSize of " v " %12 != 0
  148.    //27=tagSize of " vt" % 8 != 0
  149.    //28=tagSize of " vn" %12 != 0
  150.    //29=tag "umt" data type is not char*
  151.    //30=object uses material not found in imported materials list
  152.    //31=tag " f " missing from an object
  153.    //32=tag " f " data type is not uint<8/16/32>_t*
  154.    //33=tagLen (not tagSize) of " f " % 9 != 0
  155.    //34=tag " s " exists, but is not of type uint32_t
  156.   //separate folder and file name for relative pathing
  157.   KIT_TTM* ttm=malloc(sizeof(KIT_TTM)); memset(ttm,0,sizeof(KIT_TTM)); //malloc ttm
  158.   KIT_TTM_CHECKERR(!filePath, 16, ;);
  159.   char folderName[256]={0},fileName[256]={0};
  160.   int pathLen=strlen(filePath);
  161.   for(int i=pathLen; i>=0; --i)
  162.     if(filePath[i]=='\\' || filePath[i]=='/'){
  163.       memcpy(folderName,filePath,i); //1 char before the '\\' (or '/')
  164.       strcpy(fileName,filePath+i+1); //1 char after the '\\' (or '/')
  165.     }
  166.   ttm->bts=KIT_BTS_LoadFile(filePath); KIT_BTS* bts=ttm->bts; //load bts data
  167.   KIT_TTM_CHECKERR(bts->errorCode, (-bts->errorCode)+10, ;); //+10 to account for ttl errorCodes
  168.   KIT_TTM_CHECKERR((bts->magicNumber&0xffffff)!=0x4D5454, 17, ;);
  169.   KIT_TTM_CHECKERR((ttm->objects_len=bts->blocks_len)<2, 18, ;); //ttm->objects_len=bts->blocks_len
  170.   //load material lib(s) only if they're present
  171.   uint32_t libs_i=KIT_BTS_GetBlockIndex(bts,"_ttllib_");
  172.   if(libs_i != -1){ //if "_ttllib_" block exists
  173.     --ttm->objects_len; //subtracting "_ttllib_" block
  174.     KIT_BTS_Block libBlock=*(KIT_BTS_Block*)&bts->blocks[libs_i];
  175.     if((ttm->ttls_len=libBlock.tags_len)){ //ttm->ttls_len=libBlock.tags_len
  176.       //malloc ttl pointer array before setting all of them to NULL
  177.         ttm->ttls=malloc(sizeof(KIT_TTL*)*libBlock.tags_len);
  178.         memset(ttm->ttls,0,sizeof(KIT_TTL*)*libBlock.tags_len);
  179.     }
  180.     ttm->mats_len=0; //for readability, as it's otherwise redundant due to the memset
  181.     //load ttls
  182.     for(uint32_t lib_i=0; lib_i<libBlock.tags_len; ++lib_i){
  183.       ttm->ttls[lib_i]=KIT_TTL_LoadFile(
  184.         fstr("%s/%s",folderName,libBlock.tags[lib_i].chr_p),r);
  185.       KIT_TTM_CHECKERR(!ttm->ttls[lib_i]->mats, ttm->ttls[lib_i]->mats_len, ;);
  186.       ttm->mats_len+=ttm->ttls[lib_i]->mats_len;
  187.     }
  188.     //put pointers of all the ttl materials into a single array
  189.     ttm->mats=malloc(sizeof(KIT_TTL_Material*)*ttm->mats_len);
  190.     uint32_t currentMaterial=0;
  191.     for(uint32_t lib_i=0; lib_i<ttm->ttls_len; ++lib_i)
  192.       for(uint32_t mat_i=0; mat_i<ttm->ttls[lib_i]->mats_len; ++mat_i)
  193.         ttm->mats[currentMaterial++]=&ttm->ttls[lib_i]->mats[mat_i];
  194.   }
  195.   //load vertices
  196.    //getting block and tag indexes before checking if those indexes exist
  197.   --ttm->objects_len; //subtracting "_vertices_" block
  198.   uint32_t** f32=malloc(sizeof(uint32_t**)*ttm->objects_len); //tmp vertex buffers
  199.   uint32_t vertices_i=KIT_BTS_GetBlockIndex(bts,"_vertices_");
  200.   KIT_TTM_CHECKERR(vertices_i == -1, 19, ;);
  201.   uint32_t v_i =KIT_BTS_GetTagIndex(bts,vertices_i,*(uint32_t*)" v ");
  202.   uint32_t vt_i=KIT_BTS_GetTagIndex(bts,vertices_i,*(uint32_t*)" vt");
  203.   uint32_t vn_i=KIT_BTS_GetTagIndex(bts,vertices_i,*(uint32_t*)" vn");
  204.   KIT_TTM_CHECKERR(v_i  == -1, 20, ;);
  205.   KIT_TTM_CHECKERR(vt_i == -1, 21, ;);
  206.   KIT_TTM_CHECKERR(vn_i == -1, 22, ;);
  207.    //some more error checks...
  208.   KIT_BTS_Block vertices_b=*(KIT_BTS_Block*)&bts->blocks[vertices_i];
  209.   KIT_TTM_CHECKERR((vertices_b.tags[v_i ].header>>24) != 0x53, 23, ;);
  210.   KIT_TTM_CHECKERR((vertices_b.tags[vt_i].header>>24) != 0x53, 24, ;);
  211.   KIT_TTM_CHECKERR((vertices_b.tags[vn_i].header>>24) != 0x53, 25, ;);
  212.   KIT_TTM_CHECKERR(vertices_b.tags[v_i ].size%12 != 0, 26, ;); //size of 3 floats
  213.   KIT_TTM_CHECKERR(vertices_b.tags[vt_i].size% 8 != 0, 27, ;); //size of 2 floats
  214.   KIT_TTM_CHECKERR(vertices_b.tags[vn_i].size%12 != 0, 28, ;);
  215.    //defining the vertex arrays
  216.   KIT_vec3 *v,*vn; SDL_FPoint* vt;
  217.   uint32_t v_len =vertices_b.tags[v_i ].size/sizeof(KIT_vec3  );
  218.   uint32_t vt_len=vertices_b.tags[vt_i].size/sizeof(SDL_FPoint);
  219.   uint32_t vn_len=vertices_b.tags[vn_i].size/sizeof(KIT_vec3  );
  220.   if(v_len ) v =(KIT_vec3*  )vertices_b.tags[v_i ].flt_p;
  221.   if(vt_len) vt=(SDL_FPoint*)vertices_b.tags[vt_i].flt_p;
  222.   if(vn_len) vn=(KIT_vec3*  )vertices_b.tags[vn_i].flt_p;
  223.   //load objects
  224.   ttm->objects=malloc(sizeof(KIT_TTM_Object)*ttm->objects_len);
  225.     memset(ttm->objects,0,sizeof(KIT_TTM_Object)*ttm->objects_len);
  226.     KIT_TTM_Object* objects=ttm->objects;
  227.   uint32_t currentObject=-1; //init current object to -1 so it =0 after preincrement
  228.   for(uint32_t blk_i=0; blk_i<bts->blocks_len; ++blk_i){
  229.     if(blk_i==libs_i || blk_i==vertices_i) continue; //skip _ttllib_ and _vertices_
  230.     KIT_BTS_Block block=*(KIT_BTS_Block*)&bts->blocks[blk_i];
  231.     KIT_TTM_Object* object=&objects[++currentObject]; //preincrement currentObject
  232.     //set object->umt to used material, if one is required
  233.     uint32_t umt=KIT_BTS_GetTagIndex(bts,blk_i,*(uint32_t*)"umt");
  234.     if(umt != -1){ //if "umt" tag exists
  235.       KIT_TTM_CHECKERR(block.tags[umt].header>>24!=0xE0, 29, ;); //0xE0=char*
  236.       char* materialWant=block.tags[umt].chr_p;
  237.       uint32_t materialHave_i=-1; //will be -1 unless it finds the material
  238.       for(uint32_t mat_i=0; mat_i<ttm->mats_len; ++mat_i){
  239.         if(!strcmp(materialWant,ttm->mats[mat_i]->name)){
  240.           materialHave_i=mat_i; break;
  241.         }
  242.       }
  243.       if(strcmp(materialWant,"(null)")!=0){ //if "(null)", then skip the error check
  244.         KIT_TTM_CHECKERR(materialHave_i == -1, 30, ;);
  245.         object->umt=ttm->mats[materialHave_i];
  246.       }
  247.     } //else object->umt=NULL;
  248.     //smooth shading
  249.     uint32_t si=KIT_BTS_GetTagIndex(bts,blk_i,*(uint32_t*)" s ");
  250.     if(si != -1){ //if " s " tag exists
  251.       KIT_TTM_CHECKERR((block.tags[si].header>>24)!=0x03, 34, ;);
  252.       object->s=block.tags[si].u32;
  253.     }
  254.     //faces
  255.     object->name=block.name;
  256.     uint32_t faces_i=KIT_BTS_GetTagIndex(bts,blk_i,*(uint32_t*)" f ");
  257.     KIT_TTM_CHECKERR(faces_i == -1, 29, ;);
  258.     object->numTriangles=block.tags[faces_i].size; //=bytes, not array elements
  259.     uint8_t* f8; uint16_t* f16; //uint32_t* f32;
  260.     switch(block.tags[faces_i].header>>24){
  261.     case 0b01000000: //uint8_t*
  262.       KIT_TTM_CHECKERR(object->numTriangles%9 != 0, 33, ;); //sizeof(uint8_t)*9=9
  263.       //object->numTriangles=face count*9 (3 components*3 verts)
  264.       f32[currentObject]=malloc(object->numTriangles*sizeof(uint32_t)); //9 u32 per face
  265.       f8=block.tags[faces_i].u_8_p;
  266.       for(uint32_t component_i=0; component_i<object->numTriangles; ++component_i)
  267.         f32[currentObject][component_i]=f8[component_i];
  268.       object->numTriangles/=9; // =face count
  269.       break;
  270.     case 0b01000001: //uint16_t*
  271.       KIT_TTM_CHECKERR(object->numTriangles%18 != 0, 33, ;); //sizeof(uint16_t)*9=18
  272.       object->numTriangles/=sizeof(uint16_t);//=face count*9 (3 components*3 verts)
  273.       f32[currentObject]=malloc(object->numTriangles*sizeof(uint32_t)); //9 u32 per face
  274.       f16=block.tags[faces_i].u16_p;
  275.       for(uint32_t component_i=0; component_i<object->numTriangles; ++component_i)
  276.         f32[currentObject][component_i]=f16[component_i];
  277.       object->numTriangles/=9; // =face count
  278.       break;
  279.     case 0b01000011: //uint32_t*
  280.       KIT_TTM_CHECKERR(object->numTriangles%36 != 0, 33, ;); //sizeof(uint32_t)*9=36
  281.       //object->numTriangles=face count*sizeof(uint32_t)*9 (3 components*3 verts)
  282.       f32[currentObject]=malloc(object->numTriangles); //9 u32 per face
  283.       memcpy(f32[currentObject], block.tags[faces_i].u32_p,sizeof(uint32_t)*object->numTriangles);
  284.       object->numTriangles/=sizeof(uint32_t)*9; // =face count
  285.       break; //^^^ a single memcpy, how convenient!
  286.     default: KIT_TTM_CHECKERR(1, 32, ;); break; //condition=1; always triggers
  287.     }
  288.   }
  289.   //preprocessing
  290.   for(uint32_t obj_i=0; obj_i<ttm->objects_len; ++obj_i){
  291.     KIT_TTM_Object* object=&objects[obj_i]; //pointer; use "->", not "."
  292.     //allocating
  293.     object->original=malloc(sizeof(KIT_TTM_Triangle)*object->numTriangles);
  294.     object->work    =malloc(sizeof(KIT_TTM_Triangle)*object->numTriangles);
  295.     object->render  =malloc(sizeof(KIT_TTM_Triangle)*object->numTriangles);
  296.     //calculate face information
  297.     uint32_t component_i=-1, *faceInfo=f32[obj_i];
  298.     KIT_TTM_Triangle* original=object->original;
  299.     for(uint32_t tri_i=0; tri_i<object->numTriangles; ++tri_i){
  300.       original->a.clri=original->b.clri=original->c.clri=0xffffffff; //init color
  301.       //get vertex info
  302.       KIT_vec3 a=original[tri_i].a.pos = v[ faceInfo[++component_i] ];
  303.                  original[tri_i].a.uv  =vt[ faceInfo[++component_i] ];
  304.                  original[tri_i].a.norm=vn[ faceInfo[++component_i] ];
  305.       KIT_vec3 b=original[tri_i].b.pos = v[ faceInfo[++component_i] ];
  306.                  original[tri_i].b.uv  =vt[ faceInfo[++component_i] ];
  307.                  original[tri_i].b.norm=vn[ faceInfo[++component_i] ];
  308.       KIT_vec3 c=original[tri_i].c.pos = v[ faceInfo[++component_i] ];
  309.                  original[tri_i].c.uv  =vt[ faceInfo[++component_i] ];
  310.                  original[tri_i].c.norm=vn[ faceInfo[++component_i] ];
  311.       //calculate face midpoint
  312.       original[tri_i].mid=KIT_vec3_Mid3(a,b,c); //(a+b+c)/3
  313.       //calculate surface normals
  314.       KIT_vec3 n0=KIT_vec3_SubV(b,a); //b-a
  315.       KIT_vec3 n1=KIT_vec3_SubV(c,a); //c-a
  316.       KIT_vec3 n =KIT_vec3_Cross(n0,n1); //normal vector
  317.       float m=KIT_vec3_Hypot(n); //magnitude of normal vector
  318.       original[tri_i].norm=KIT_vec3_DivF(n,m); //converting to unit vector; n/m
  319.     }
  320.   }
  321.   //free the temporary v_ indexes
  322.   if(f32){
  323.     for(uint32_t obj_i=0; obj_i; ++obj_i) if(f32[obj_i]) free(f32[obj_i]);
  324.     free(f32);
  325.   }
  326.   return ttm;
  327. }
  328.  
  329. void KIT_TTM_Destroy(KIT_TTM** ttm_p){
  330.   if(!*ttm_p) return;
  331.   KIT_TTM* ttm=*ttm_p;
  332.   KIT_BTS_Destroy(&ttm->bts);
  333.   if(ttm->ttls) for(uint32_t lib=0; lib<ttm->ttls_len; ++lib)
  334.     KIT_TTL_Destroy(&ttm->ttls[lib]);
  335.   ttm->ttls=NULL;
  336.   if( ttm->mats   ){ free(ttm->mats); ttm->mats=NULL;         }
  337.   if(!ttm->objects){ free(ttm      );    *ttm_p=NULL; return; }
  338.   KIT_TTM_Object* objects=ttm->objects;
  339.   for(uint32_t obj=0; obj<ttm->objects_len; ++obj){
  340.     if(objects[obj].original) free(objects[obj].original);
  341.     if(objects[obj].work    ) free(objects[obj].work    );
  342.     if(objects[obj].render  ) free(objects[obj].render  );
  343.   }
  344.   if( ttm->objects){ free(ttm->objects); ttm->objects=NULL; }
  345.   if(*ttm_p       ){ free(ttm         );       *ttm_p=NULL; }
  346. }
  347.  
  348. int KIT_TTM_Transform(KIT_TTM* ttm,  int* opt, KIT_vec3* ops, int opCount){
  349.   //operation 0 -> 2 = translate,rotate,scale
  350.   if(!ttm) return 1;
  351.   float yaw, pitch, roll;
  352.   float s_yaw,   c_yaw;
  353.   float s_pitch, c_pitch;
  354.   float s_roll,  c_roll;
  355.   float Axx,Axy,Axz, Ayx,Ayy,Ayz, Azx,Azy,Azz;
  356.   KIT_vec3 rotMulX,rotMulY,rotMulZ, tempV;
  357.   uint32_t objects_len=ttm->objects_len;
  358.   //copy info
  359.   for(uint32_t obj_i=0; obj_i<objects_len; ++obj_i){
  360.     KIT_TTM_Object* object=&ttm->objects[obj_i];
  361.     memcpy(object->work,object->original,sizeof(KIT_TTM_Object)*objects_len);
  362.   }
  363.   //apply transformations
  364.   for(int op_i=0; op_i<opCount; ++op_i){
  365.     KIT_TTM_Object* object=&ttm->objects[op_i];
  366.     KIT_TTM_Triangle* work=object->work;
  367.     int opr=opt[op_i]; //operator
  368.     KIT_vec3 opa=ops[op_i]; //operand
  369.     if(opr==1){ //precalculate black box euler rotation
  370.       yaw=opa.a, pitch=opa.b, roll=opa.c;
  371.       s_yaw  =sinf(yaw),   c_yaw  =cosf(yaw);
  372.       s_pitch=sinf(pitch), c_pitch=cosf(pitch);
  373.       s_roll =sinf(roll),  c_roll =cosf(roll);
  374.       Axx=c_yaw*c_pitch;
  375.       Axy=c_yaw*s_pitch*s_roll - s_yaw*c_roll;
  376.       Axz=c_yaw*s_pitch*c_roll + s_yaw*s_roll;
  377.       Ayx=s_yaw*c_pitch;
  378.       Ayy=s_yaw*s_pitch*s_roll + c_yaw*c_roll;
  379.       Ayz=s_yaw*s_pitch*c_roll - c_yaw*s_roll;
  380.       Azx=-s_pitch;
  381.       Azy=c_pitch*s_roll;
  382.       Azz=c_pitch*c_roll;
  383.       rotMulX.x=Axx; rotMulX.y=Axy; rotMulX.z=Axz;
  384.       rotMulY.x=Ayx; rotMulY.y=Ayy; rotMulY.z=Ayz;
  385.       rotMulZ.x=Azx; rotMulZ.y=Azy; rotMulZ.z=Azz;
  386.     }
  387.     //apply given operation to each object
  388.     for(uint32_t obj_i=0; obj_i<objects_len; ++obj_i){
  389.       KIT_TTM_Object* object=&ttm->objects[obj_i];
  390.       uint32_t numTriangles=object->numTriangles;
  391.       switch(opr){
  392.       case 0: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //translate
  393.         work[face_i].mid  =KIT_vec3_AddV(work[face_i].mid  ,opa);
  394.         work[face_i].a.pos=KIT_vec3_AddV(work[face_i].a.pos,opa);
  395.         work[face_i].b.pos=KIT_vec3_AddV(work[face_i].b.pos,opa);
  396.         work[face_i].c.pos=KIT_vec3_AddV(work[face_i].c.pos,opa);
  397.       } break;
  398.       case 1: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //rotate
  399.         #define KIT_TTM_Transform_ROTATE(member) \
  400.           tempV=work[face_i].member; \
  401.           work[face_i].member.x=KIT_vec3_Dot(tempV,rotMulX); \
  402.           work[face_i].member.y=KIT_vec3_Dot(tempV,rotMulY); \
  403.           work[face_i].member.z=KIT_vec3_Dot(tempV,rotMulZ);
  404.         KIT_TTM_Transform_ROTATE(mid   ); //face midpoint
  405.         KIT_TTM_Transform_ROTATE(norm  ); //surface normal
  406.         KIT_TTM_Transform_ROTATE(a.pos ); //vert a position
  407.         KIT_TTM_Transform_ROTATE(a.norm); //vert a normal
  408.         KIT_TTM_Transform_ROTATE(b.pos ); //vert b position
  409.         KIT_TTM_Transform_ROTATE(b.norm); //vert b normal
  410.         KIT_TTM_Transform_ROTATE(c.pos ); //vert c position
  411.         KIT_TTM_Transform_ROTATE(c.norm); //vert c normal
  412.       } break;
  413.       case 2: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //scale
  414.         work[face_i].mid  =KIT_vec3_MulV(work[face_i].mid  ,opa);
  415.         work[face_i].a.pos=KIT_vec3_MulV(work[face_i].a.pos,opa);
  416.         work[face_i].b.pos=KIT_vec3_MulV(work[face_i].b.pos,opa);
  417.         work[face_i].c.pos=KIT_vec3_MulV(work[face_i].c.pos,opa);
  418.       } break;
  419.       case 3: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //add,sub uv coordinate (x,y,index)
  420.         //tbd
  421.       } break;
  422.       }
  423.     }
  424.   }
  425.   //postprocessing
  426.   for(int obj_i=0; obj_i<objects_len; ++obj_i){
  427.     //set, clip, and cull
  428.     KIT_TTM_Object* object=&ttm->objects[obj_i];
  429.     uint32_t numTriangles=object->numTriangles, numWorkTris=0;
  430.     KIT_TTM_Triangle* work=object->work;
  431.     KIT_TTM_Triangle* render=object->render;
  432.      //set all of render to 0xff so vertex RGBA values are all 0xffffffff
  433.     memset(render,0xff,numTriangles*sizeof(KIT_TTM_Triangle));
  434.     for(uint32_t face_i=0; face_i<numTriangles; ++face_i){
  435.       int isInRange=work[face_i].mid.z>=KIT_TTM_NEAR && work[face_i].mid.z<=KIT_TTM_FAR;
  436.       int isFrontFace=KIT_vec3_Dot(work[face_i].norm,KIT_vec3_Flip(work[face_i].mid)) > 0;
  437.       printf("=%i,%i\n",isInRange,isFrontFace);
  438.       if(isInRange && isFrontFace)
  439.         render[numWorkTris++]=work[face_i];
  440.     }
  441.     //copy back over to work buffer (render was only used here temporarily)
  442.     memcpy(work,render,sizeof(KIT_TTM_Triangle)*numWorkTris);
  443.     object->numWorkTris=numWorkTris;
  444.   }
  445.   return 0;
  446. }
  447.  
  448. //qsort callbacks
  449. int KIT_TTM_ZCompareVert(const void* p1, const void* p2){
  450.   const KIT_TTM_Vertex* vert1=p1;
  451.   const KIT_TTM_Vertex* vert2=p2;
  452.   float z1=vert1->pos.z;
  453.   float z2=vert2->pos.z;
  454.   return (z1>z2) - (z1<z2);
  455. }
  456. int KIT_TTM_ZCompareTri(const void* p1, const void* p2){
  457.   const KIT_TTM_Triangle* tri1=p1;
  458.   const KIT_TTM_Triangle* tri2=p2;
  459.   float z1=tri1->mid.z;
  460.   float z2=tri2->mid.z;
  461.   return (z1>z2) - (z1<z2);
  462. }
  463.  
  464. KIT_TTM_Canvas3D* KIT_TTM_CreateCanvas3D(SDL_Renderer* renderer,
  465.                                          int w,int h, float v_w,float v_h){
  466.   if(w==0 || h==0 || v_w==0 || v_h==0) return NULL;
  467.     w=(  w>0)?  w:  -w;   h=(  h>0)?  h:  -h;
  468.   v_w=(v_w>0)?v_w:-v_w; v_h=(v_h>0)?v_h:-v_h;
  469.   KIT_TTM_Canvas3D* canvas=malloc(sizeof(KIT_TTM_Canvas3D));
  470.   canvas->texture=SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
  471.                                     SDL_TEXTUREACCESS_STREAMING, w,h);
  472.   canvas->renderer=renderer;
  473.   if(!canvas->texture){ if(canvas){ free(canvas); } return NULL; }
  474.   canvas->zBuffer=malloc(sizeof(float) * w*h);
  475.   canvas->v_w=v_w; canvas->v_h=v_h;
  476.   canvas->w=w; canvas->h=h;
  477.   return canvas;
  478. }
  479. void KIT_TTM_DestroyCanvas3D(KIT_TTM_Canvas3D** c_p){
  480.   if(!*c_p) return;
  481.   KIT_TTM_Canvas3D* c=*c_p;
  482.   if(c->zBuffer ){ free(c->zBuffer); c->zBuffer=NULL; }
  483.   if(c->texture ){ SDL_DestroyTexture(c->texture); c->texture=NULL; }
  484.   if(c          ){ free(c); *c_p=NULL; }
  485. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement