Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern char* fstr(const char* fmt, ...);
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <SDL2/SDL.h>
- #include <SDL2/SDL_image.h>
- #include <KIT/kmath.h>
- #include <KIT/kbts.h>
- #include <KIT/kttm.h>
- /* TTL */
- #define KIT_TTL_CHECKERR(condition,errCode,doBefore) \
- if(condition){ \
- doBefore \
- if(ttl->mats != NULL) free(ttl->mats); \
- ttl->mats=NULL; \
- ttl->mats_len=errCode; \
- return ttl; \
- }
- #define KIT_TTL_ASCALAR(id,attribute,ttype,tsize) \
- if((ti=KIT_BTS_GetTagIndex(ttl->bts,m,*(uint32_t*)(id))) != 0xffffffff){ \
- KIT_TTL_CHECKERR(block.tags[ti].size!=tsize,8,;); \
- mats[m].attribute=block.tags[ti].ttype; \
- }
- #define KIT_TTL_AARRAY(id,attribute,ttype,arrsize) \
- if((ti=KIT_BTS_GetTagIndex(ttl->bts,m,*(uint32_t*)(id))) != 0xffffffff){ \
- KIT_TTL_CHECKERR(block.tags[ti].size!=arrsize,9,;); \
- memcpy(&mats[m].attribute, block.tags[ti].ttype, arrsize); \
- }
- #define KIT_TTL_ATEXTURE(id,attribute) \
- if((ti=KIT_BTS_GetTagIndex(ttl->bts,m,*(uint32_t*)(id)))!=0xffffffff){ \
- sprintf(fileNameBuffer,"%s",block.tags[ti].chr_p); \
- mats[m].attribute=IMG_LoadTexture(r,pathBuffer); \
- KIT_TTL_CHECKERR(mats[m].attribute==NULL,10,;); \
- }
- KIT_TTL* KIT_TTL_LoadFile(const char* filePath, SDL_Renderer* r){
- //if ttl->mats is NULL, then mats_len is error code (0=no error)
- //1=failure to open ttl
- //2=fileSize < 12
- //3=dataSize doesn't correlate with fileSize
- //4=block_len = 0
- //5=blockSize doesn't correlate with end of block's tags
- //6=file signature is not "TTL"
- //7=mats_len is 0
- //8=incorrect size of scalar tag
- //9=incorrect size of array tag
- //10=failed to load texture map file (check SDL_GetError() for more info)
- //general allocation and prep
- //extract folder from file path
- //(use relative paths for texture map file names inside the .ttl)
- char pathBuffer[255], *fileNameBuffer; int folderLen;
- for(folderLen=strlen(filePath); folderLen>=0; --folderLen)
- if(filePath[folderLen]=='\\' || filePath[folderLen]=='/'){
- sprintf(pathBuffer,"%s",filePath); break;
- }
- fileNameBuffer=pathBuffer+folderLen+1;
- KIT_TTL* ttl=malloc(sizeof(KIT_TTL));
- memset(ttl,0,sizeof(KIT_TTL));
- ttl->bts=KIT_BTS_LoadFile(filePath);
- KIT_TTL_CHECKERR(ttl->bts->errorCode, -ttl->bts->errorCode, ;);
- KIT_TTL_CHECKERR((ttl->bts->magicNumber&0xffffff)!=0x4C5454, 6, ;);
- ttl->mats_len=ttl->bts->blocks_len;
- KIT_TTL_CHECKERR(ttl->mats_len==0, 7, ;);
- ttl->mats=malloc(sizeof(KIT_TTL_Material)*ttl->mats_len);
- memset(ttl->mats,0,sizeof(KIT_TTL_Material)*ttl->mats_len);
- //interpreting the bts data
- uint32_t ti; //tag index
- KIT_TTL_Material* mats=ttl->mats;
- for(uint32_t m=0; m<ttl->mats_len; ++m){
- KIT_BTS_Block block=*(KIT_BTS_Block*)&ttl->bts->blocks[m];
- mats[m].name=block.name; //material name
- KIT_TTL_AARRAY( " Ka", Ka,flt_p,sizeof(KIT_vec3)); //ambient color
- KIT_TTL_AARRAY( " Kd", Kd,flt_p,sizeof(KIT_vec3)); //diffuse color
- KIT_TTL_AARRAY( " Ks", Ks,flt_p,sizeof(KIT_vec3)); //specular color
- KIT_TTL_ASCALAR( " Ns", Ns,flt ,sizeof(float )); //specular exponent
- KIT_TTL_ASCALAR( " d ", d ,flt ,sizeof(float )); //alpha
- KIT_TTL_AARRAY( " Tf", Tf,flt_p,sizeof(KIT_vec3)); //transmission filter color
- KIT_TTL_ASCALAR( " Ni", Ni,flt ,sizeof(float )); //optical density
- KIT_TTL_ASCALAR( "ilm",ilm,u32 ,sizeof(uint32_t)); //illumination model
- KIT_TTL_ATEXTURE("mKa",mKa); //ambient texture map
- KIT_TTL_ATEXTURE("mKd",mKd); //diffuse texture map
- KIT_TTL_ATEXTURE("mKs",mKs); //specular color texture map
- KIT_TTL_ATEXTURE("mNs",mNs); //specular highlight component
- KIT_TTL_ATEXTURE("md ",md ); //alpha texture map
- KIT_TTL_ATEXTURE("mbm",mbm); //bump map
- KIT_TTL_ATEXTURE("dsp",dsp); //displacement map
- KIT_TTL_ATEXTURE("dcl",dcl); //stencil decal texture
- KIT_TTL_AARRAY( " Ke", Ke,flt_p,sizeof(KIT_vec3)); //emissive color (format ext.)
- }
- return ttl;
- }
- void KIT_TTL_Destroy(KIT_TTL** ttl_p){
- if(*ttl_p == NULL) return;
- KIT_TTL* ttl=*ttl_p;
- KIT_BTS_Destroy(&ttl->bts);
- if(ttl->mats == NULL){ free(ttl); *ttl_p=NULL; return; }
- KIT_TTL_Material* mats=ttl->mats;
- for(uint32_t m=0; m<ttl->mats_len; ++m){
- if(mats[m].mKa) SDL_DestroyTexture(mats[m].mKa);
- if(mats[m].mKd) SDL_DestroyTexture(mats[m].mKd);
- if(mats[m].mKs) SDL_DestroyTexture(mats[m].mKs);
- if(mats[m].mNs) SDL_DestroyTexture(mats[m].mNs);
- if(mats[m].md ) SDL_DestroyTexture(mats[m].md );
- if(mats[m].mbm) SDL_DestroyTexture(mats[m].mbm);
- if(mats[m].dsp) SDL_DestroyTexture(mats[m].dsp);
- if(mats[m].dcl) SDL_DestroyTexture(mats[m].dcl);
- }
- if(ttl->mats){ free(ttl->mats); ttl->mats=NULL; }
- if(ttl ){ free(ttl ); *ttl_p=NULL; }
- }
- /* TTM */
- #define KIT_TTM_CHECKERR(condition,errCode,doBefore) \
- if(condition){ \
- doBefore \
- if(ttm->objects){ free(ttm->objects); ttm->objects=NULL; } \
- ttm->objects_len=errCode; return ttm; \
- }
- KIT_TTM* KIT_TTM_LoadFile(const char* filePath, SDL_Renderer* r){
- //if ttm->objects is NULL, then ttm->objects_len is error code (0=no error)
- // 1->10=(see ttl error codes)
- //11=failed to open ttm
- //12=ttm's filesize < 12
- //13=ttm's dataSize doesn't correlate with fileSize
- //14=ttm's block_len = 0
- //15=ttm's blockSize doesn't correlate with end of block's tags
- //16=filePath is NULL
- //17=file signature is not "TTM"
- //18=block count is < 2 (must have at least _vertices_ and 1 object tag)
- //19=missing "_vertices_" block
- //20=missing "_vertices_":" v "
- //21=missing "_vertices_":" vt"
- //22=missing "_vertices_":" vn"
- //23=tag " v " data type is not float*
- //24=tag " vt" data type is not float*
- //25=tag " vn" data type is not float*
- //26=tagSize of " v " %12 != 0
- //27=tagSize of " vt" % 8 != 0
- //28=tagSize of " vn" %12 != 0
- //29=tag "umt" data type is not char*
- //30=object uses material not found in imported materials list
- //31=tag " f " missing from an object
- //32=tag " f " data type is not uint<8/16/32>_t*
- //33=tagLen (not tagSize) of " f " % 9 != 0
- //34=tag " s " exists, but is not of type uint32_t
- //separate folder and file name for relative pathing
- KIT_TTM* ttm=malloc(sizeof(KIT_TTM)); memset(ttm,0,sizeof(KIT_TTM)); //malloc ttm
- KIT_TTM_CHECKERR(!filePath, 16, ;);
- char folderName[256]={0},fileName[256]={0};
- int pathLen=strlen(filePath);
- for(int i=pathLen; i>=0; --i)
- if(filePath[i]=='\\' || filePath[i]=='/'){
- memcpy(folderName,filePath,i); //1 char before the '\\' (or '/')
- strcpy(fileName,filePath+i+1); //1 char after the '\\' (or '/')
- }
- ttm->bts=KIT_BTS_LoadFile(filePath); KIT_BTS* bts=ttm->bts; //load bts data
- KIT_TTM_CHECKERR(bts->errorCode, (-bts->errorCode)+10, ;); //+10 to account for ttl errorCodes
- KIT_TTM_CHECKERR((bts->magicNumber&0xffffff)!=0x4D5454, 17, ;);
- KIT_TTM_CHECKERR((ttm->objects_len=bts->blocks_len)<2, 18, ;); //ttm->objects_len=bts->blocks_len
- //load material lib(s) only if they're present
- uint32_t libs_i=KIT_BTS_GetBlockIndex(bts,"_ttllib_");
- if(libs_i != -1){ //if "_ttllib_" block exists
- --ttm->objects_len; //subtracting "_ttllib_" block
- KIT_BTS_Block libBlock=*(KIT_BTS_Block*)&bts->blocks[libs_i];
- if((ttm->ttls_len=libBlock.tags_len)){ //ttm->ttls_len=libBlock.tags_len
- //malloc ttl pointer array before setting all of them to NULL
- ttm->ttls=malloc(sizeof(KIT_TTL*)*libBlock.tags_len);
- memset(ttm->ttls,0,sizeof(KIT_TTL*)*libBlock.tags_len);
- }
- ttm->mats_len=0; //for readability, as it's otherwise redundant due to the memset
- //load ttls
- for(uint32_t lib_i=0; lib_i<libBlock.tags_len; ++lib_i){
- ttm->ttls[lib_i]=KIT_TTL_LoadFile(
- fstr("%s/%s",folderName,libBlock.tags[lib_i].chr_p),r);
- KIT_TTM_CHECKERR(!ttm->ttls[lib_i]->mats, ttm->ttls[lib_i]->mats_len, ;);
- ttm->mats_len+=ttm->ttls[lib_i]->mats_len;
- }
- //put pointers of all the ttl materials into a single array
- ttm->mats=malloc(sizeof(KIT_TTL_Material*)*ttm->mats_len);
- uint32_t currentMaterial=0;
- for(uint32_t lib_i=0; lib_i<ttm->ttls_len; ++lib_i)
- for(uint32_t mat_i=0; mat_i<ttm->ttls[lib_i]->mats_len; ++mat_i)
- ttm->mats[currentMaterial++]=&ttm->ttls[lib_i]->mats[mat_i];
- }
- //load vertices
- //getting block and tag indexes before checking if those indexes exist
- --ttm->objects_len; //subtracting "_vertices_" block
- uint32_t** f32=malloc(sizeof(uint32_t**)*ttm->objects_len); //tmp vertex buffers
- uint32_t vertices_i=KIT_BTS_GetBlockIndex(bts,"_vertices_");
- KIT_TTM_CHECKERR(vertices_i == -1, 19, ;);
- uint32_t v_i =KIT_BTS_GetTagIndex(bts,vertices_i,*(uint32_t*)" v ");
- uint32_t vt_i=KIT_BTS_GetTagIndex(bts,vertices_i,*(uint32_t*)" vt");
- uint32_t vn_i=KIT_BTS_GetTagIndex(bts,vertices_i,*(uint32_t*)" vn");
- KIT_TTM_CHECKERR(v_i == -1, 20, ;);
- KIT_TTM_CHECKERR(vt_i == -1, 21, ;);
- KIT_TTM_CHECKERR(vn_i == -1, 22, ;);
- //some more error checks...
- KIT_BTS_Block vertices_b=*(KIT_BTS_Block*)&bts->blocks[vertices_i];
- KIT_TTM_CHECKERR((vertices_b.tags[v_i ].header>>24) != 0x53, 23, ;);
- KIT_TTM_CHECKERR((vertices_b.tags[vt_i].header>>24) != 0x53, 24, ;);
- KIT_TTM_CHECKERR((vertices_b.tags[vn_i].header>>24) != 0x53, 25, ;);
- KIT_TTM_CHECKERR(vertices_b.tags[v_i ].size%12 != 0, 26, ;); //size of 3 floats
- KIT_TTM_CHECKERR(vertices_b.tags[vt_i].size% 8 != 0, 27, ;); //size of 2 floats
- KIT_TTM_CHECKERR(vertices_b.tags[vn_i].size%12 != 0, 28, ;);
- //defining the vertex arrays
- KIT_vec3 *v,*vn; SDL_FPoint* vt;
- uint32_t v_len =vertices_b.tags[v_i ].size/sizeof(KIT_vec3 );
- uint32_t vt_len=vertices_b.tags[vt_i].size/sizeof(SDL_FPoint);
- uint32_t vn_len=vertices_b.tags[vn_i].size/sizeof(KIT_vec3 );
- if(v_len ) v =(KIT_vec3* )vertices_b.tags[v_i ].flt_p;
- if(vt_len) vt=(SDL_FPoint*)vertices_b.tags[vt_i].flt_p;
- if(vn_len) vn=(KIT_vec3* )vertices_b.tags[vn_i].flt_p;
- //load objects
- ttm->objects=malloc(sizeof(KIT_TTM_Object)*ttm->objects_len);
- memset(ttm->objects,0,sizeof(KIT_TTM_Object)*ttm->objects_len);
- KIT_TTM_Object* objects=ttm->objects;
- uint32_t currentObject=-1; //init current object to -1 so it =0 after preincrement
- for(uint32_t blk_i=0; blk_i<bts->blocks_len; ++blk_i){
- if(blk_i==libs_i || blk_i==vertices_i) continue; //skip _ttllib_ and _vertices_
- KIT_BTS_Block block=*(KIT_BTS_Block*)&bts->blocks[blk_i];
- KIT_TTM_Object* object=&objects[++currentObject]; //preincrement currentObject
- //set object->umt to used material, if one is required
- uint32_t umt=KIT_BTS_GetTagIndex(bts,blk_i,*(uint32_t*)"umt");
- if(umt != -1){ //if "umt" tag exists
- KIT_TTM_CHECKERR(block.tags[umt].header>>24!=0xE0, 29, ;); //0xE0=char*
- char* materialWant=block.tags[umt].chr_p;
- uint32_t materialHave_i=-1; //will be -1 unless it finds the material
- for(uint32_t mat_i=0; mat_i<ttm->mats_len; ++mat_i){
- if(!strcmp(materialWant,ttm->mats[mat_i]->name)){
- materialHave_i=mat_i; break;
- }
- }
- if(strcmp(materialWant,"(null)")!=0){ //if "(null)", then skip the error check
- KIT_TTM_CHECKERR(materialHave_i == -1, 30, ;);
- object->umt=ttm->mats[materialHave_i];
- }
- } //else object->umt=NULL;
- //smooth shading
- uint32_t si=KIT_BTS_GetTagIndex(bts,blk_i,*(uint32_t*)" s ");
- if(si != -1){ //if " s " tag exists
- KIT_TTM_CHECKERR((block.tags[si].header>>24)!=0x03, 34, ;);
- object->s=block.tags[si].u32;
- }
- //faces
- object->name=block.name;
- uint32_t faces_i=KIT_BTS_GetTagIndex(bts,blk_i,*(uint32_t*)" f ");
- KIT_TTM_CHECKERR(faces_i == -1, 29, ;);
- object->numTriangles=block.tags[faces_i].size; //=bytes, not array elements
- uint8_t* f8; uint16_t* f16; //uint32_t* f32;
- switch(block.tags[faces_i].header>>24){
- case 0b01000000: //uint8_t*
- KIT_TTM_CHECKERR(object->numTriangles%9 != 0, 33, ;); //sizeof(uint8_t)*9=9
- //object->numTriangles=face count*9 (3 components*3 verts)
- f32[currentObject]=malloc(object->numTriangles*sizeof(uint32_t)); //9 u32 per face
- f8=block.tags[faces_i].u_8_p;
- for(uint32_t component_i=0; component_i<object->numTriangles; ++component_i)
- f32[currentObject][component_i]=f8[component_i];
- object->numTriangles/=9; // =face count
- break;
- case 0b01000001: //uint16_t*
- KIT_TTM_CHECKERR(object->numTriangles%18 != 0, 33, ;); //sizeof(uint16_t)*9=18
- object->numTriangles/=sizeof(uint16_t);//=face count*9 (3 components*3 verts)
- f32[currentObject]=malloc(object->numTriangles*sizeof(uint32_t)); //9 u32 per face
- f16=block.tags[faces_i].u16_p;
- for(uint32_t component_i=0; component_i<object->numTriangles; ++component_i)
- f32[currentObject][component_i]=f16[component_i];
- object->numTriangles/=9; // =face count
- break;
- case 0b01000011: //uint32_t*
- KIT_TTM_CHECKERR(object->numTriangles%36 != 0, 33, ;); //sizeof(uint32_t)*9=36
- //object->numTriangles=face count*sizeof(uint32_t)*9 (3 components*3 verts)
- f32[currentObject]=malloc(object->numTriangles); //9 u32 per face
- memcpy(f32[currentObject], block.tags[faces_i].u32_p,sizeof(uint32_t)*object->numTriangles);
- object->numTriangles/=sizeof(uint32_t)*9; // =face count
- break; //^^^ a single memcpy, how convenient!
- default: KIT_TTM_CHECKERR(1, 32, ;); break; //condition=1; always triggers
- }
- }
- //preprocessing
- for(uint32_t obj_i=0; obj_i<ttm->objects_len; ++obj_i){
- KIT_TTM_Object* object=&objects[obj_i]; //pointer; use "->", not "."
- //allocating
- object->original=malloc(sizeof(KIT_TTM_Triangle)*object->numTriangles);
- object->work =malloc(sizeof(KIT_TTM_Triangle)*object->numTriangles);
- object->render =malloc(sizeof(KIT_TTM_Triangle)*object->numTriangles);
- //calculate face information
- uint32_t component_i=-1, *faceInfo=f32[obj_i];
- KIT_TTM_Triangle* original=object->original;
- for(uint32_t tri_i=0; tri_i<object->numTriangles; ++tri_i){
- original->a.clri=original->b.clri=original->c.clri=0xffffffff; //init color
- //get vertex info
- KIT_vec3 a=original[tri_i].a.pos = v[ faceInfo[++component_i] ];
- original[tri_i].a.uv =vt[ faceInfo[++component_i] ];
- original[tri_i].a.norm=vn[ faceInfo[++component_i] ];
- KIT_vec3 b=original[tri_i].b.pos = v[ faceInfo[++component_i] ];
- original[tri_i].b.uv =vt[ faceInfo[++component_i] ];
- original[tri_i].b.norm=vn[ faceInfo[++component_i] ];
- KIT_vec3 c=original[tri_i].c.pos = v[ faceInfo[++component_i] ];
- original[tri_i].c.uv =vt[ faceInfo[++component_i] ];
- original[tri_i].c.norm=vn[ faceInfo[++component_i] ];
- //calculate face midpoint
- original[tri_i].mid=KIT_vec3_Mid3(a,b,c); //(a+b+c)/3
- //calculate surface normals
- KIT_vec3 n0=KIT_vec3_SubV(b,a); //b-a
- KIT_vec3 n1=KIT_vec3_SubV(c,a); //c-a
- KIT_vec3 n =KIT_vec3_Cross(n0,n1); //normal vector
- float m=KIT_vec3_Hypot(n); //magnitude of normal vector
- original[tri_i].norm=KIT_vec3_DivF(n,m); //converting to unit vector; n/m
- }
- }
- //free the temporary v_ indexes
- if(f32){
- for(uint32_t obj_i=0; obj_i; ++obj_i) if(f32[obj_i]) free(f32[obj_i]);
- free(f32);
- }
- return ttm;
- }
- void KIT_TTM_Destroy(KIT_TTM** ttm_p){
- if(!*ttm_p) return;
- KIT_TTM* ttm=*ttm_p;
- KIT_BTS_Destroy(&ttm->bts);
- if(ttm->ttls) for(uint32_t lib=0; lib<ttm->ttls_len; ++lib)
- KIT_TTL_Destroy(&ttm->ttls[lib]);
- ttm->ttls=NULL;
- if( ttm->mats ){ free(ttm->mats); ttm->mats=NULL; }
- if(!ttm->objects){ free(ttm ); *ttm_p=NULL; return; }
- KIT_TTM_Object* objects=ttm->objects;
- for(uint32_t obj=0; obj<ttm->objects_len; ++obj){
- if(objects[obj].original) free(objects[obj].original);
- if(objects[obj].work ) free(objects[obj].work );
- if(objects[obj].render ) free(objects[obj].render );
- }
- if( ttm->objects){ free(ttm->objects); ttm->objects=NULL; }
- if(*ttm_p ){ free(ttm ); *ttm_p=NULL; }
- }
- int KIT_TTM_Transform(KIT_TTM* ttm, int* opt, KIT_vec3* ops, int opCount){
- //operation 0 -> 2 = translate,rotate,scale
- if(!ttm) return 1;
- float yaw, pitch, roll;
- float s_yaw, c_yaw;
- float s_pitch, c_pitch;
- float s_roll, c_roll;
- float Axx,Axy,Axz, Ayx,Ayy,Ayz, Azx,Azy,Azz;
- KIT_vec3 rotMulX,rotMulY,rotMulZ, tempV;
- uint32_t objects_len=ttm->objects_len;
- //copy info
- for(uint32_t obj_i=0; obj_i<objects_len; ++obj_i){
- KIT_TTM_Object* object=&ttm->objects[obj_i];
- memcpy(object->work,object->original,sizeof(KIT_TTM_Object)*objects_len);
- }
- //apply transformations
- for(int op_i=0; op_i<opCount; ++op_i){
- KIT_TTM_Object* object=&ttm->objects[op_i];
- KIT_TTM_Triangle* work=object->work;
- int opr=opt[op_i]; //operator
- KIT_vec3 opa=ops[op_i]; //operand
- if(opr==1){ //precalculate black box euler rotation
- yaw=opa.a, pitch=opa.b, roll=opa.c;
- s_yaw =sinf(yaw), c_yaw =cosf(yaw);
- s_pitch=sinf(pitch), c_pitch=cosf(pitch);
- s_roll =sinf(roll), c_roll =cosf(roll);
- Axx=c_yaw*c_pitch;
- Axy=c_yaw*s_pitch*s_roll - s_yaw*c_roll;
- Axz=c_yaw*s_pitch*c_roll + s_yaw*s_roll;
- Ayx=s_yaw*c_pitch;
- Ayy=s_yaw*s_pitch*s_roll + c_yaw*c_roll;
- Ayz=s_yaw*s_pitch*c_roll - c_yaw*s_roll;
- Azx=-s_pitch;
- Azy=c_pitch*s_roll;
- Azz=c_pitch*c_roll;
- rotMulX.x=Axx; rotMulX.y=Axy; rotMulX.z=Axz;
- rotMulY.x=Ayx; rotMulY.y=Ayy; rotMulY.z=Ayz;
- rotMulZ.x=Azx; rotMulZ.y=Azy; rotMulZ.z=Azz;
- }
- //apply given operation to each object
- for(uint32_t obj_i=0; obj_i<objects_len; ++obj_i){
- KIT_TTM_Object* object=&ttm->objects[obj_i];
- uint32_t numTriangles=object->numTriangles;
- switch(opr){
- case 0: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //translate
- work[face_i].mid =KIT_vec3_AddV(work[face_i].mid ,opa);
- work[face_i].a.pos=KIT_vec3_AddV(work[face_i].a.pos,opa);
- work[face_i].b.pos=KIT_vec3_AddV(work[face_i].b.pos,opa);
- work[face_i].c.pos=KIT_vec3_AddV(work[face_i].c.pos,opa);
- } break;
- case 1: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //rotate
- #define KIT_TTM_Transform_ROTATE(member) \
- tempV=work[face_i].member; \
- work[face_i].member.x=KIT_vec3_Dot(tempV,rotMulX); \
- work[face_i].member.y=KIT_vec3_Dot(tempV,rotMulY); \
- work[face_i].member.z=KIT_vec3_Dot(tempV,rotMulZ);
- KIT_TTM_Transform_ROTATE(mid ); //face midpoint
- KIT_TTM_Transform_ROTATE(norm ); //surface normal
- KIT_TTM_Transform_ROTATE(a.pos ); //vert a position
- KIT_TTM_Transform_ROTATE(a.norm); //vert a normal
- KIT_TTM_Transform_ROTATE(b.pos ); //vert b position
- KIT_TTM_Transform_ROTATE(b.norm); //vert b normal
- KIT_TTM_Transform_ROTATE(c.pos ); //vert c position
- KIT_TTM_Transform_ROTATE(c.norm); //vert c normal
- } break;
- case 2: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //scale
- work[face_i].mid =KIT_vec3_MulV(work[face_i].mid ,opa);
- work[face_i].a.pos=KIT_vec3_MulV(work[face_i].a.pos,opa);
- work[face_i].b.pos=KIT_vec3_MulV(work[face_i].b.pos,opa);
- work[face_i].c.pos=KIT_vec3_MulV(work[face_i].c.pos,opa);
- } break;
- case 3: for(uint32_t face_i=0; face_i<numTriangles; ++face_i){ //add,sub uv coordinate (x,y,index)
- //tbd
- } break;
- }
- }
- }
- //postprocessing
- for(int obj_i=0; obj_i<objects_len; ++obj_i){
- //set, clip, and cull
- KIT_TTM_Object* object=&ttm->objects[obj_i];
- uint32_t numTriangles=object->numTriangles, numWorkTris=0;
- KIT_TTM_Triangle* work=object->work;
- KIT_TTM_Triangle* render=object->render;
- //set all of render to 0xff so vertex RGBA values are all 0xffffffff
- memset(render,0xff,numTriangles*sizeof(KIT_TTM_Triangle));
- for(uint32_t face_i=0; face_i<numTriangles; ++face_i){
- int isInRange=work[face_i].mid.z>=KIT_TTM_NEAR && work[face_i].mid.z<=KIT_TTM_FAR;
- int isFrontFace=KIT_vec3_Dot(work[face_i].norm,KIT_vec3_Flip(work[face_i].mid)) > 0;
- printf("=%i,%i\n",isInRange,isFrontFace);
- if(isInRange && isFrontFace)
- render[numWorkTris++]=work[face_i];
- }
- //copy back over to work buffer (render was only used here temporarily)
- memcpy(work,render,sizeof(KIT_TTM_Triangle)*numWorkTris);
- object->numWorkTris=numWorkTris;
- }
- return 0;
- }
- //qsort callbacks
- int KIT_TTM_ZCompareVert(const void* p1, const void* p2){
- const KIT_TTM_Vertex* vert1=p1;
- const KIT_TTM_Vertex* vert2=p2;
- float z1=vert1->pos.z;
- float z2=vert2->pos.z;
- return (z1>z2) - (z1<z2);
- }
- int KIT_TTM_ZCompareTri(const void* p1, const void* p2){
- const KIT_TTM_Triangle* tri1=p1;
- const KIT_TTM_Triangle* tri2=p2;
- float z1=tri1->mid.z;
- float z2=tri2->mid.z;
- return (z1>z2) - (z1<z2);
- }
- KIT_TTM_Canvas3D* KIT_TTM_CreateCanvas3D(SDL_Renderer* renderer,
- int w,int h, float v_w,float v_h){
- if(w==0 || h==0 || v_w==0 || v_h==0) return NULL;
- w=( w>0)? w: -w; h=( h>0)? h: -h;
- v_w=(v_w>0)?v_w:-v_w; v_h=(v_h>0)?v_h:-v_h;
- KIT_TTM_Canvas3D* canvas=malloc(sizeof(KIT_TTM_Canvas3D));
- canvas->texture=SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
- SDL_TEXTUREACCESS_STREAMING, w,h);
- canvas->renderer=renderer;
- if(!canvas->texture){ if(canvas){ free(canvas); } return NULL; }
- canvas->zBuffer=malloc(sizeof(float) * w*h);
- canvas->v_w=v_w; canvas->v_h=v_h;
- canvas->w=w; canvas->h=h;
- return canvas;
- }
- void KIT_TTM_DestroyCanvas3D(KIT_TTM_Canvas3D** c_p){
- if(!*c_p) return;
- KIT_TTM_Canvas3D* c=*c_p;
- if(c->zBuffer ){ free(c->zBuffer); c->zBuffer=NULL; }
- if(c->texture ){ SDL_DestroyTexture(c->texture); c->texture=NULL; }
- if(c ){ free(c); *c_p=NULL; }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement