From d62f5536adf80e33d99eb5aef5df27ae7745bd05 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Mon, 4 Jan 2021 18:28:27 +0100 Subject: [PATCH] export whole scenes --- io_export_psx_tmesh.py | 102 +++++--- primdrawGT.c | 531 ++++++++++++++++++++++++++--------------- 2 files changed, 404 insertions(+), 229 deletions(-) diff --git a/io_export_psx_tmesh.py b/io_export_psx_tmesh.py index 85752d2..a02239a 100644 --- a/io_export_psx_tmesh.py +++ b/io_export_psx_tmesh.py @@ -22,6 +22,7 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper): def execute(self, context): import bmesh + from math import degrees def triangulate_object(obj): # Stolen from here : https://blender.stackexchange.com/questions/45698/triangulate-mesh-in-python/45722#45722 me = obj.data @@ -41,15 +42,20 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper): if bpy.data.objects[m].type == 'MESH': triangulate_object(bpy.data.objects[m]) - scale = 120 + scale = 200 f = open(os.path.normpath(self.filepath),"w+") # write typedef struct f.write("typedef struct { \n"+ - "\tTMESH * tmesh;\n" + - "\tint * index;\n" + - "\tTIM_IMAGE * tim; \n" + - "\tu_long * tim_data;\n" + "\tTMESH * tmesh;\n" + + "\tint * index;\n" + + "\tTIM_IMAGE * tim; \n" + + "\tu_long * tim_data;\n"+ + "\tMATRIX * mat;\n" + + "\tVECTOR * pos;\n" + + "\tSVECTOR * rot;\n" + + "\tshort * isPrism;\n" + + "\tlong * p;\n" + "\t} MESH;\n\n") for m in bpy.data.meshes: @@ -86,22 +92,24 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper): # get image size x, y # print(bpy.data.meshes[0].uv_textures[0].data[0].image.size[0]) # x # print(bpy.data.meshes[0].uv_textures[0].data[0].image.size[1]) # y - if m.uv_textures[0].data[0].image != None: - f.write("SVECTOR "+"model"+m.name+"_uv[] = {\n") - texture_image = m.uv_textures[0].data[0].image - tex_width = texture_image.size[0] - tex_height = texture_image.size[1] - uv_layer = m.uv_layers[0].data - for i in range(len(uv_layer)): - u = uv_layer[i].uv - ux = u.x * tex_width - uy = u.y * tex_height - f.write("\t"+str(ux)+","+str(tex_height - uy)+", 0, 0") - if i != len(uv_layer) - 1: - f.write(",") - f.write("\n") - f.write("};\n\n") - + if len(m.uv_textures) != 0: + for t in range(len(m.uv_textures)): + if m.uv_textures[t].data[0].image != None: + f.write("SVECTOR "+"model"+m.name+"_uv[] = {\n") + texture_image = m.uv_textures[t].data[0].image + tex_width = texture_image.size[0] + tex_height = texture_image.size[1] + uv_layer = m.uv_layers[0].data + for i in range(len(uv_layer)): + u = uv_layer[i].uv + ux = u.x * tex_width + uy = u.y * tex_height + f.write("\t"+str(ux)+","+str(tex_height - uy)+", 0, 0") + if i != len(uv_layer) - 1: + f.write(",") + f.write("\n") + f.write("};\n\n") + # Write vertex colors vectors f.write("CVECTOR "+"model"+m.name+"_color[] = {\n") @@ -135,13 +143,23 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper): f.write("\n") f.write("};\n\n") + #write object matrix, rot and pos vectors + f.write("MATRIX model"+m.name+"_matrix = {0};\n" + + "VECTOR model"+m.name+"_pos = {"+ str(bpy.data.objects[m.name].location.x * 100) + "," + str(bpy.data.objects[m.name].location.y * 100) + "," + str(bpy.data.objects[m.name].location.z * 100) + ", 0};\n" + + "SVECTOR model"+m.name+"_rot = {"+ str(degrees(bpy.data.objects[m.name].rotation_euler.x)/360 * 4096) + "," + str(degrees(bpy.data.objects[m.name].rotation_euler.y)/360 * 4096) + "," + str(degrees(bpy.data.objects[m.name].rotation_euler.z)/360 * 4096) + "};\n" + + "short model"+m.name+"_isPrism = 0;\n" + + "long model"+m.name+"_p = 0;\n" + + "\n") + # Write TMESH struct f.write("TMESH "+"model"+m.name+" = {\n") f.write("\t"+"model"+m.name+"_mesh, \n") f.write("\t"+"model"+m.name+"_normal,\n") - if m.uv_textures[0].data[0].image != None: - f.write("\t"+"model"+m.name+"_uv,\n") + if len(m.uv_textures) != 0: + for t in range(len(m.uv_textures)): + if m.uv_textures[0].data[0].image != None: + f.write("\t"+"model"+m.name+"_uv,\n") else: f.write("\t0,\n") @@ -154,25 +172,35 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper): # write texture binary name and declare TIM_IMAGE # by default, load the file from the TIM folder # ~ if len(m.uv_textures) != 0: - if m.uv_textures[0].data[0].image != None: - tex_name = texture_image.name - prefix = str.partition(tex_name, ".")[0].replace('-','_') - f.write("extern unsigned long "+"_binary_TIM_" + prefix + "_tim_start[];\n") - f.write("extern unsigned long "+"_binary_TIM_" + prefix + "_tim_end[];\n") - f.write("extern unsigned long "+"_binary_TIM_" + prefix + "_tim_length;\n\n") - f.write("TIM_IMAGE tim_" + prefix + ";\n\n") - + if len(m.uv_textures) != 0: + for t in range(len(m.uv_textures)): + if m.uv_textures[0].data[0].image != None: + tex_name = texture_image.name + prefix = str.partition(tex_name, ".")[0].replace('-','_') + f.write("extern unsigned long "+"_binary_TIM_" + prefix + "_tim_start[];\n") + f.write("extern unsigned long "+"_binary_TIM_" + prefix + "_tim_end[];\n") + f.write("extern unsigned long "+"_binary_TIM_" + prefix + "_tim_length;\n\n") + f.write("TIM_IMAGE tim_" + prefix + ";\n\n") + f.write("MESH mesh"+m.name+" = {\n") f.write("\t&model"+ m.name +",\n") f.write("\tmodel" + m.name + "_index,\n") - if m.uv_textures[0].data[0].image != None: - f.write("\t&tim_"+ prefix + ",\n") - f.write("\t_binary_TIM_" + prefix + "_tim_start\n") + if len(m.uv_textures) != 0: + for t in range(len(m.uv_textures)): + if m.uv_textures[0].data[0].image != None: + f.write("\t&tim_"+ prefix + ",\n") + f.write("\t_binary_TIM_" + prefix + "_tim_start,\n") else: - f.write("0,\n" + - "0,\n") - + f.write("\t0,\n" + + "\t0,\n") + f.write("\t&model"+m.name+"_matrix,\n" + + "\t&model"+m.name+"_pos,\n" + + "\t&model"+m.name+"_rot,\n" + + "\t&model"+m.name+"_isPrism,\n" + + "\t&model"+m.name+"_p\n") + + f.write("};\n\n") f.write("MESH * meshes[" + str(len(bpy.data.meshes)) + "] = {\n") diff --git a/primdrawGT.c b/primdrawGT.c index ae09d23..df9c960 100644 --- a/primdrawGT.c +++ b/primdrawGT.c @@ -2,6 +2,10 @@ - Draw a gouraud shaded, UV textured mesh exported by the blender <= 2.79b plugin io_export_psx_tmesh.py + * added depth cueing use with fog farcolor + * switched to double buffer + * switched to vsync callback for pad input + based on primdraw.c by Lameguy64 (http://www.psxdev.net/forum/viewtopic.php?f=64&t=537) 2014 Meido-Tek Productions. @@ -35,6 +39,10 @@ #include #include +// Precalculated sin/cos values +#include "psin.c" +#include "pcos.c" + // Sample vector model #include "coridor.c" @@ -54,7 +62,7 @@ DISPENV disp[2]; DRAWENV draw[2]; -u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives) +u_long ot[2][OTLEN] = {0}; // Ordering table (contains addresses to primitives) char primbuff[2][PRIMBUFFLEN] = {0}; // Primitive list // That's our prim buffer //~ int primcnt=0; // Primitive counter @@ -64,20 +72,248 @@ char * nextpri = primbuff[0]; // Primitive counter char db = 0; // Current buffer counter short vs; -//~ RECT ClearRect ={0,0,320,240}; -//~ extern unsigned long _binary_TIM_bousai_tim_start[]; -//~ extern unsigned long _binary_TIM_bousai_tim_end[]; -//~ extern unsigned long _binary_TIM_bousai_tim_length; +int PadStatus; +//~ int TPressed=0; +//~ int AutoRotate=0; -//~ TIM_IMAGE bousai; +//~ SVECTOR Rotate={0}; // Rotation coordinates +//~ VECTOR Trans={ 0, 0, CENTERX, 0 }; // Translation coordinates +//~ MATRIX Matrix={0}; // Matrix data for the GTE + //~ // Scaling coordinates +//~ VECTOR Scale={ ONE, ONE, ONE, 0 }; // ONE == 4096 -//~ static int frame = 0; +typedef struct{ + int x, xv; // x: current value += vx : new value + int y, yv; + int z, zv; + int pan, panv; + int tilt, tiltv; + int rol; + + VECTOR pos; + SVECTOR rot; + SVECTOR dvs; + + MATRIX mat; +} CAMERA; + +CAMERA camera = {0}; // Prototypes void init(void); void display(void); +void applyCamera(CAMERA * cam); +void applyOrbCam(MESH * mesh); void LoadTexture(u_long * tim, TIM_IMAGE * tparam); +void callback(void); + +int main() { + + int i; + + long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143 + + POLY_GT3 * poly; // pointer to a POLY_G4 + + SVECTOR RotVector = {0, 0, 0}; // Initialize rotation vector {x, y, z} + VECTOR MovVector = {0, 50, 50, 0}; + MATRIX PolyMatrix = {0}; + + + CVECTOR outCol ={0,0,0,0}; + CVECTOR outCol1 ={0,0,0,0}; + CVECTOR outCol2 ={0,0,0,0}; + + // Texture window + + //~ DR_MODE * dr_mode; // Pointer to dr_mode prim + + //~ RECT tws = {0, 0, 32, 32}; // Texture window coordinates : x, y, w, h + + init(); + + VSyncCallback(callback); + + //~ SetBackColor(255 , 255, 255); + SetFarColor(20, 20, 40); + SetFogNearFar(1200, 3000,SCREENXRES); + + for (int k = 0; k < sizeof(meshes)/sizeof(TMESH *); k++){ + LoadTexture(meshes[k]->tim_data, meshes[k]->tim); + } + + // Set Camera starting pos + + camera.xv = -ONE * -89; + camera.yv = -ONE * 59; + camera.zv = -ONE * 133; + + camera.tiltv = 232 ; + camera.panv = -336; + + applyCamera(&camera); + + // Main loop + while (1) { + + + // Local Transform + + meshes[2]->rot->vy -= 28; + meshes[1]->rot->vy += 28; + //~ meshes[1]->rot->vz += 8; + //~ meshes[1]->rot->vx += 2; + + + //World Translations + + meshes[1]->pos->vz = meshes[1]->pos->vz + (pcos[VSync(-1)%1024]/768 ); + meshes[1]->pos->vx = meshes[1]->pos->vx + (psin[VSync(-1)%1024]/768 ); + //~ meshes[1]->pos->vz = pcos[VSync(-1)%4096] / 4096; + //~ meshes[1]->pos->vx = psin[VSync(-1)%4096] / 4096; + //~ meshes[1]->pos->vx = 0; + //~ meshes[1]->pos->vz = 100; + //~ meshes[1]->rot->vy ++; + + + //~ if (!(VSync(-1)%2)){ + //~ meshes[1]->pos->vy = pcos[VSync(-1)%ONE] * psin[VSync(-1)%ONE] / ONE / 128; + //~ } + + // Camera setup + + camera.pos.vx = -(camera.x/ONE); + camera.pos.vy = -(camera.y/ONE); + camera.pos.vz = -(camera.z/ONE); + + camera.rot.vx = camera.tilt; + camera.rot.vy = -camera.pan; + + applyCamera(&camera); + + // Clear the current OT + ClearOTagR(ot[db], OTLEN); + + for (int k = 0; k < sizeof(meshes)/sizeof(meshes[0]); k++){ + + // Render the sample vector model + t=0; + + // modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ... + for (i = 0; i < (meshes[k]->tmesh->len * 3); i += 3) { + + poly = (POLY_GT3 *)nextpri; + // Initialize the primitive and set its color values + + RotMatrix(meshes[k]->rot, meshes[k]->mat); // Apply rotation matrix + + TransMatrix(meshes[k]->mat, meshes[k]->pos); // Apply translation matrix + CompMatrixLV(&camera.mat, meshes[k]->mat, &PolyMatrix); + + + SetRotMatrix(&PolyMatrix); // Set default rotation matrix + SetTransMatrix(&PolyMatrix); + + //~ applyOrbCam(meshes[1]); + + SetPolyGT3(poly); + + DpqColor3(&meshes[k]->tmesh->c[i],&meshes[k]->tmesh->c[i+1],&meshes[k]->tmesh->c[i+2], *meshes[k]->p, + &outCol,&outCol1,&outCol2 + ); + + setRGB0(poly, outCol.r, outCol.g , outCol.b); + setRGB1(poly, outCol1.r, outCol1.g, outCol1.b); + setRGB2(poly, outCol2.r, outCol2.g, outCol2.b); + + + + // The TIMs are loaded in vram vertically on the same TPAGE; eg. Tim1 640,0, Tim1 640, 128 + // We then add tim_image.prect.y to the y coord of the uvs to use the correct texture. + if (*meshes[k]->isPrism){ + ((POLY_GT3 *)poly)->tpage = getTPage(meshes[k]->tim->mode&0x3, 0, + 0, + 256 + ); + setUV3(poly, 32, 32, + 32, 220, + 220,220); + } else { + + ((POLY_GT3 *)poly)->tpage = getTPage(meshes[k]->tim->mode&0x3, 0, + meshes[k]->tim->prect->x, + meshes[k]->tim->prect->y + ); + } + + setUV3(poly, meshes[k]->tmesh->u[i].vx , meshes[k]->tmesh->u[i].vy + meshes[k]->tim->prect->y, + meshes[k]->tmesh->u[i+1].vx, meshes[k]->tmesh->u[i+1].vy + meshes[k]->tim->prect->y, + meshes[k]->tmesh->u[i+2].vx, meshes[k]->tmesh->u[i+2].vy + meshes[k]->tim->prect->y); + //~ } + // Rotate, translate, and project the vectors and output the results into a primitive + + OTz = RotTransPers(&meshes[k]->tmesh->v[meshes[k]->index[t]] , (long*)&poly->x0, meshes[k]->p, &Flag); + OTz += RotTransPers(&meshes[k]->tmesh->v[meshes[k]->index[t+1]], (long*)&poly->x1, meshes[k]->p, &Flag); + OTz += RotTransPers(&meshes[k]->tmesh->v[meshes[k]->index[t+2]], (long*)&poly->x2, meshes[k]->p, &Flag); + + // Using RotTransPers3 is a bit faster (-31ms/frame), but you loose precision for Z-ordering + //~ OTz = RotTransPers3( + //~ &meshes[k]->tmesh->v[meshes[k]->index[t]], + //~ &meshes[k]->tmesh->v[meshes[k]->index[t+1]], + //~ &meshes[k]->tmesh->v[meshes[k]->index[t+2]], + //~ (long*)&poly->x0, (long*)&poly->x1, (long*)&poly->x2, + //~ &p, + //~ &Flag + //~ ); + + // Sort the primitive into the OT + OTz /= 3; + if ((OTz > 0) && (OTz < OTLEN) && (*meshes[k]->p < 3588)){ + AddPrim(&ot[db][OTz-2], poly); + } + nextpri += sizeof(POLY_GT3); + + t+=3; + } + } + + // Can we use texture window with UV mapping ? + + //~ dr_mode = (DR_MODE *)nextpri; + + //~ setDrawMode(dr_mode,1,0, getTPage(tim_cube.mode&0x3, 0, + //~ tim_cube.prect->x, + //~ tim_cube.prect->y), &tws); //set texture window + + //~ AddPrim(&ot[db], dr_mode); + + //~ nextpri += sizeof(DR_MODE); + + + + // Render the banner (FntPrint is always on top because it is not part of the OT) + + //~ FntPrint("BASED ON PRIMDRAW BY LAMEGUY64, 2014 \n"); + FntPrint("#Tris :%d \n", sizeof(ot[db])/sizeof(POLY_GT3)); + FntPrint("Vsync :%d \n", VSync(0)); + FntPrint("#Meshes %d\n", sizeof(meshes)/sizeof(TMESH *)); + FntPrint("Cam pos : %d, %d, %d\n", camera.pos.vx, camera.pos.vy, camera.pos.vz); + FntPrint("Cam or : %d, %d", camera.tilt, camera.pan); + + FntPrint("\np:%d", *meshes[0]->p); + FntPrint("\n%d %d", meshes[1]->pos->vx, meshes[1]->pos->vz); + FntPrint("\n%d %d", *meshes[0]->isPrism, *meshes[1]->isPrism); + + FntFlush(-1); + + display(); + + //~ frame = VSync(-1); + + } + return 0; +} void init(){ // Reset the GPU before doing anything and the controller @@ -87,7 +323,7 @@ void init(){ // Initialize and setup the GTE InitGeom(); SetGeomOffset(CENTERX, CENTERY); // x, y offset - SetGeomScreen(CENTERX*2); // Distance between eye and screen + SetGeomScreen(CENTERX); // Distance between eye and screen // Set the display and draw environments SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); @@ -103,8 +339,8 @@ void init(){ disp[1].screen.y += 8; } - setRGB0(&draw[0], 80, 80, 255); - setRGB0(&draw[1], 80, 80, 255); + setRGB0(&draw[0], 0, 0, 0); + setRGB0(&draw[1], 0, 0, 0); draw[0].isbg = 1; draw[1].isbg = 1; @@ -114,14 +350,14 @@ void init(){ // Init font system FntLoad(960, 0); - FntOpen(16, 16, 196, 64, 0, 256); + FntOpen(16, 16, 196, 96, 0, 512); } void display(void){ DrawSync(0); - vs = VSync(0); + vs = VSync(-1); PutDispEnv(&disp[db]); PutDrawEnv(&draw[db]); @@ -137,6 +373,40 @@ void display(void){ } +void applyCamera(CAMERA * cam){ + VECTOR vec; // Vector that holds the output values of the following instructions + + RotMatrix(&cam->rot, &cam->mat); // Convert rotation angle in psx units (360° == 4096) to rotation matrix) + + ApplyMatrixLV(&cam->mat, &cam->pos, &vec); // Multiply matrix by vector pos and output to vec + + TransMatrix(&cam->mat, &vec); // Apply transform vector + + SetRotMatrix(&cam->mat); // Set Rotation matrix + SetTransMatrix(&cam->mat); // Set Transform matrix +} + +void applyOrbCam(MESH * mesh){ + + MATRIX mat; + + RotMatrix(mesh->rot, mesh->mat); // Apply rotation matrix + TransMatrix(mesh->mat, mesh->pos); // Apply translation matrix + + CompMatrixLV(&camera.mat, mesh->mat, &mat); + + SetRotMatrix(&mat); // Set default rotation matrix + SetTransMatrix(&mat); // Set Transform matrix + + //~ RotMatrix(meshes[k]->rot, meshes[k]->mat); // Apply rotation matrix + //~ TransMatrix(meshes[k]->mat, meshes[k]->pos); // Apply translation matrix + + //~ CompMatrixLV(&camera.mat, meshes[k]->mat, &PolyMatrix); + + //~ SetRotMatrix(&PolyMatrix); // Set default rotation matrix + //~ SetTransMatrix(&PolyMatrix); +} + void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous OpenTIM(tim); // Open the tim binary data, feed it the address of the data in memory ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure @@ -151,186 +421,63 @@ void LoadTexture(u_long * tim, TIM_IMAGE * tparam){ // This part is from Lam } -int main() { - - int i; - int PadStatus; - int TPressed=0; - int AutoRotate=1; +void callback(void){ + + PadStatus = PadRead(0); - long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143 + // Camera panning + if (PadStatus & PADLup) camera.tiltv += 8; + if (PadStatus & PADLdown) camera.tiltv -= 8; + if (PadStatus & PADLleft) camera.panv -= 12; + if (PadStatus & PADLright) camera.panv += 12; - POLY_GT3 *poly = {0}; // pointer to a POLY_G4 - - - SVECTOR Rotate={ 0 }; // Rotation coordinates - VECTOR Trans={ 0, 0, CENTERX*2, 0 }; // Translation coordinates - // Scaling coordinates - VECTOR Scale={ ONE, ONE, ONE, 0 }; // ONE == 4096 - MATRIX Matrix={0}; // Matrix data for the GTE - - // Texture window - - DR_MODE * dr_mode; // Pointer to dr_mode prim - - RECT tws = {0, 0, 32, 32}; // Texture window coordinates : x, y, w, h - - init(); - - for (int k = 0; k < sizeof(meshes)/sizeof(TMESH *); k++){ - LoadTexture(meshes[k]->tim_data, meshes[k]->tim); - } - - // Main loop - while (1) { - //~ while ((VSync(-1) - frame) < 1){ - - // Read pad status - PadStatus = PadRead(0); - - if (AutoRotate == 0) { - - if (PadStatus & PADL1) Trans.vz -= 4; - if (PadStatus & PADR1) Trans.vz += 4; - if (PadStatus & PADL2) Rotate.vz -= 8; - if (PadStatus & PADR2) Rotate.vz += 8; - - if (PadStatus & PADLup) Rotate.vx -= 8; - if (PadStatus & PADLdown) Rotate.vx += 8; - if (PadStatus & PADLleft) Rotate.vy -= 14; - if (PadStatus & PADLright) Rotate.vy += 14; - - if (PadStatus & PADRup) Trans.vy -= 2; - if (PadStatus & PADRdown) Trans.vy += 2; - if (PadStatus & PADRleft) Trans.vx -= 2; - if (PadStatus & PADRright) Trans.vx += 2; - - if (PadStatus & PADselect) { - Rotate.vx = Rotate.vy = Rotate.vz = 0; - Scale.vx = Scale.vy = Scale.vz = ONE; - Trans.vx = Trans.vy = 0; - Trans.vz = CENTERX; - } - - } - - if (PadStatus & PADstart) { - if (TPressed == 0) { - AutoRotate = (AutoRotate + 1) & 1; - Rotate.vx = Rotate.vy = Rotate.vz = 0; - Scale.vx = Scale.vy = Scale.vz = ONE; - Trans.vx = Trans.vy = 0; - Trans.vz = CENTERX; - } - TPressed = 1; - } else { - TPressed = 0; - } - - if (AutoRotate) { - Rotate.vy += 8; // Pan - Rotate.vx += 8; // Tilt - //~ Rotate.vz += 8; // Roll - } - - - // Clear the current OT - ClearOTagR(ot[db], OTLEN); - - // Convert and set the matrixes - RotMatrix(&Rotate, &Matrix); - TransMatrix(&Matrix, &Trans); - ScaleMatrix(&Matrix, &Scale); - - SetRotMatrix(&Matrix); - SetTransMatrix(&Matrix); - - for (int k = 0; k < sizeof(meshes)/sizeof(TMESH *); k++){ - - // Render the sample vector model - t=0; - - // modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ... - for (i = 0; i < (meshes[0]->tmesh->len * 3); i += 3) { - - poly = (POLY_GT3 *)nextpri; - - // Initialize the primitive and set its color values - - SetPolyGT3(poly); - - setRGB0(poly, meshes[k]->tmesh->c[i].r , meshes[k]->tmesh->c[i].g , meshes[k]->tmesh->c[i].b); - setRGB1(poly, meshes[k]->tmesh->c[i+1].r, meshes[k]->tmesh->c[i+1].g, meshes[k]->tmesh->c[i+1].b); - setRGB2(poly, meshes[k]->tmesh->c[i+2].r, meshes[k]->tmesh->c[i+2].g, meshes[k]->tmesh->c[i+2].b); - - ((POLY_GT3 *)poly)->tpage = getTPage(meshes[k]->tim->mode&0x3, 0, - meshes[k]->tim->prect->x, - meshes[k]->tim->prect->y - ); - // The TIMs are loaded in vram vertically on the same TPAGE; eg. Tim1 640,0, Tim1 640, 128 - // We then add tim_image.prect.y to the y coord of the uvs to use the correct texture. - - setUV3(poly, meshes[k]->tmesh->u[i].vx , meshes[k]->tmesh->u[i].vy + meshes[k]->tim->prect->y, - meshes[k]->tmesh->u[i+1].vx, meshes[k]->tmesh->u[i+1].vy + meshes[k]->tim->prect->y, - meshes[k]->tmesh->u[i+2].vx, meshes[k]->tmesh->u[i+2].vy + meshes[k]->tim->prect->y); - - // Rotate, translate, and project the vectors and output the results into a primitive - - OTz = RotTransPers(&meshes[k]->tmesh->v[meshes[k]->index[t]] , (long*)&poly->x0, &p, &Flag); - OTz += RotTransPers(&meshes[k]->tmesh->v[meshes[k]->index[t+1]], (long*)&poly->x1, &p, &Flag); - OTz += RotTransPers(&meshes[k]->tmesh->v[meshes[k]->index[t+2]], (long*)&poly->x2, &p, &Flag); - - - // Using RotTransPers3 is a bit faster (-31ms/frame), but you loose precision for Z-ordering - //~ OTz = RotTransPers3( - //~ &meshes[k]->tmesh->v[meshes[k]->index[t]], - //~ &meshes[k]->tmesh->v[meshes[k]->index[t+1]], - //~ &meshes[k]->tmesh->v[meshes[k]->index[t+2]], - //~ (long*)&poly->x0, (long*)&poly->x1, (long*)&poly->x2, - //~ &p, - //~ &Flag - //~ ); - - // Sort the primitive into the OT - OTz /= 3; - if ((OTz > 0) && (OTz < OTLEN)) - AddPrim(&ot[db][OTz-2], poly); - - nextpri += sizeof(POLY_GT3); - - t+=3; - - } - } - - //~ dr_mode = (DR_MODE *)nextpri; - - //~ setDrawMode(dr_mode,1,0, getTPage(tim_cube.mode&0x3, 0, - //~ tim_cube.prect->x, - //~ tim_cube.prect->y), &tws); //set texture window - - //~ AddPrim(&ot[db], dr_mode); - - //~ nextpri += sizeof(DR_MODE); - - // Render the banner (FntPrint is always on top because it is not part of the OT) - //~ #if HI_RES - //~ FntPrint("\n\n"); - //~ #endif - //~ FntPrint("\n\nGOURAUD SHADED TMESH EXAMPLE\n"); - //~ FntPrint("SCHNAPPY, 2020 \n"); - //~ FntPrint("BASED ON PRIMDRAW BY LAMEGUY64, 2014 \n"); - FntPrint("# tris :%d \n", sizeof(ot[db])/sizeof(POLY_GT3)); - FntPrint("Vsync :%d \n", vs); - FntPrint("%d ", sizeof(meshes)/sizeof(TMESH *)); - FntPrint("%d ", meshes[0]->tim->prect->y); - - FntFlush(-1); - - display(); - - //~ frame = VSync(-1); - + // Camera movement + if (PadStatus & PADRup) { + camera.zv += (ccos(camera.pan) * ccos(camera.tilt)) / 1024; // pan = horizontal motion, tilt = vertical. cos(pan) returns value in rang -ONE,ONE on the horiz. axis. -4096-0 = left, 0-4096 = right + camera.xv += (csin(camera.pan) * ccos(camera.tilt)) / 1024; + camera.yv += (csin(camera.tilt) * ccos(camera.tilt)) / 1024; } - return 0; -} + + if (PadStatus & PADRdown) { + camera.zv -= (ccos(camera.pan) * ccos(camera.tilt)) / 1024; // pan = horizontal motion, tilt = vertical. cos(pan) returns value in rang -ONE,ONE on the horiz. axis. -4096-0 = left, 0-4096 = right + camera.xv -= (csin(camera.pan) * ccos(camera.tilt)) / 1024; + camera.yv -= (csin(camera.tilt) * ccos(camera.tilt)) / 1024; + } + + if (PadStatus & PADRleft) { + camera.zv += (csin(camera.pan)*2); + camera.xv -= (ccos(camera.pan)*2); + } + + if (PadStatus & PADRright) { + camera.zv -= (csin(camera.pan)*2); + camera.xv += (ccos(camera.pan)*2); + } + + if (PadStatus & PADR1) camera.yv -= ONE*1; + if (PadStatus & PADR2) camera.yv += ONE*1; + + // Reset + if (PadStatus & PADselect) { + camera.x = camera.y = camera.z = 0; + camera.pan = camera.tilt = camera.rol = 0; + camera.panv = camera.tiltv = 0; + camera.xv = 0; + camera.yv = 0; + camera.zv = -150; + } + + camera.x += camera.xv; + camera.y += camera.yv; + camera.z += camera.zv; + camera.pan += camera.panv; + camera.tilt += camera.tiltv; + + camera.xv = 0; + camera.yv = 0; + camera.zv = 0; + camera.panv = 0; + camera.tiltv = 0; + + + }