/* Morph v1.0 My first program in Yaroze. 7/XI/1997 F Javier Ventoso Reigosa ID: JAVIER (Vilanova de Arousa-Pontevedra-Spain) e-mail: xavit@mx2.redestb.es */ #include #include "pad.h" #define PI 3.1416 #define PI2 PI*2 double tsen[256]; double tcos[256]; // paquetes GPU #define PACKETMAX 1500 #define PACKETMAX2 (PACKETMAX*24) #define TMDCara1 (u_long *)0x80090000 #define TMDCara2 (u_long *)0x800a0000 // whithout normals #define TMDCara3 (u_long *)0x800a5000 // whithout normals GsDOBJ2 Cara1OBJ; GsCOORDINATE2 Cara1SysCoord; #define setVector(v,x,y,z) (v)->vx = (x), (v)->vy = (y), (v)->vz = (z) #define setColor(c,_r,_g,_b) (c)->r = (_r), (c)->g = (_g), (c)->b = (_b) #define lengthOT 12 GsOT OT[2]; GsOT_TAG zTable[2][1 << lengthOT]; PACKET GpuOutputPacket[2][PACKETMAX2]; GsRVIEW2 Nikon; int BuffInd; u_long radio = 100; typedef struct { u_long *vert_top; u_long n_vert; u_long *normal_top; u_long n_normal; u_long *primitive_top; u_long n_primitive; long scale; } _TMD; _TMD *TMD1Handler; _TMD *TMD2Handler; _TMD *TMD3Handler; typedef struct { short x; short y; short z; short pad; } _VERTEX; _VERTEX *VERTEX1Handler; _VERTEX *VERTEX2Handler; _VERTEX *VERTEX3Handler; void init_sen_cos( void ); int ControlPad( void ); void loadTMD1( u_long *tmdAddr, char objNum, GsDOBJ2 *obj ) { GsMapModelingData( (u_long *)(tmdAddr + 1) ); GsLinkObject4( (u_long)(tmdAddr + 3), obj, objNum ); TMD1Handler = (_TMD *)(tmdAddr+3); VERTEX1Handler = (_VERTEX*)TMD1Handler->vert_top; } void loadTMD2( u_long *tmdAddr ) { GsMapModelingData( (u_long*)(tmdAddr+1) ); TMD2Handler = (_TMD *)(tmdAddr+3); VERTEX2Handler = (_VERTEX*)TMD2Handler->vert_top; } void loadTMD3( u_long *tmdAddr ) { GsMapModelingData( (u_long*)(tmdAddr+1) ); TMD3Handler = (_TMD *)(tmdAddr+3); VERTEX3Handler = (_VERTEX*)TMD3Handler->vert_top; } float aIncs[900][3]; // incs for morph float aTermError[900][3]; // interpolation's term error char nMorphActual = 3; // 2 = morph 1 to 2 // 3 = morph 1 to 3 char nRunMorph = 0; // run morph x ( 2 or 3 ) void interpola_1_2_objects( void ) { int ncon; u_long nNumVertex = TMD1Handler->n_vert; printf( "Morphing 1 to 2... \n" ); for( ncon = 0; ncon < nNumVertex; ncon++ ) { aIncs[ncon][0] = (float)(VERTEX2Handler->x - VERTEX1Handler->x)/256; aIncs[ncon][1] = (float)(VERTEX2Handler->y - VERTEX1Handler->y)/256; aIncs[ncon][2] = (float)(VERTEX2Handler->z - VERTEX1Handler->z)/256; VERTEX1Handler++; VERTEX2Handler++; } VERTEX1Handler -= nNumVertex; VERTEX2Handler -= nNumVertex; for( ncon = 0; ncon < nNumVertex; ncon++ ) { aTermError[ncon][0] = (float)VERTEX1Handler->x; aTermError[ncon][1] = (float)VERTEX1Handler->y; aTermError[ncon][2] = (float)VERTEX1Handler->z; VERTEX1Handler++; } VERTEX1Handler -= nNumVertex; } void run_1_2_morph( void ) { static short nframe = 0; short ncon; if( (nRunMorph != 2) || (nMorphActual == 2) ) return; // 256 morph's frames if( nframe > 256 ) { nframe = 0; // init to 0 for new future morph nRunMorph = 0; // init to 0 because morph is done nMorphActual = 2; // fix current morph number return; } for( ncon = 0; ncon < TMD1Handler->n_vert; ncon++ ) { aTermError[ncon][0] += aIncs[ncon][0]; aTermError[ncon][1] += aIncs[ncon][1]; aTermError[ncon][2] += aIncs[ncon][2]; VERTEX1Handler->x = (short) aTermError[ncon][0]; VERTEX1Handler->y = (short) aTermError[ncon][1]; VERTEX1Handler->z = (short) aTermError[ncon][2]; VERTEX1Handler++; } VERTEX1Handler -= TMD1Handler->n_vert; nframe++; } void interpola_1_3_objects( void ) { int ncon; u_long nNumVertex = TMD1Handler->n_vert; printf( "Morphing 1 to 3... \n" ); for( ncon = 0; ncon < nNumVertex; ncon++ ) { aIncs[ncon][0] = (float)(VERTEX3Handler->x - VERTEX1Handler->x)/256; aIncs[ncon][1] = (float)(VERTEX3Handler->y - VERTEX1Handler->y)/256; aIncs[ncon][2] = (float)(VERTEX3Handler->z - VERTEX1Handler->z)/256; VERTEX1Handler++; VERTEX3Handler++; } VERTEX1Handler -= nNumVertex; VERTEX3Handler -= nNumVertex; for( ncon = 0; ncon < nNumVertex; ncon++ ) { aTermError[ncon][0] = (float)VERTEX1Handler->x; aTermError[ncon][1] = (float)VERTEX1Handler->y; aTermError[ncon][2] = (float)VERTEX1Handler->z; VERTEX1Handler++; } VERTEX1Handler -= nNumVertex; } void run_1_3_morph( void ) { static short nframe = 0; short ncon; if( (nRunMorph != 3) || (nMorphActual == 3) ) return; // 256 morph's frames if( nframe > 256 ) { nframe = 0; // init to 0 for new future morph nRunMorph = 0; // init to 0 because morph is done nMorphActual = 3; // fix current morph number return; } for( ncon = 0; ncon < TMD1Handler->n_vert; ncon++ ) { aTermError[ncon][0] += aIncs[ncon][0]; aTermError[ncon][1] += aIncs[ncon][1]; aTermError[ncon][2] += aIncs[ncon][2]; VERTEX1Handler->x = (short) aTermError[ncon][0]; VERTEX1Handler->y = (short) aTermError[ncon][1]; VERTEX1Handler->z = (short) aTermError[ncon][2]; VERTEX1Handler++; } VERTEX1Handler -= TMD1Handler->n_vert; nframe++; } int main(void) { MATRIX transformMatrix; short int angleObject = 0; int incAngleObject = 5; SVECTOR vRotation; GsF_LIGHT Light1, Light2, Light3; MATRIX screenMatrix; unsigned short int angle = 0; printf( "Init sin & cos table... \n" ); init_sen_cos(); PadInit(); ResetGraph(0); SetVideoMode( MODE_PAL ); GsInitGraph( 320, 256, GsOFSGPU, 1, 0 ); GsDefDispBuff(0, 0, 0, 256); GsInit3D(); // init OT OT[0].length = lengthOT; OT[0].org = zTable[0]; OT[1].length = lengthOT; OT[1].org = zTable[1]; // load 3D objects loadTMD1( TMDCara1, 0, &Cara1OBJ ); loadTMD2( TMDCara2 ); loadTMD3( TMDCara3 ); // init coord Cara1OBJ.coord2 = &Cara1SysCoord; GsInitCoordinate2( WORLD, &Cara1SysCoord ); // init lights setColor( &Light1, 150, 80, 0 ); setVector( &Light1, 0, -ONE, ONE ); GsSetFlatLight( 0, &Light1 ); setColor( &Light2, 0, 50, 255 ); setVector( &Light2, -ONE, 0, -ONE/2 ); GsSetFlatLight( 1, &Light2 ); setColor( &Light3, 0, 255, 0 ); setVector( &Light3, ONE, 0, -ONE/2 ); GsSetFlatLight( 2, &Light3 ); // fog on & fix ambient GsSetLightMode( 1 ); GsSetAmbient(ONE/2,ONE/2,ONE/2); // init projection GsSetProjection(500); // fix camera Nikon.vpx = 0; Nikon.vpy = -500; Nikon.vpz = -1500; Nikon.vrx = 0; Nikon.vry = 0; Nikon.vrz = 0; Nikon.rz = 0; Nikon.super = WORLD; for(;;) { // init general settings BuffInd = GsGetActiveBuff(); GsSetWorkBase( (PACKET * ) GpuOutputPacket[BuffInd] ); GsClearOt( 0, 0, &OT[BuffInd] ); GsSetRefView2( &Nikon ); // init transform matrix to id matrix transformMatrix = GsIDMATRIX; // reboot the object if( angleObject > 1024 ) incAngleObject = -incAngleObject; if( angleObject < -1024 ) incAngleObject = -incAngleObject; // set rotation vector setVector( &vRotation, 0, angleObject, 0 ); // rotate RotMatrix( &vRotation, &transformMatrix ); // do circular translation ( XY plane ) transformMatrix.t[0] += tcos[(int)(angle+256)%256] * radio; transformMatrix.t[1] -= tsen[(int)(angle+256)%256] * radio; angle += 3; // fix transform matrix to object coord Cara1SysCoord.coord = transformMatrix; Cara1SysCoord.flg = 0; // set the lights in the axis defined by transformMatrix GsSetLightMatrix( &transformMatrix ); // calculate screen matrix GsGetLs( &Cara1SysCoord, &screenMatrix ); // set screen matrix GsSetLsMatrix( &screenMatrix ); // make packets GsSortObject4( &Cara1OBJ, &OT[BuffInd], 14 - OT[BuffInd].length, (u_long *) getScratchAddr( 0 ) ); DrawSync(0); VSync(0); if( !ControlPad() ) break; GsSwapDispBuff(); GsSortClear(0, 0, 0, &OT[BuffInd]); GsDrawOt( &OT[BuffInd] ); // inc angle angleObject += incAngleObject; // run morphs run_1_2_morph(); run_1_3_morph(); } // ญญญ Ala !!! a comer... ResetGraph( 1 ); return 0; } // return 0 with select & start int ControlPad() { u_long ncon; u_long PAD = PadRead(); if( PAD & PADstart && PAD & PADselect ) return( 0 ); // radio if( PAD & PADR1 ) { radio += 1; printf( "Radio : %d \r", radio ); } if( PAD & PADR2 ) { if( radio > 0 ) { radio -= 1; printf ("Radio : %d \r", radio ); } } // change camera if( PAD & PADL1 ) { Nikon.super = WORLD; printf( "Camera to world \r" ); } if( PAD & PADL2 ) { Nikon.super = &Cara1SysCoord; printf( "Camera to face \r" ); } if( PAD & PADLup ) { if( Nikon.vpz < -700 ) { Nikon.vpz += 50; GsSetRefView2( &Nikon ); } } if( PAD & PADLdown ) { if( Nikon.vpz > -20000 ) { Nikon.vpz -= 50; GsSetRefView2( &Nikon ); } } // deform object in YZ plane ( if nRunMorph = 0 ) if( PAD & PADRup ) { if( !nRunMorph ) { for( ncon = 0; ncon < TMD1Handler->n_vert; ncon++ ) { if( ncon % 2 ) VERTEX1Handler->y += 10; else VERTEX1Handler->z += 10; VERTEX1Handler++; } VERTEX1Handler -= TMD1Handler->n_vert; } } if( PAD & PADRdown ) { if( !nRunMorph ) { for( ncon = 0; ncon < TMD1Handler->n_vert; ncon++ ) { if( ncon % 2 ) VERTEX1Handler->y -= 10; else VERTEX1Handler->z -= 10; VERTEX1Handler++; } VERTEX1Handler -= TMD1Handler->n_vert; } } // MORPH!!! object 1 to 2 if( PAD & PADRleft ) { if( (nRunMorph == 0) && (nMorphActual != 2) ) { interpola_1_2_objects(); nRunMorph = 2; } } // morph object 1 to 3 if( PAD & PADRright ) { if( !nRunMorph && (nMorphActual != 3 ) ) { interpola_1_3_objects(); nRunMorph = 3; } } return( 1 ); } void init_sen_cos( void ) { int ncon; for( ncon = 0; ncon < 256; ncon++ ) { tsen[ncon] = ( double ) sin( ncon*PI2/256 ); tcos[ncon] = ( double ) cos( ncon*PI2/256 ); printf( "Working... %d%% \r", ncon*100/256 ); } }