uint8_t path_get_next (vect_t *p) { if (path.found) { assert (path.get != PATH_DST_NODE_INDEX); uint8_t prev = path.get; vect_t pp; path_pos (prev, &pp); uint8_t next = path.astar_nodes[path.get].prev; path.get = next; path_pos (next, p); while (next != 0xff) { /* Try to remove useless points. */ uint8_t next = path.astar_nodes[path.get].prev; if (next == 0xff || next == PATH_DST_NODE_INDEX) break; vect_t np; path_pos (next, &np); vect_t vnp = np; vect_sub (&vnp, &pp); vect_t vp = *p; vect_sub (&vp, &pp); if (vect_normal_dot_product (&vp, &vnp) == 0) { path.get = next; *p = np; } else break; } return 1; } else return 0; }
void CGravityModifier::m_Force (float4 framepos, AD_Vect3D *pos, AD_Vect3D *vel, AD_Vect3D *accel) { AD_Vect3D posrel, force; float4 dist; if (p_Mapping==FORCE_PLANAR) { if (p_Decay!=0) { vect_sub(pos, &p_CurrentPosition, &posrel); dist = fabsf(vect_dot(&p_Force, &posrel)); vect_scale(&p_ScaledForce, (float4)exp(-p_Decay*dist), accel); } else vect_copy(&p_ScaledForce, accel); } else { vect_sub(&p_CurrentPosition, pos, &force); dist = vect_length(&force); if (dist != 0) vect_auto_scale(&force, 1.0f/dist); if (p_Decay != 0) { vect_scale(&force, p_ScaledStrength*(float4)exp(-p_Decay*dist), accel); } else vect_scale(&force, p_ScaledStrength, accel); } }
void CWindModifier::m_Force (float4 framepos, AD_Vect3D *pos, AD_Vect3D *vel, AD_Vect3D *accel) { AD_Vect3D posrel, tf, p, force, p2; float4 dist, freq, turb; freq=p_Frequency; turb=p_Turbolence; if (p_Mapping==FORCE_PLANAR) { if (p_Decay!=0.0f) { vect_sub(pos, &p_CurrentPosition, &posrel); dist=fabsf(vect_dot(&p_Force, &posrel)); vect_scale(&p_ScaledForce, (float4)exp(-p_Decay*dist), accel); } else vect_copy(&p_ScaledForce, accel); } else { vect_sub(pos, &p_CurrentPosition, &force); dist = vect_length(&force); if (dist != 0) vect_auto_scale(&force, 1.0f/dist); if (p_Decay != 0) vect_scale(&force, p_ScaledStrength*(float4)exp(-p_Decay*dist), accel); else vect_scale(&force, p_ScaledStrength, accel); } if (turb != 0) { vect_sub(pos, &p_CurrentPosition, &p2); freq *= 0.01f; vect_copy(&p2, &p); p.x = freq * framepos; tf.x = noise3(p.x*p_Scale, p.y*p_Scale, p.z*p_Scale); vect_copy(&p2, &p); p.y = freq * framepos; tf.y = noise3(p.x*p_Scale, p.y*p_Scale, p.z*p_Scale); vect_copy(&p2, &p); p.z = freq * framepos; tf.z = noise3(p.x*p_Scale, p.y*p_Scale, p.z*p_Scale); turb *= 0.0001f*forceScaleFactor; vect_auto_scale(&tf, turb); vect_add(accel, &tf, accel); } }
t_vect *get_normal_at_cylinder(t_cylinder *c, t_vect *point) { t_vect *v; t_vect *tmp1; t_vect *tmp2; tmp1 = vect_sub(c->center, point); tmp2 = vect_project(tmp1, c->axis); v = vect_sub(tmp2, tmp1); v = normalize(v); delete_vect(tmp1); delete_vect(tmp2); return (v); }
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); }
/** Update the cache of blocked nodes. */ static void path_blocked_update (void) { uint8_t i, j; for (i = 0; i < PATH_GRID_NODES_NB; i++) { uint8_t valid = 1; /* First, gather information from tables. */ if (!path_nodes[i].usable || food_blocking (path_nodes[i].carry_corn)) valid = 0; else { vect_t pos; path_pos (i, &pos); /* Then, test for obstacles. */ for (j = 0; j < PATH_OBSTACLES_NB; j++) { if (path.obstacles[j].valid) { vect_t v = pos; vect_sub (&v, &path.obstacles[j].c); uint32_t dsq = vect_dot_product (&v, &v); uint32_t r = path.obstacles[j].r; if (dsq <= r * r) { valid = 0; break; } } } } /* Update cache. */ path.valid[i] = valid; } }
int32 CGeometricObject::m_CopyTEX1Vertex(int32 baseIndex, void *dest, CMesh *mesh) { FVFGeometryUV1 *l_dest; int32 i; l_dest=(FVFGeometryUV1 *)dest; /*if (!p_BaseMaterial->m_MapNeedUVTransform(1)) for (i=0; i<mesh->p_NumDriverVertex; i++) { vect_copy(&mesh->p_DriverVertex[i].point, &l_dest[i+baseIndex].point); vect_copy(&mesh->p_DriverVertex[i].normal, &l_dest[i+baseIndex].normal); l_dest[i+baseIndex].uv1.u=mesh->p_DriverVertex[i].uv1.u; l_dest[i+baseIndex].uv1.v=-mesh->p_DriverVertex[i].uv1.v; } else*/ for (i=0; i<mesh->p_NumDriverVertex; i++) { //vect_copy(&mesh->p_DriverVertex[i].point, &l_dest[i+baseIndex].point); vect_sub(&mesh->p_DriverVertex[i].point, &p_Pivot, &l_dest[i+baseIndex].point); vect_copy(&mesh->p_DriverVertex[i].normal, &l_dest[i+baseIndex].normal); l_dest[i+baseIndex].uv1.u=mesh->p_DriverVertex[i].uv1.u; l_dest[i+baseIndex].uv1.v=mesh->p_DriverVertex[i].uv1.v; } return (mesh->p_NumDriverVertex); }
uint8_t radar_blocking (const vect_t *robot_pos, const vect_t *dest_pos, const vect_t *obs_pos, uint8_t obs_nb) { uint8_t i; /* Stop here if no obstacle. */ if (!obs_nb) return 0; vect_t vd = *dest_pos; vect_sub (&vd, robot_pos); uint16_t d = vect_norm (&vd); /* If destination is realy near, stop here. */ if (d < RADAR_EPSILON_MM) return 0; /* If destination is near, use clearance to destination point instead of * stop length. */ vect_t t; if (d < RADAR_STOP_MM) t = *dest_pos; else { vect_scale_f824 (&vd, (1ll << 24) / d * RADAR_STOP_MM); t = *robot_pos; vect_translate (&t, &vd); } /* Now, look at obstacles. */ for (i = 0; i < obs_nb; i++) { /* Vector from robot to obstacle. */ vect_t vo = obs_pos[i]; vect_sub (&vo, robot_pos); /* Ignore if in our back. */ int32_t dp = vect_dot_product (&vd, &vo); if (dp < 0) continue; /* Check distance. */ int16_t od = distance_segment_point (robot_pos, &t, &obs_pos[i]); if (od > BOT_SIZE_SIDE + RADAR_CLEARANCE_MM / 2 + RADAR_OBSTACLE_RADIUS_MM) continue; /* Else, obstacle is blocking. */ return 1; } return 0; }
void gen_normals(MESH* m) { int i; float3 a, b, t; float3 *n = malloc(sizeof(float3)*m->nf); // Generate per face normals for(i=0; i<m->nf; i++) { vect_sub( &a, &m->v[m->f[i].x], &m->v[m->f[i].y] ); vect_sub( &b, &m->v[m->f[i].x], &m->v[m->f[i].z] ); vect_cross( &t, &b, &a ); vect_norm( &n[i], &t); } m->n = n; m->nn = m->nf; }
void CSpotLight::m_Update (float4 frame) { AD_Vect3D l_Dir; if (p_TargetTrack) p_TargetTrack->m_GetData(frame, &p_CurrentTargetPosition); CLight::m_Update(frame); vect_sub(&p_CurrentTargetPosition, &p_CurrentPosition, &l_Dir); p_D3DLight.Direction.x=l_Dir.x; p_D3DLight.Direction.y=l_Dir.y; p_D3DLight.Direction.z=l_Dir.z; }
void CScene3D::m_RotateCamera(float4 ax, float4 ay, float4 az) { AD_Vect3D cameradir, xAxis, yAxis, zAxis, v; AD_Vect3D vx, vy, vz, ptmp; AD_Quaternion q1, q2; AD_Matrix rot1, rot2, rot12, pretrans; if (!p_CurrentCamera) return; // estrazione assi locali mat_get_row(&p_CurrentCamera->p_CurrentRotationMatrix, 0, &xAxis); mat_get_row(&p_CurrentCamera->p_CurrentRotationMatrix, 1, &yAxis); mat_get_row(&p_CurrentCamera->p_CurrentRotationMatrix, 2, &zAxis); // creazioni delle matrici di rotazione quat_set(&q1, xAxis.x, xAxis.y, xAxis.z, ax); quat_set(&q2, yAxis.x, yAxis.y, yAxis.z, ay); quat_quat_to_rotquat(&q1); quat_rotquat_to_matrix(&q1, &rot1); quat_quat_to_rotquat(&q2); quat_rotquat_to_matrix(&q2, &rot2); mat_mul(&rot1, &rot2, &rot12); // ruoto la posizione vect_sub(&p_CurrentCamera->p_CurrentPosition, &p_CurrentCamera->p_CurrentTargetPosition, &cameradir); mat_mulvect(&rot12, &cameradir, &v); vect_add(&v, &p_CurrentCamera->p_CurrentTargetPosition, &p_CurrentCamera->p_CurrentPosition); // ruoto il target /*vect_sub(&p_CurrentCamera->p_CurrentTargetPosition, &p_CurrentCamera->p_CurrentPosition, &cameradir); mat_mulvect(&rot12, &cameradir, &v); vect_add(&v, &p_CurrentCamera->p_CurrentPosition, &p_CurrentCamera->p_CurrentTargetPosition);*/ mat_mulvect(&rot12, &xAxis, &vx); vect_auto_normalize(&vx); mat_mulvect(&rot12, &yAxis, &vy); vect_auto_normalize(&vy); mat_mulvect(&rot12, &zAxis, &vz); vect_auto_normalize(&vz); mat_insert_row(&p_CurrentCamera->p_CurrentRotationMatrix, 0, &vx); mat_insert_row(&p_CurrentCamera->p_CurrentRotationMatrix, 1, &vy); mat_insert_row(&p_CurrentCamera->p_CurrentRotationMatrix, 2, &vz); vect_neg(&p_CurrentCamera->p_CurrentPosition, &ptmp); mat_setmatrix_of_pretraslation(&pretrans, &ptmp); mat_mul(&p_CurrentCamera->p_CurrentRotationMatrix, &pretrans, &p_CurrentCamera->p_WorldMatrix); }
int32 CGeometricObject::m_CopyTEX1DOT3Vertex(int32 baseIndex, void *dest, CMesh *mesh) { VSGeometryUV1DOT3 *l_dest; int32 i; l_dest=(VSGeometryUV1DOT3 *)dest; for (i=0; i<mesh->p_NumDriverVertex; i++) { //vect_copy(&mesh->p_DriverVertex[i].point, &l_dest[i+baseIndex].point); vect_sub(&mesh->p_DriverVertex[i].point, &p_Pivot, &l_dest[i+baseIndex].point); vect_copy(&mesh->p_DriverVertex[i].normal, &l_dest[i+baseIndex].normal); l_dest[i+baseIndex].uv1.u=mesh->p_DriverVertex[i].uv1.u; l_dest[i+baseIndex].uv1.v=mesh->p_DriverVertex[i].uv1.v; vect_copy(&mesh->p_DriverVertex[i].bumpspace.T, &l_dest[i+baseIndex].T); } return (mesh->p_NumDriverVertex); }
int32 CGeometricObject::m_CopyTEX2Vertex(int32 baseIndex, void *dest, CMesh *mesh) { FVFGeometryUV2 *l_dest; int32 i; l_dest=(FVFGeometryUV2 *)dest; for (i=0; i<mesh->p_NumDriverVertex; i++) { //vect_copy(&mesh->p_DriverVertex[i].point, &l_dest[i+baseIndex].point); vect_sub(&mesh->p_DriverVertex[i].point, &p_Pivot, &l_dest[i+baseIndex].point); vect_copy(&mesh->p_DriverVertex[i].normal, &l_dest[i+baseIndex].normal); l_dest[i+baseIndex].uv1.u=mesh->p_DriverVertex[i].uv1.u; l_dest[i+baseIndex].uv1.v=mesh->p_DriverVertex[i].uv1.v; l_dest[i+baseIndex].uv2.u=mesh->p_DriverVertex[i].uv2.u; l_dest[i+baseIndex].uv2.v=mesh->p_DriverVertex[i].uv2.v; } return (mesh->p_NumDriverVertex); }
void AD_Object3D::precalc_radius(void) { int16 i; float4 aux=-1.0, mn; AD_Vect3D midp, paux; vect_set(&midp, 0, 0, 0); for (i=0; i<num_vertex3D; i++) { vect_add(&midp, &vertex3D[i].point, &midp); } vect_scale(&midp, 1.0f/(float)num_vertex3D, &midp); vect_copy(&midp, &mid_point); for (i=0; i<num_vertex3D; i++) { vect_sub(&vertex3D[i].point, &midp, &paux); mn=vect_lenght(&paux); if (mn>aux) aux=mn; } radius=aux; }
int32 CGeometricObject::m_CopyVertex(int32 baseIndex, void *dest, CMesh *mesh) { FVFOnlyGeometry *l_dest; int32 i; // if (p_ScaleTrack) // p_ScaleTrack->m_GetData(0, &p_CurrentScale); l_dest=(FVFOnlyGeometry *)dest; for (i=0; i<mesh->p_NumDriverVertex; i++) { //vect_copy(&mesh->p_DriverVertex[i].point, &l_dest[i+baseIndex].point); vect_sub(&mesh->p_DriverVertex[i].point, &p_Pivot, &l_dest[i+baseIndex].point); vect_copy(&mesh->p_DriverVertex[i].normal, &l_dest[i+baseIndex].normal); /* l_dest[i+baseIndex].normal.x*=p_CurrentScale.x; l_dest[i+baseIndex].normal.y*=p_CurrentScale.y; l_dest[i+baseIndex].normal.z*=p_CurrentScale.z; */ } return (mesh->p_NumDriverVertex); }
void CGeometricObject::m_DoOSMs(int32 witchLod) { int32 i, j, k; AD_Vect3D *point_tr, pp; DriverVertex *l_DriverVertex; HRESULT hr; uint32 start_lock, end_lock, vsize; BYTE *l_Data; k=p_Lods[witchLod].Mesh->p_NumDriverVertex; l_DriverVertex=p_Lods[witchLod].Mesh->p_DriverVertex; vsize=p_BaseMaterial->p_InputVertexFormat.vertexSize; start_lock=p_Lods[witchLod].VBStart*vsize; end_lock=p_Lods[witchLod].VBLong*vsize; locka: ; hr=p_VertexBuffer->Lock(start_lock, end_lock, (BYTE **)&l_Data, D3DLOCK_NOOVERWRITE );// 0); if (hr!=D3D_OK) goto locka; for (i=0; i<k; i++) { point_tr=(AD_Vect3D *)l_Data; //vect_copy(&l_DriverVertex[i].point, &pp); vect_sub(&l_DriverVertex[i].point, &p_Pivot, &pp); for (j=0; j<p_NumOSMs; j++) { p_OSMs[j]->m_Map(&pp, &pp); } vect_copy(&pp, point_tr); l_Data+=vsize; } hr=p_VertexBuffer->Unlock(); }
void CCamera::m_Update(float4 frame) { AD_Vect3D cameradir; const float4 EPS=0.2f; float4 focus, c, s; // estrazione dei dati tramite il keyframer, niente di piu' facile !!! if (p_PosTrack) p_PosTrack->m_GetData(frame, &p_CurrentPosition); if (p_TargetTrack) p_TargetTrack->m_GetData(frame, &p_CurrentTargetPosition); if (p_RollTrack) p_RollTrack->m_GetData(frame, &p_CurrentRoll); if (p_FovTrack) { p_FovTrack->m_GetData(frame, &p_CurrentFov); p_CurrentTanFov=(float4)tan(p_CurrentFov); // costruzione del frustrum (le normali puntano all'interno) s=fast_sinf(p_CurrentFov*0.5f); c=fast_cosf(p_CurrentFov*0.5f); vect_set(&p_LeftFrustrumNormal, c, 0, s); vect_set(&p_RightFrustrumNormal, -c, 0, s); vect_set(&p_UpFrustrumNormal, 0, c, s); vect_set(&p_DownFrustrumNormal, 0, -c, s); } vect_sub(&p_CurrentTargetPosition, &p_CurrentPosition, &cameradir); focus=vect_length(&cameradir); /* cr=currentroll; vect_set(&up, (float)sin(cr), (float)(-cos(cr)), 0.0); vect_cross(&cameradir, &up, &right); vect_normalize(&right); vect_cross(&right, &cameradir, &up); mat_insert_row(¤tmatrix_rot, 0, &right); mat_insert_row(¤tmatrix_rot, 1, &up); mat_insert_row(¤tmatrix_rot, 2, &cameradir); mat_mul(¤tmatrix_rot, &pretrans, ¤tmatrix); */ /* vect_normalize(&cameradir, &ptmp); if (fabs(ptmp.z) < EPS) { int32 fdfd=0; //if (cameradir.x >= 0) ax=0; az=0; ay=0; //else //ax=-1.5708f; } else*/ { p_CurrentAngX = (float4)-atan2 (cameradir.x, cameradir.z); p_CurrentAngY = (float4)asin (cameradir.y / focus); p_CurrentAngZ = -p_CurrentRoll; } m_BuildWorldMatrix(); }
/** * void mtx_lanczos_procedure(double *A, double *Tm, int n, int m) * * @brief Function that implements the first step of the eigenproblem solution * based on lanzos algorithm. This function generates a matrix Tm that contains * a set (<=) of eigenvalues that approximate those of matrix A. Finding the eigenvalues * in Tm is easier and serves as an optimization method for problems in which only a few * eigenpairs are required. * @param A, the matrix on which the procedure is applied. Needs to be square and Hermitian. * @param (out)a, elements of the diagonal of the matrix Tm * @param (out)b, elements off diagonal of the matrix Tm * @param n, the dimensions of the square matrix A * @param m, the number of iterations for the lanczos procedure (and the dimensions of the array returned) */ void mtx_lanczos_procedure(double *A, double *a, double *b, int n, int m) { int i,j,array_index_i; double* v_i = (double*)calloc(n, sizeof(double)); double* a_times_v_i = (double*)calloc(n, sizeof(double)); double* b_times_v_i_minus_one = (double*)calloc(n, sizeof(double)); double* v_i_minus_one = (double*)calloc(n, sizeof(double)); double* w_i = (double*)calloc(n, sizeof(double)); double* v1 = (double*)calloc(n, sizeof(double)); double* temp; /*get a n-long random vector with norm equal to 1*/ //vect_rand_unit(v1,n); for(i=0;i<n;i++){ v1[i] = 1/sqrt(n); } /*first iteration of the procedure*/ i = 1; array_index_i = i-1; /*computes w_i*/ /*w[i] <= A*v[i]*/ mtx_mult(A, v1, w_i, n, n, 1); /*computes a_i*/ /*a[i] <= w[i]*v[i]*/ a[array_index_i] = vect_dot_product(w_i, v1,n); /*update w_i*/ /*w[i] <= w[i]-a[i]*v[i]-b[i]*v[i-1]*/ /*note: b[1] = 0*/ memcpy(a_times_v_i,v1,n*sizeof(double)); vect_scalar_multiply(a_times_v_i,a[array_index_i],n); vect_sub(w_i, a_times_v_i, n); /*computes next b_i*/ /*b[i+1] = ||w[i]||*/ b[array_index_i+1] = vect_norm(w_i,n); /*copy v1 to v_i*/ memcpy(v_i,v1,n*sizeof(double)); /*save v[i] to be used asv[i-1]*/ temp = v_i_minus_one; v_i_minus_one = v_i; /*computes next v_i = w_i/b(i+1)*/ /*v[i+1] = w[i]/b[i+1]*/ v_i = w_i; vect_scalar_multiply(v_i, 1/b[array_index_i+1], n); /*reuse memory former v_i_minus_one space for w_i*/ w_i = temp; /*rest of the iterations of the procedure*/ for(i=2;i<=m-1;i++){ array_index_i = i-1; /*computes w_i*/ /*w[i] <= A*v[i]*/ mtx_mult(A, v_i, w_i, n, n, 1); /*computes a_i*/ /*a[i] <= w[i]*v[i]*/ a[array_index_i] = vect_dot_product(w_i, v_i, n); /*update w_i*/ /*prepare a[i]*v[i]*/ memcpy(a_times_v_i,v_i,n*sizeof(double)); vect_scalar_multiply(a_times_v_i,a[array_index_i],n); /*prepare b[i]*v[i-1]*/ memcpy(b_times_v_i_minus_one,v_i_minus_one,n*sizeof(double)); vect_scalar_multiply(b_times_v_i_minus_one,b[array_index_i],n); /*w[i] <= w[i]-a[i]*v[i]-b[i]*v[i-1]*/ vect_sub(w_i, a_times_v_i,n); vect_sub(w_i, b_times_v_i_minus_one,n); /*computes next b_i*/ /*b[i+1] = ||w[i]||*/ b[array_index_i+1] = vect_norm(w_i,n); /*save current v_i*/ temp = v_i_minus_one; v_i_minus_one = v_i; /*computes next v_i = w_i/b(i+1)*/ /*v[i+1] = w[i]/b[i+1]*/ v_i = w_i; vect_scalar_multiply(v_i, 1/b[array_index_i+1],n); /*reuse memory former v_i_minus_one space for w_i*/ w_i = temp; } /*compute last term a[m]*/ array_index_i = m-1; mtx_mult(A, v_i, w_i, n, n, 1); a[array_index_i] = vect_dot_product(w_i,v_i,n); /*translate data representation in the b matrix to match the CLAPACK standard*/ for(i=0;i<(n-1);i++){ b[i] = b[i+1]; } b[n-1] = 0; free(v1); free(v_i); free(a_times_v_i); free(b_times_v_i_minus_one); free(v_i_minus_one); free(w_i); }
void AD_Object3D::paint(float4 pos, AD_Camera *telecamera, AD_Omnilight *omnilight) { int16 w, wl; float4 invz, cosalpha, nlX, nlY, max_scale, dist; AD_Vect3D inv_accum_scale; AD_Vertex3D *v; AD_Matrix matrixrot_all, matrixtransform_all; AD_Matrix matrixtall_clip; AD_Vect3D light_vertex_vector, camerapos_inobject, vtmp, paux; // AD_Vertex2D *v2D=vertex2D; // AD_Vect3D *v3D=points_tr; build_objectmatrix(pos); if (type==BONE) { return; } else if (type==DUMMY) { // mat_mulvect(¤tmatrix, ¤tpos, &paux); mat_mulvect(&telecamera->currentmatrix, ¤tpos, &vtmp); if ( (flare!=(texture *)NULL) && (vtmp.z > telecamera->znear) && (vtmp.z < telecamera->zfar) ) { // proietto in 2D su schermo la luce (flare) invz=1.0f/vtmp.z; vtmp.x=telecamera->prospettivaX*(vtmp.x*invz) + (telecamera->screenX); vtmp.y=(telecamera->screenY) - telecamera->prospettivaY*(vtmp.y*invz); nlX=(flare_scale_x*latoX)/(vtmp.z - telecamera->znear + 1.0f); nlY=(flare_scale_y*latoY)/(vtmp.z - telecamera->znear + 1.0f); // mi calcolo i punti dei 2 triangoli vertex2D[0].xs=vtmp.x - (nlX/2.0f); if (vertex2D[0].xs > telecamera->screenX*2) return; vertex2D[0].ys=vtmp.y - (nlY/2.0f); if (vertex2D[0].ys > telecamera->screenY*2) return; vertex2D[0].dist=invz; vertex2D[0].z=vtmp.z/zfar; vertex2D[1].xs=vtmp.x + (nlX/2.0f); if (vertex2D[1].xs < 0) return; vertex2D[1].ys=vtmp.y - (nlY/2.0f); vertex2D[1].dist=invz; vertex2D[1].z=vtmp.z/zfar; vertex2D[2].xs=vtmp.x - (nlX/2.0f); vertex2D[2].ys=vtmp.y + (nlY/2.0f); if (vertex2D[2].ys < 0) return; vertex2D[2].dist=invz; vertex2D[2].z=vtmp.z/zfar; vertex2D[3].xs=vtmp.x + (nlX/2.0f); vertex2D[3].ys=vtmp.y + (nlY/2.0f); vertex2D[3].dist=invz; vertex2D[3].z=vtmp.z/zfar; tria[0].mid_z=vtmp.z; tria[1].mid_z=vtmp.z; (*list_to_paint_trasparent)=&tria[0]; list_to_paint_trasparent++; (*list_to_paint_trasparent)=&tria[1]; list_to_paint_trasparent++; } return; } if ((bones_matrix!=(AD_Matrix **)NULL) || (skin_modifier!=(Skin_Bone **)NULL)) { paint_bones(pos, telecamera, omnilight); return; } else if (num_OSMmods > 0) { paint_modifiers(pos, telecamera, omnilight); return; } max_scale=fabsf(accum_scale.x); if (fabsf(accum_scale.y) > max_scale) max_scale=fabsf(accum_scale.y); if (fabsf(accum_scale.z) > max_scale) max_scale=fabsf(accum_scale.z); inv_accum_scale.x=1.0f/accum_scale.x; inv_accum_scale.y=1.0f/accum_scale.y; inv_accum_scale.z=1.0f/accum_scale.z; // ***************************************************** // *** CASO DI OGGETTI NORMALE (mesh triangolari) *** // ***************************************************** // test di bounding clip 3d sull'oggetto intero mat_mulvect(¤tmatrix, &mid_point, &paux); mat_mulvect(&telecamera->currentmatrix, &paux, &vtmp); if (triaobj_isclipped_bounding(&vtmp, radius*max_scale, telecamera)) return; // si porta la camera nello spazio oggetto vect_sub(&telecamera->currentpos, ¤tpos, &vtmp); vtmp.x*=inv_accum_scale.x; vtmp.y*=inv_accum_scale.y; vtmp.z*=inv_accum_scale.z; mat_mulvectaffine(&inverse_rotmatrix, &vtmp, &camerapos_inobject); // si calcolano le matrici di trasformazione totali mat_mulaffine(&telecamera->currentmatrix_rot, ¤tmatrix_rot, &matrixrot_all); mat_mul(&telecamera->currentmatrix, ¤tmatrix, &matrixtall_clip); // calcolo della matrice di trasformazione con inclusi i // fattori di aspect ratio; mat_copy(&matrixtall_clip, &matrixtransform_all); for (w=0; w<4; w++) { matrixtransform_all.a[0][w]=matrixtransform_all.a[0][w]*telecamera->prospettivaX; matrixtransform_all.a[1][w]=matrixtransform_all.a[1][w]*telecamera->prospettivaY; } // si portano le luci nello spazio oggetto for (w=0; w<num_omni; w++) { vect_sub(&omnilight[w].currentpos, ¤tpos, &vtmp); vtmp.x*=inv_accum_scale.x; vtmp.y*=inv_accum_scale.y; vtmp.z*=inv_accum_scale.z; mat_mulvectaffine(&inverse_rotmatrix, &vtmp, &omnilight[w].currentpos_inobject); } TRIA_PIPELINE_ENVRGB TRIA_PIPELINE_RGB TRIA_PIPELINE_ENVMAP TRIA_PIPELINE_ELSE }
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); }
void AD_PatchObject::paint(float4 pos, AD_Camera *telecamera, AD_Omnilight *omnilight) { int w, ntria_generated, wl; float4 inv_accum_scale, invz; float4 envdimx, envdimy, cosalpha; AD_Matrix matrixrot_all, matrixtransform_all; AD_Matrix matrixtall_clip; AD_Vect3D camerapos_inobject, vtmp, light_vertex_vector; AD_Vertex3D *v; build_objectmatrix(pos); inv_accum_scale=1.0f/accum_scale; // si porta la camera nello spazio oggetto vect_sub(&telecamera->currentpos, ¤tpos, &vtmp); mat_mulvectaffine(&inverse_rotmatrix, &vtmp, &camerapos_inobject); camerapos_inobject.x*=inv_accum_scale; camerapos_inobject.y*=inv_accum_scale; camerapos_inobject.z*=inv_accum_scale; // si calcolano le matrici di trasformazione totali mat_mulaffine(&telecamera->currentmatrix_rot, ¤tmatrix_rot, &matrixrot_all); mat_mul(&telecamera->currentmatrix, ¤tmatrix, &matrixtall_clip); // calcolo della matrice di trasformazione con inclusi i // fattori di aspect ratio; pX e pY si trovano in render.cpp mat_copy(&matrixtall_clip, &matrixtransform_all); for (w=0; w<4; w++) { matrixtransform_all.a[0][w]=matrixtransform_all.a[0][w]*telecamera->prospettivaX; matrixtransform_all.a[1][w]=matrixtransform_all.a[1][w]*telecamera->prospettivaY; } // si portano le luci nello spazio della telecamera for (w=0; w<num_omni; w++) { vect_sub(&omnilight[w].currentpos, ¤tpos, &vtmp); mat_mulvectaffine(&inverse_rotmatrix, &vtmp, &omnilight[w].currentpos_inobject); omnilight[w].currentpos_inobject.x*=inv_accum_scale; omnilight[w].currentpos_inobject.y*=inv_accum_scale; omnilight[w].currentpos_inobject.z*=inv_accum_scale; } // trasformiamo tutti i vertici geometrici for (w=0; w<num_points; w++) { // ottengo le posizioni dei vertici dal keyframer if (vert_pos[w].numkey>0) vert_pos[w].get_data(pos, &verteces[w]); // li trasformo in camera space mat_mulvect(&matrixtransform_all, &verteces[w], &verteces_tr[w]); } // trasformiamo tutti i vettori for (w=0; w<num_vectors; w++) { // ottengo le posizioni dei vettori dal keyframer if (vect_pos[w].numkey>0) vect_pos[w].get_data(pos, &vectors[w]); // li trasformo in camera space mat_mulvect(&matrixtransform_all, &vectors[w], &vectors_tr[w]); } ntria_generated=Tassellate(); TRIA_PIPELINE_ENVRGB TRIA_PIPELINE_RGB TRIA_PIPELINE_ENVMAP TRIA_PIPELINE_ELSE }
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; }
float calc_shade( primitive *light, vector *isect_pt, vector *lv, vector *ln, primitive *scene, int shadows ) { float shade = 1.0f; float l_dist; int i; ray r; vector o, dir; intersection *isect; primitive *iter; if( light->is_light == AREA_LIGHT && shadows > 1 && light->grid != NULL ) { for( i = 0; i < shadows; i++ ) { dir.x = light->grid[(i&63)*3] + ((float)rand()/RAND_MAX)*light->dx; dir.y = light->grid[(i&63)*3+1] + ((float)rand()/RAND_MAX)*light->dy; dir.z = light->grid[(i&63)*3+2] + ((float)rand()/RAND_MAX)*light->dz; vect_sub( &dir, isect_pt ); l_dist = vect_length( &dir ); vect_multf( &dir, 1.0f / l_dist ); vect_copy( &o, &dir ); vect_multf( &o, EPSILON ); vect_add( &o, isect_pt ); r.origin = &o; r.dir = &dir; for( iter = scene; iter != NULL; iter = iter->next ) { isect = iter->intersect( iter, &r ); if( isect != NULL && !iter->is_light && isect->dist < l_dist ) { shade -= 1.0f / shadows; free( isect ); break; } free( isect ); } } } else { /* setup the ray */ vect_copy( &o, ln ); vect_multf( &o, EPSILON ); vect_add( &o, isect_pt ); r.origin = &o; r.dir = ln; l_dist = vect_length( lv ); for( iter = scene; iter != NULL; iter = iter->next ) { isect = iter->intersect( iter, &r ); if( isect != NULL && !iter->is_light && isect->dist < l_dist ) { shade = 0.0f; free( isect ); break; } free( isect ); } } return shade; }
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_PatchObject::paint(float4 pos, AD_Camera *telecamera, AD_Omnilight *omnilight) { int w, ntria_generated, wl; float4 invz, cosalpha, dist, inv_prospX, inv_prospY; float4 envdimx, envdimy; AD_Matrix matrixrot_all, matrixtransform_all; AD_Matrix matrixtall_clip; AD_Vect3D vtmp, light_vertex_vector, inv_accum_scale, vaux; AD_Vertex3D *v; AD_Tria3D **right_list; build_objectmatrix(pos); inv_accum_scale.x=1.0f/accum_scale.x; inv_accum_scale.y=1.0f/accum_scale.y; inv_accum_scale.z=1.0f/accum_scale.z; mat_mulvect(&telecamera->currentmatrix, ¤tpos, ¤tpos_incamera); // si calcolano le matrici di trasformazione totali mat_mulaffine(&telecamera->currentmatrix_rot, ¤tmatrix_rot, &matrixrot_all); mat_mul(&telecamera->currentmatrix, ¤tmatrix, &matrixtall_clip); // calcolo della matrice di trasformazione con inclusi i // fattori di aspect ratio; pX e pY si trovano in render.cpp mat_copy(&matrixtall_clip, &matrixtransform_all); for (w=0; w<4; w++) { matrixtransform_all.a[0][w]=matrixtransform_all.a[0][w]*telecamera->prospettivaX; matrixtransform_all.a[1][w]=matrixtransform_all.a[1][w]*telecamera->prospettivaY; } inv_prospX=1.0f/telecamera->prospettivaX; inv_prospY=1.0f/telecamera->prospettivaY; // si portano le luci nello spazio oggetto (ma sempre nello // spazio camera) for (w=0; w<num_omni; w++) mat_mulvect(&telecamera->currentmatrix, &omnilight[w].currentpos, &omnilight[w].currentpos_inobject); // trasformiamo tutti i vertici geometrici for (w=0; w<num_points; w++) { // ottengo le posizioni dei vertici dal keyframer if (vert_pos[w].numkey>0) vert_pos[w].get_data(pos, &verteces[w]); // li trasformo in camera space mat_mulvect(&matrixtransform_all, &verteces[w], &verteces_tr[w]); // calcolo i rispettivi per il calcolo delle normali // in camera space mat_mulvect(&matrixtall_clip, &verteces[w], &verteces_trn[w]); vect_sub(&verteces_trn[w], ¤tpos_incamera, &verteces_trn[w]); } // trasformiamo tutti i vettori for (w=0; w<num_vectors; w++) { // ottengo le posizioni dei vettori dal keyframer if (vect_pos[w].numkey>0) vect_pos[w].get_data(pos, &vectors[w]); // li trasformo in camera space mat_mulvect(&matrixtransform_all, &vectors[w], &vectors_tr[w]); // calcolo i rispettivi per il calcolo delle normali // in camera space mat_mulvect(&matrixtall_clip, &vectors[w], &vectors_trn[w]); vect_sub(&vectors_trn[w], ¤tpos_incamera, &vectors_trn[w]); } ntria_generated=Tassellate(); if (matbase->flags & IS_TRASPARENT) right_list=list_to_paint_trasparent; else right_list=(AD_Tria3D **)matbase->my_tria_list; if (swap_normals==TRUE) { TRIA_PIPELINE_ENVRGB_SWAP TRIA_PIPELINE_RGB_SWAP } else { TRIA_PIPELINE_ENVRGB TRIA_PIPELINE_RGB } TRIA_PIPELINE_ENVMAP TRIA_PIPELINE_ELSE if (matbase->flags & IS_TRASPARENT) list_to_paint_trasparent=right_list; else matbase->my_tria_list=(void **)right_list; }
void test_basic_vector_op(void) { /******************************/ /* Test the vector operations */ /******************************/ /*create two vectors and show them*/ int vector_length = 5; double vector_a[5] = {2.5, -10.9, 15.8, 12.2, 7.9}; double vector_b[5] = {2.5, 0.2, 21.33, 70.1, -0.2}; double vector_c[5]; double result = 0.0; /*seed the random generator*/ srand(time(NULL)); printf("The two vectors a and b\n"); show_vector(vector_a, vector_length); show_vector(vector_b, vector_length); /*vector addition*/ printf("c = a + b\n"); /*copy a*/ memcpy(vector_c, vector_a, vector_length*sizeof(double)); /*compute*/ vect_add(vector_c, vector_b, vector_length); /*show expected and obtained results*/ printf("Expected: 5.0000 -10.7000 37.1300 82.3000 7.7000\n"); printf("Result: "); show_vector(vector_c, vector_length); /*vector subtraction*/ printf("c = a - b\n"); /*copy a*/ memcpy(vector_c, vector_a, vector_length*sizeof(double)); /*compute*/ vect_sub(vector_c, vector_b, vector_length); /*show expected and obtained results*/ printf("Expected: 0.0000 -11.1000 -5.5300 -57.9000 8.1000\n"); printf("Result: "); show_vector(vector_c, vector_length); /*vector scalar multiplication*/ printf("c = a * 5\n"); /*copy a*/ memcpy(vector_c, vector_a, vector_length*sizeof(double)); /*compute*/ vect_scalar_multiply(vector_c, 5, vector_length); /*show expected and obtained results*/ printf("Expected: 12.5000 -54.5000 79.0000 61.0000 39.5000\n"); printf("Result: "); show_vector(vector_c, vector_length); /*vector dot product*/ printf("c = a .* b\n"); /*compute*/ result = vect_dot_product(vector_a, vector_b, vector_length); /*show expected and obtained results*/ printf("Expected: 1194.72\n"); printf("Result: %2.2f\n",result); /*vector cross product*/ /*To be completed*/ /*vector norm*/ printf("c = |a|\n"); /*compute*/ result = vect_norm(vector_a, vector_length); /*show expected and obtained results*/ printf("Expected: 24.2064\n"); printf("Result: %2.4f\n",result); /*vector rand unit*/ printf("c is a random vector\n"); printf("|c| == 1\n"); /*compute*/ vect_rand_unit(vector_c, vector_length); /*show expected and obtained results*/ printf("The vector: "); show_vector(vector_c, vector_length); result = vect_norm(vector_c, vector_length); printf("Expected norm: 1.0000\n"); printf("Obtained norm: %2.4f\n",result); }
void AD_MeltModifier::Map(AD_Vect3D *pos, AD_Vect3D *out) { float x, y, z; float xw, yw, zw; float vdist, mfac, dx, dy; float defsinex, coldef, realmax; AD_Vect3D p; vect_sub(pos, ¢er, &p); // vect_copy(pos, &p); x = p.x; y = p.y; z = p.z; xw= x-cx; yw= y-cy; zw= z-cz; // xw= x-center.x; yw= y-center.y; zw= z-center.z; if(xw==0.0 && yw==0.0 && zw==0.0) xw=yw=zw=1.0f; // Kill singularity for XW,YW,ZW if(x==0.0 && y==0.0 && z==0.0) x=y=z=1.0f; // Kill singularity for XYZ // Find distance from centre vdist=sqrtf(xw*xw+yw*yw+zw*zw); mfac=size/vdist; if(axis==0){ dx = xw+sign(xw)*((float) (fabs(xw*mfac))*(amount*spread)); dy = yw+sign(yw)*((float) (fabs(yw*mfac))*(amount*spread)); x=(dx+cx); y=(dy+cy); } if(axis==1){ dx = xw+sign(xw)*((float) (fabs(xw*mfac))*(amount*spread)); dy = zw+sign(zw)*((float) (fabs(zw*mfac))*(amount*spread)); x=(dx+cx); z=(dy+cz); } if(axis==2){ dx = zw+sign(zw)*((float) (fabs(zw*mfac))*(amount*spread)); dy = yw+sign(yw)*((float) (fabs(yw*mfac))*(amount*spread)); z=(dx+cz); y=(dy+cy); } if(axis==0) if(p.z<(bbz1)) goto skipmelt; if(axis==1) if(p.y<(bby1)) goto skipmelt; if(axis==2) if(p.x<(bbx1)) goto skipmelt; if(axis==0) realmax = (float)hypot( (bbx2-cx),(bby2-cy) ); if(axis==1) realmax = (float)hypot( (bbx2-cx),(bbz2-cz) ); if(axis==2) realmax = (float)hypot( (bbz2-cz),(bby2-cy) ); if(axis==0){ defsinex = (float)hypot( (x-cx),(y-cy) ); coldef = realmax - (float)hypot( (x-cx),(y-cy) ); } if(axis==1){ defsinex = (float)hypot( (x-cx),(z-cz) ); coldef = realmax - (float)hypot( (x-cx),(z-cz) ); } if(axis==2){ defsinex = (float)hypot( (z-cz),(y-cy) ); coldef = realmax - (float)hypot( (z-cz),(y-cy) ); } if (coldef<0.0f) coldef=0.0f; defsinex+=(coldef/solidity); // Melt me! if(axis==0){ if(!negaxis) { z-=(defsinex*amount); if(z<=bbz1) z=bbz1; // if(z<=(bbox.pmin.z+zbr)) z=(bbox.pmin.z+zbr); } else { z+=(defsinex*amount); if(z>=bbz2) z=bbz2; // if(z>=(bbox.pmax.z+zbr)) z=(bbox.pmax.z+zbr); } } if(axis==1){ if(!negaxis) { y-=(defsinex*amount); if(y<=bby1) y=bby1; // if(y<=(bbox.pmin.y+zbr)) y=(bbox.pmin.y+zbr); } else { y+=(defsinex*amount); if(y>=bby2) y=bby2; // if(y>=(bbox.pmax.y+zbr)) y=(bbox.pmax.y+zbr); } } if(axis==2){ if(!negaxis) { x-=(defsinex*amount); if(x<=bbx1) x=bbx1; // if(x<=(bbox.pmin.x+zbr)) x=(bbox.pmin.x+zbr); } else { x+=(defsinex*amount); if(x>=bbx2) x=bbx2; // if(x>=(bbox.pmax.x+zbr)) x=(bbox.pmax.x+zbr); } } skipmelt: out->x = x+center.x; out->y = y+center.y; out->z = z+center.z; }