quaternion_s make_look_quaternion(vect_s direction, vect_s up) { vect_s i = vect_normalize(direction); vect_s j = vect_normalize(vect_sub(up, vect_project(up, direction))); vect_s k = vect_cross(i, j); return make_quaternion_from_ijk(i, j, k); }
void AD_Object3D::get_vertex_normal (int16 quale, AD_Vect3D *vnorm) { int16 tt; AD_Vect3D somma; AD_Vertex3D *quale_ptr; vect_set(&somma, 0, 0, 0); quale_ptr=&vertex3D[quale]; for (tt=0; tt<num_tria; tt++) { if ((tria[tt].v1==quale_ptr) || (tria[tt].v2==quale_ptr) || (tria[tt].v3==quale_ptr)) vect_add(&somma, &tria[tt].normal, &somma); } vect_normalize(&somma); vect_copy(&somma, vnorm); }
static void handle_tick( game_context_s *context, void *data, const nothing_s *n) { dummy_scene_s *dummy_scene = data; const transform_s *transform = handle_get(dummy_scene->transform); const player_input_s *player_input = handle_get(dummy_scene->player_input); if(transform && player_input) { send_transform_move(context, transform->component, vect_div(player_input->direction, 100)); send_transform_rotate(context, transform->component, make_quaternion_rotation( vect_normalize(make_vect(1, 1, 1)), 0.01)); if(transform->pos.x > 100) game_remove_component(context, dummy_scene->group); } }
/* input: correlation matrix * size of the matrix * list of bags * <norm> the normal factor for the new matrix row * output: new correlation matrix */ double * gates_update_correlation_matrix (double *corrmat, int *size, GQueue *bags, double norm) { if (!corrmat) { *size = 1; return corrmat_init (1, .0); } double *m = corrmat_resize_once (corrmat, size, .0); double *sim = bags_naive_vote (bags, *size); // normalize vect_normalize (sim, *size, norm); // smoothen // double *sims = math_smooth_double (sim, *size, 3); // cut the diagonal int diagsize = 1; for (int i=0;i<diagsize;i++) { if (i <= *size - 1) sim[*size-1-i] = .0; } printf ("sim vector: \n"); for (int i=0;i<*size;i++) printf ("%.4f ", sim[i]); printf ("\n"); for (int i=0;i<*size;i++) { CORRMAT_SET (m, *size, *size-1, i, sim[i]); } free (sim); return m; }
int AD_PatchObject::Tassellate_NormalsTexture(void) { // *************************************************************** // TASSELLIZZAZIONE con generazione anche delle normali ai vertici // e coordinate texture // *************************************************************** AD_Vertex3D *vertex_row_up, *vertex_row_down; AD_Vect3D *points_already_calculated, *points_to_calculate; AD_VectUV *UVpoints_already_calculated, *UVpoints_to_calculate; AD_Vect3D *normals_already_calculated, *normals_to_calculate; float4 u_step, v_step, u, v; float4 tu0, tu1, tv0, tv1, dtu, dtv; int num_u_step, num_v_step, w, i, j; int ntria=0; AD_Vect3D p1, p2; u_step=1.0f/(u_evaluations-1); num_u_step=(int)(u_evaluations); v_step=1.0f/(v_evaluations-1); num_v_step=(int)(v_evaluations); points_already_calculated=&points_tr[0]; points_to_calculate=&points_tr[num_u_step]; vertex_row_up=&vertex3D[0]; vertex_row_down=&vertex3D[num_u_step]; UVpoints_already_calculated=&vertexUV[0]; UVpoints_to_calculate=&vertexUV[num_u_step]; normals_already_calculated=&normals[0]; normals_to_calculate=&normals[num_u_step]; ntria=0; for (w=0; w<num_patches; w++) { // precalcolo fila iniziale (isoparametrica v=0) v=u=0; dtu=(UVverteces[patches[w].UVvert[3]].u- UVverteces[patches[w].UVvert[0]].u)/(u_evaluations-1); dtv=(UVverteces[patches[w].UVvert[3]].v- UVverteces[patches[w].UVvert[0]].v)/(u_evaluations-1); tu0=UVverteces[patches[w].UVvert[0]].u; tv0=UVverteces[patches[w].UVvert[0]].v; for (i=0; i<num_u_step; i++) { Evaluate_Patch(&patches[w], u, 0, &points_already_calculated[i]); Evaluate_uDerivate(&patches[w], u, 0, &p1); Evaluate_vDerivate(&patches[w], u, 0, &p2); vect_cross(&p1, &p2, &normals_already_calculated[i]); vect_normalize(&normals_already_calculated[i]); UVpoints_already_calculated[i].u=tu0; UVpoints_already_calculated[i].v=tv0; tu0+=dtu; tv0+=dtv; u+=u_step; } v=0; for (j=0; j<num_v_step-1; j++) { v+=v_step; u=0; tu0= v*UVverteces[patches[w].UVvert[1]].u+ (1-v)*UVverteces[patches[w].UVvert[0]].u; tv0= v*UVverteces[patches[w].UVvert[1]].v+ (1-v)*UVverteces[patches[w].UVvert[0]].v; tu1= v*UVverteces[patches[w].UVvert[2]].u+ (1-v)*UVverteces[patches[w].UVvert[3]].u; tv1= v*UVverteces[patches[w].UVvert[2]].v+ (1-v)*UVverteces[patches[w].UVvert[3]].v; dtu=(tu1-tu0)/(u_evaluations-1); dtv=(tv1-tv0)/(u_evaluations-1); for (i=0; i<num_u_step; i++) { Evaluate_Patch(&patches[w], u, v, &points_to_calculate[i]); Evaluate_uDerivate(&patches[w], u, v, &p1); Evaluate_vDerivate(&patches[w], u, v, &p2); vect_cross(&p1, &p2, &normals_to_calculate[i]); vect_normalize(&normals_to_calculate[i]); UVpoints_to_calculate[i].u=tu0; UVpoints_to_calculate[i].v=tv0; tu0+=dtu; tv0+=dtv; u+=u_step; } // creazione dei triangoli for (i=0; i<num_u_step-1; i++) { tria[ntria].v1=vertex_row_up; tria[ntria].v2=&(*(vertex_row_up+1)); tria[ntria].v3=&(*(vertex_row_down+1)); tria[ntria].v1->tpoint=&points_already_calculated[i]; tria[ntria].v2->tpoint=&points_already_calculated[i+1]; tria[ntria].v3->tpoint=&points_to_calculate[i+1]; tria[ntria].v1->normal=&normals_already_calculated[i]; tria[ntria].v2->normal=&normals_already_calculated[i+1]; tria[ntria].v3->normal=&normals_to_calculate[i+1]; // calcolo della normale vect_sub(tria[ntria].v1->tpoint, tria[ntria].v2->tpoint, &p1); vect_sub(tria[ntria].v3->tpoint, tria[ntria].v2->tpoint, &p2); vect_cross(&p1, &p2, &tria[ntria].normal); vect_normalize(&tria[ntria].normal); tria[ntria].uv1=&UVpoints_already_calculated[i]; tria[ntria].uv2=&UVpoints_already_calculated[i+1]; tria[ntria].uv3=&UVpoints_to_calculate[i+1]; ntria++; tria[ntria].v1=&(*(vertex_row_down+1)); tria[ntria].v2=vertex_row_down; tria[ntria].v3=vertex_row_up; tria[ntria].v1->tpoint=&points_to_calculate[i+1]; tria[ntria].v2->tpoint=&points_to_calculate[i]; tria[ntria].v3->tpoint=&points_already_calculated[i]; tria[ntria].v1->normal=&normals_to_calculate[i+1]; tria[ntria].v2->normal=&normals_to_calculate[i]; tria[ntria].v3->normal=&normals_already_calculated[i]; // calcolo della normale vect_sub(tria[ntria].v1->tpoint, tria[ntria].v2->tpoint, &p1); vect_sub(tria[ntria].v3->tpoint, tria[ntria].v2->tpoint, &p2); vect_cross(&p1, &p2, &tria[ntria].normal); vect_normalize(&tria[ntria].normal); tria[ntria].uv1=&UVpoints_to_calculate[i+1]; tria[ntria].uv2=&UVpoints_to_calculate[i]; tria[ntria].uv3=&UVpoints_already_calculated[i]; ntria++; vertex_row_up+=1; vertex_row_down+=1; } vertex_row_up+=1; vertex_row_down+=1; points_already_calculated+=num_u_step; points_to_calculate+=num_u_step; normals_already_calculated+=num_u_step; normals_to_calculate+=num_u_step; UVpoints_already_calculated+=num_u_step; UVpoints_to_calculate+=num_u_step; } vertex_row_up+=num_u_step; vertex_row_down+=num_u_step; points_already_calculated+=num_u_step; points_to_calculate+=num_u_step; normals_already_calculated+=num_u_step; normals_to_calculate+=num_u_step; UVpoints_already_calculated+=num_u_step; UVpoints_to_calculate+=num_u_step; } return(ntria); }
int AD_PatchObject::Tassellate_Normals(void) { // *************************************************************** // TASSELLIZZAZIONE con generazione anche delle normali ai vertici // *************************************************************** AD_Vertex3D *vertex_row_up, *vertex_row_down; AD_Vect3D *points_already_calculated, *points_to_calculate; AD_Vect3D *normals_already_calculated, *normals_to_calculate; float4 u_step, v_step, u, v; int num_u_step, num_v_step, w, i, j; int ntria=0; AD_Vect3D p1, p2; u_step=1.0f/(u_evaluations-1); num_u_step=(int)(u_evaluations); v_step=1.0f/(v_evaluations-1); num_v_step=(int)(v_evaluations); points_already_calculated=&points_tr[0]; points_to_calculate=&points_tr[num_u_step]; vertex_row_up=&vertex3D[0]; vertex_row_down=&vertex3D[num_u_step]; normals_already_calculated=&normals[0]; normals_to_calculate=&normals[num_u_step]; ntria=0; for (w=0; w<num_patches; w++) { // precalcolo fila iniziale (isoparametrica v=0) v=u=0; for (i=0; i<num_u_step; i++) { Evaluate_Patch(&patches[w], u, 0, &points_already_calculated[i]); Evaluate_uDerivate(&patches[w], u, 0, &p1); Evaluate_vDerivate(&patches[w], u, 0, &p2); vect_cross(&p1, &p2, &normals_already_calculated[i]); vect_normalize(&normals_already_calculated[i]); u+=u_step; } v=0; for (j=0; j<num_v_step-1; j++) { v+=v_step; u=0; for (i=0; i<num_u_step; i++) { Evaluate_Patch(&patches[w], u, v, &points_to_calculate[i]); Evaluate_uDerivate(&patches[w], u, v, &p1); Evaluate_vDerivate(&patches[w], u, v, &p2); vect_cross(&p1, &p2, &normals_to_calculate[i]); vect_normalize(&normals_to_calculate[i]); u+=u_step; } // creazione dei triangoli for (i=0; i<num_u_step-1; i++) { tria[ntria].v1=vertex_row_up; tria[ntria].v2=&(*(vertex_row_up+1)); tria[ntria].v3=&(*(vertex_row_down+1)); tria[ntria].v1->tpoint=&points_already_calculated[i]; tria[ntria].v2->tpoint=&points_already_calculated[i+1]; tria[ntria].v3->tpoint=&points_to_calculate[i+1]; tria[ntria].v1->normal=&normals_already_calculated[i]; tria[ntria].v2->normal=&normals_already_calculated[i+1]; tria[ntria].v3->normal=&normals_to_calculate[i+1]; // calcolo della normale vect_sub(tria[ntria].v1->tpoint, tria[ntria].v2->tpoint, &p1); vect_sub(tria[ntria].v3->tpoint, tria[ntria].v2->tpoint, &p2); vect_cross(&p1, &p2, &tria[ntria].normal); vect_normalize(&tria[ntria].normal); ntria++; tria[ntria].v1=&(*(vertex_row_down+1)); tria[ntria].v2=vertex_row_down; tria[ntria].v3=vertex_row_up; tria[ntria].v1->tpoint=&points_to_calculate[i+1]; tria[ntria].v2->tpoint=&points_to_calculate[i]; tria[ntria].v3->tpoint=&points_already_calculated[i]; tria[ntria].v1->normal=&normals_to_calculate[i+1]; tria[ntria].v2->normal=&normals_to_calculate[i]; tria[ntria].v3->normal=&normals_already_calculated[i]; // calcolo della normale vect_sub(tria[ntria].v1->tpoint, tria[ntria].v2->tpoint, &p1); vect_sub(tria[ntria].v3->tpoint, tria[ntria].v2->tpoint, &p2); vect_cross(&p1, &p2, &tria[ntria].normal); vect_normalize(&tria[ntria].normal); ntria++; vertex_row_up+=1; vertex_row_down+=1; } vertex_row_up+=1; vertex_row_down+=1; points_already_calculated+=num_u_step; points_to_calculate+=num_u_step; normals_already_calculated+=num_u_step; normals_to_calculate+=num_u_step; } vertex_row_up+=num_u_step; vertex_row_down+=num_u_step; points_already_calculated+=num_u_step; points_to_calculate+=num_u_step; normals_already_calculated+=num_u_step; normals_to_calculate+=num_u_step; } return(ntria); }
/* Decodes a 3x4 transformation matrix into separate scale, rotation, translation, and shear vectors. Based on a program by Spencer W. Thomas (Graphics Gems II) */ void mat_decode (Matrix mat, Vector scale, Vector shear, Vector rotate, Vector transl) { int i; Vector row[3], temp; for (i = 0; i < 3; i++) transl[i] = mat[3][i]; for (i = 0; i < 3; i++) { row[i][X] = mat[i][0]; row[i][Y] = mat[i][1]; row[i][Z] = mat[i][2]; } scale[X] = vect_mag (row[0]); vect_normalize (row[0]); shear[X] = vect_dot (row[0], row[1]); row[1][X] = row[1][X] - shear[X]*row[0][X]; row[1][Y] = row[1][Y] - shear[X]*row[0][Y]; row[1][Z] = row[1][Z] - shear[X]*row[0][Z]; scale[Y] = vect_mag (row[1]); vect_normalize (row[1]); if (scale[Y] != 0.0) shear[X] /= scale[Y]; shear[Y] = vect_dot (row[0], row[2]); row[2][X] = row[2][X] - shear[Y]*row[0][X]; row[2][Y] = row[2][Y] - shear[Y]*row[0][Y]; row[2][Z] = row[2][Z] - shear[Y]*row[0][Z]; shear[Z] = vect_dot (row[1], row[2]); row[2][X] = row[2][X] - shear[Z]*row[1][X]; row[2][Y] = row[2][Y] - shear[Z]*row[1][Y]; row[2][Z] = row[2][Z] - shear[Z]*row[1][Z]; scale[Z] = vect_mag (row[2]); vect_normalize (row[2]); if (scale[Z] != 0.0) { shear[Y] /= scale[Z]; shear[Z] /= scale[Z]; } vect_cross (temp, row[1], row[2]); if (vect_dot (row[0], temp) < 0.0) { for (i = 0; i < 3; i++) { scale[i] *= -1.0; row[i][X] *= -1.0; row[i][Y] *= -1.0; row[i][Z] *= -1.0; } } if (row[0][Z] < -1.0) row[0][Z] = -1.0; if (row[0][Z] > +1.0) row[0][Z] = +1.0; rotate[Y] = asin(-row[0][Z]); if (fabs(cos(rotate[Y])) > EPSILON) { rotate[X] = atan2 (row[1][Z], row[2][Z]); rotate[Z] = atan2 (row[0][Y], row[0][X]); } else { rotate[X] = atan2 (row[1][X], row[1][Y]); rotate[Z] = 0.0; } /* Convert the rotations to degrees */ rotate[X] = (180.0/PI)*rotate[X]; rotate[Y] = (180.0/PI)*rotate[Y]; rotate[Z] = (180.0/PI)*rotate[Z]; }
color* trace( ray *aray, primitive *scene, int depth, float refr, float *dist, int shadows ){ intersection *isect; primitive *prim, *iter; vector isect_pt, pn, lv, ln, tmpv1, tmpv2; ray tmpr; float tmpf1, tmpf2, tmpf3, shade; color *tmpc; color *c = (color*)malloc( sizeof( color ) ); if( c == NULL ) { fprintf( stderr, "*** error: could not allocate color memory\n" ); exit( 1 ); } c->x = 0.0f; c->y = 0.0f; c->z = 0.0f; isect = intersect( aray, scene ); if( isect == NULL ) { return c; } *dist = isect->dist; prim = isect->prim; if( prim->is_light ) { vect_copy( c, &(isect->prim->mat.col) ); free( isect ); return c; } vect_copy( &isect_pt, aray->dir ); vect_multf( &isect_pt, isect->dist ); vect_add( &isect_pt, aray->origin ); prim->normal( prim, &isect_pt, &pn ); iter = scene; while( iter != NULL ) { if( iter->is_light ) { vect_copy( &lv, &iter->center ); vect_sub( &lv, &isect_pt ); vect_copy( &ln, &lv ); vect_normalize( &ln ); shade = calc_shade( iter, &isect_pt, &lv, &ln, scene, shadows ); if( shade > 0.0f ) { /* determine the diffuse component */ tmpf1 = prim->mat.diffuse; if( tmpf1 > 0.0f ) { tmpf2 = vect_dot( &pn, &ln ); if( tmpf2 > 0.0f ) { tmpf1 *= tmpf2 * shade; vect_copy( &tmpv1, &prim->mat.col ); vect_mult( &tmpv1, &iter->mat.col ); vect_multf( &tmpv1, tmpf1 ); vect_add( c, &tmpv1 ); } } /* determine the specular component */ tmpf1 = prim->mat.specular; if( tmpf1 > 0.0f ) { vect_copy( &tmpv1, &pn ); vect_copy( &tmpv2, &ln ); tmpf2 = 2.0f * vect_dot( &ln, &pn ); vect_multf( &tmpv1, tmpf2 ); vect_sub( &tmpv2, &tmpv1 ); tmpf2 = vect_dot( aray->dir, &tmpv2 ); if( tmpf2 > 0.0f ) { tmpf1 = powf( tmpf2, 20.0f ) * tmpf1 * shade; vect_copy( &tmpv1, &iter->mat.col ); vect_multf( &tmpv1, tmpf1 ); vect_add( c, &tmpv1 ); } } } } iter = iter->next; } /* calculate reflection */ if( prim->mat.refl > 0.0f && depth < TRACE_DEPTH ) { vect_copy( &tmpv1, &pn ); vect_multf( &tmpv1, 2.0f * vect_dot( &pn, aray->dir ) ); vect_copy( &tmpv2, aray->dir ); vect_sub( &tmpv2, &tmpv1 ); vect_copy( &tmpv1, &tmpv2 ); vect_multf( &tmpv1, EPSILON ); vect_add( &tmpv1, &isect_pt ); tmpr.origin = &tmpv1; tmpr.dir = &tmpv2; tmpc = trace( &tmpr, scene, depth + 1, refr, &tmpf1, shadows ); vect_multf( tmpc, prim->mat.refl ); vect_copy( &tmpv1, &prim->mat.col ); vect_mult( &tmpv1, tmpc ); vect_add( c, &tmpv1 ); free( tmpc ); } /* calculate refraction */ if( prim->mat.is_refr && depth < TRACE_DEPTH ) { vect_copy( &tmpv1, &pn ); if( isect->inside ) { vect_multf( &tmpv1, -1.0f ); } tmpf1 = refr / prim->mat.refr; tmpf2 = -( vect_dot( &tmpv1, aray->dir ) ); tmpf3 = 1.0f - tmpf1 * tmpf1 * (1.0f - tmpf2 * tmpf2); if( tmpf3 > 0.0f ) { vect_copy( &tmpv2, aray->dir ); vect_multf( &tmpv2, tmpf1 ); vect_multf( &tmpv1, tmpf1 * tmpf2 - sqrtf( tmpf3 ) ); vect_add( &tmpv1, &tmpv2 ); vect_copy( &tmpv2, &tmpv1 ); vect_multf( &tmpv2, EPSILON ); vect_add( &tmpv2, &isect_pt ); tmpr.origin = &tmpv2; tmpr.dir = &tmpv1; tmpc = trace( &tmpr, scene, depth + 1, refr, &tmpf1, shadows ); vect_copy( &tmpv1, &prim->mat.col ); vect_multf( &tmpv1, prim->mat.absorb * tmpf1 ); tmpv2.x = expf( -tmpv1.x ); tmpv2.y = expf( -tmpv1.y ); tmpv2.z = expf( -tmpv1.z ); vect_mult( tmpc, &tmpv2 ); vect_add( c, tmpc ); free( tmpc ); } } free( isect ); if( c->x > 1.0f ) { c->x = 1.0f; } else if( c->x < 0.0f ) { c->x = 0.0f; } if( c->y > 1.0f ) { c->y = 1.0f; } else if( c->y < 0.0f ) { c->y = 0.0f; } if( c->z > 1.0f ) { c->z = 1.0f; } else if( c->z < 0.0f ) { c->z = 0.0f; } return c; }
void render( int width, int height, color ***image, primitive *scene, int aa_level, int shadows ) { float world_left, world_right, world_top, world_bot; float delta_x, delta_y; float screen_x, screen_y; float tmpf; int x, y; int aa_x, aa_y; int aa_root; vector origin, dir; ray r; color *tmpc; world_left = -(4.0f * ((float)width / (float)height) ); world_right = -world_left; world_top = 4.0f; world_bot = -4.0f; /* The amount to shift for each pixel */ delta_x = (world_right - world_left) / width; delta_y = (world_bot - world_top) / height; origin.x = 0.0f; origin.y = 0.0f; origin.z = -5.0f; aa_root = (int)sqrt( aa_level ); screen_y = world_top; for( y = 0; y < height; y++ ) { screen_x = world_left; for( x = 0; x < width; x++ ) { for( aa_x = 0; aa_x < aa_root; aa_x++ ) { for( aa_y = 0; aa_y < aa_root; aa_y++ ) { dir.x = screen_x + delta_x * aa_x / (float)aa_root; dir.y = screen_y + delta_y * aa_y / (float)aa_root; dir.z = 0.0f; vect_sub( &dir, &origin ); vect_normalize( &dir ); r.origin = &origin; r.dir = &dir; tmpc = trace( &r, scene, 0, 1.0f, &tmpf, shadows ); if( image[y][x] == NULL ) { image[y][x] = tmpc; } else { vect_add( image[y][x], tmpc ); free( tmpc ); } } } vect_multf( image[y][x], 1.0f / aa_level ); screen_x += delta_x; } screen_y += delta_y; } }
void AD_Object3D::init_normals(void) // le normali dei triangoli devono essere gia' state calcolate // vertici triangoli e smoothing groups devono già essare in memoria { #define normal_err 0.0001f // indica l'errore massimo possibile x riciclare una normale: + e' alto il numero piu' // si perde qualita' visiva e si guadagna velocita': bisogna trovare un buon compromesso int *condivisi; int *smooth, *nosmooth; // array di triangoli condivisi da smoothare AD_Vect3D *tempnormal; AD_Vect3D normadd; int num_condivisi, i, j, tr, num_smooth, num_nosmooth; int num_normal, norm; float maxerr, err; condivisi=new int[num_tria]; // nel caso peggiore tutti i triangoli sono condivisi smooth=new int[num_tria]; nosmooth=new int[num_tria]; tempnormal=new AD_Vect3D[num_tria*3]; // nel caso peggiore ci sono 3 normali per triangolo num_normal=0; for (i=0; i<num_vertex3D; i++) { // trovo i triangoli che condividono il vertice i num_condivisi=0; for (j=0; j<num_tria; j++) { if ((tria[j].v1==&vertex3D[i]) || (tria[j].v2==&vertex3D[i]) || (tria[j].v3==&vertex3D[i])) { condivisi[num_condivisi]=j; num_condivisi++; } } while (num_condivisi>0) { tr=condivisi[0]; // triangolo di riferimento num_smooth=0; num_nosmooth=0; smooth[num_smooth]=tr; num_smooth++; for(j=1; j<num_condivisi; j++) { if ((triasmoothgroup[tr] & triasmoothgroup[condivisi[j]])!=0) { smooth[num_smooth]=condivisi[j]; num_smooth++; } else { nosmooth[num_nosmooth]=condivisi[j]; num_nosmooth++; } } // cacolo la normale vect_set(&normadd, 0, 0, 0); for (j=0; j<num_smooth; j++) vect_add(&normadd, &tria[smooth[j]].normal, &normadd); vect_normalize(&normadd); // cerco se ne esiste gia' una molto simile j=0; norm=-1; maxerr=normal_err; while (j < num_normal) { // trovo l'errore massimo della normale j err=fmax(fmax(fabsf(normadd.x-tempnormal[j].x), fabsf(normadd.y-tempnormal[j].y)), fabsf(normadd.z-tempnormal[j].z)); if (err < maxerr) { // trovata normale + precisa maxerr=err; norm=j; } j++; } if (norm==-1) { // non trovata: la creo vect_copy(&normadd, &tempnormal[num_normal]); norm=num_normal; num_normal++; } for (j=0; j<num_smooth; j++) { // la assegno al triangolo (cercando il vertice giusto) if (tria[smooth[j]].v1==&vertex3D[i]) tria[smooth[j]].n1=&tempnormal[norm]; if (tria[smooth[j]].v2==&vertex3D[i]) tria[smooth[j]].n2=&tempnormal[norm]; if (tria[smooth[j]].v3==&vertex3D[i]) tria[smooth[j]].n3=&tempnormal[norm]; } // tolgo quelli assegnati e ricompatto gli altri for (j=0; j<num_nosmooth; j++) condivisi[j]=nosmooth[j]; num_condivisi-=num_smooth; } } // copio la parte usata di tempnormal in normal normals = new AD_Vect3D[num_normal]; num_normals=num_normal; for (j=0; j<num_normal; j++) { vect_copy(&tempnormal[j], &normals[j]); for (i=0; i<num_tria; i++) { if (tria[i].n1==&tempnormal[j]) tria[i].n1=&normals[j]; if (tria[i].n2==&tempnormal[j]) tria[i].n2=&normals[j]; if (tria[i].n3==&tempnormal[j]) tria[i].n3=&normals[j]; } } delete [] condivisi; delete [] smooth; delete [] nosmooth; delete [] tempnormal; delete [] triasmoothgroup; // non servono piu' }
int AD_PatchObject::Tassellate_Texture(void) { // *************************************************************** // TASSELLIZZAZIONE con generazione anche delle coordinate texture // *************************************************************** AD_Vertex3D *points_already_calculated, *points_to_calculate; AD_Vertex2D *UVpoints_already_calculated, *UVpoints_to_calculate; float4 u_step, v_step, u, v; float4 tu0, tu1, tv0, tv1, dtu, dtv; int num_u_step, num_v_step, w, i, j; int ntria=0; AD_Vect3D p1, p2; u_step=1.0f/(u_evaluations-1); num_u_step=(int)(u_evaluations); v_step=1.0f/(v_evaluations-1); num_v_step=(int)(v_evaluations); points_already_calculated=&vertex3D[0]; points_to_calculate=&vertex3D[num_u_step]; UVpoints_already_calculated=&vertex2D[0]; UVpoints_to_calculate=&vertex2D[num_u_step]; ntria=0; for (w=0; w<num_patches; w++) { int patcul=Is_Patch_Culled(&patches[w]); if (!patcul) { // precalcolo fila iniziale (isoparametrica v=0) v=u=0; dtu=(UVverteces[patches[w].UVvert[3]].u- UVverteces[patches[w].UVvert[0]].u)/(u_evaluations-1); dtv=(UVverteces[patches[w].UVvert[3]].v- UVverteces[patches[w].UVvert[0]].v)/(u_evaluations-1); tu0=UVverteces[patches[w].UVvert[0]].u; tv0=UVverteces[patches[w].UVvert[0]].v; for (i=0; i<num_u_step; i++) { Evaluate_Patch(&patches[w], u, 0, &points_already_calculated[i].tpoint); UVpoints_already_calculated[i].u=tu0; UVpoints_already_calculated[i].v=tv0; tu0+=dtu; tv0+=dtv; u+=u_step; } v=0; for (j=0; j<num_v_step-1; j++) { v+=v_step; u=0; tu0= v*UVverteces[patches[w].UVvert[1]].u+ (1-v)*UVverteces[patches[w].UVvert[0]].u; tv0= v*UVverteces[patches[w].UVvert[1]].v+ (1-v)*UVverteces[patches[w].UVvert[0]].v; tu1= v*UVverteces[patches[w].UVvert[2]].u+ (1-v)*UVverteces[patches[w].UVvert[3]].u; tv1= v*UVverteces[patches[w].UVvert[2]].v+ (1-v)*UVverteces[patches[w].UVvert[3]].v; dtu=(tu1-tu0)/(u_evaluations-1); dtv=(tv1-tv0)/(u_evaluations-1); for (i=0; i<num_u_step; i++) { Evaluate_Patch(&patches[w], u, v, &points_to_calculate[i].tpoint); UVpoints_to_calculate[i].u=tu0; UVpoints_to_calculate[i].v=tv0; tu0+=dtu; tv0+=dtv; u+=u_step; } // creazione dei triangoli for (i=0; i<num_u_step-1; i++) { tria[ntria].v1=&points_already_calculated[i]; tria[ntria].v2=&points_already_calculated[i+1]; tria[ntria].v3=&points_to_calculate[i+1]; // calcolo della normale vect_sub_inline(&tria[ntria].v1->tpoint, &tria[ntria].v2->tpoint, &p1); vect_sub_inline(&tria[ntria].v3->tpoint, &tria[ntria].v2->tpoint, &p2); vect_cross(&p1, &p2, &tria[ntria].normal); vect_normalize(&tria[ntria].normal); tria[ntria].sp1=&UVpoints_already_calculated[i]; tria[ntria].sp2=&UVpoints_already_calculated[i+1]; tria[ntria].sp3=&UVpoints_to_calculate[i+1]; ntria++; tria[ntria].v1=&points_to_calculate[i+1]; tria[ntria].v2=&points_to_calculate[i]; tria[ntria].v3=&points_already_calculated[i]; // calcolo della normale vect_sub_inline(&tria[ntria].v1->tpoint, &tria[ntria].v2->tpoint, &p1); vect_sub_inline(&tria[ntria].v3->tpoint, &tria[ntria].v2->tpoint, &p2); vect_cross(&p1, &p2, &tria[ntria].normal); vect_normalize(&tria[ntria].normal); tria[ntria].sp1=&UVpoints_to_calculate[i+1]; tria[ntria].sp2=&UVpoints_to_calculate[i]; tria[ntria].sp3=&UVpoints_already_calculated[i]; ntria++; } points_already_calculated+=num_u_step; points_to_calculate+=num_u_step; UVpoints_already_calculated+=num_u_step; UVpoints_to_calculate+=num_u_step; } points_already_calculated+=num_u_step; points_to_calculate+=num_u_step; UVpoints_already_calculated+=num_u_step; UVpoints_to_calculate+=num_u_step; } } return(ntria); }