void mat_make_look_at(struct matrix *m, const struct vector *o, const struct vector *p) { struct vector n, u, v, t; struct matrix a; vec_sub(&n, p, o); vec_normalize(&n); /* v' = (0, 1, 0) */ vec_set(&v, 0.f, 1.f, 0.f); /* v = v' - (v'*n)*n */ vec_scalar_mul_copy(&t, &n, vec_dot_product(&v, &n)); vec_sub_from(&v, &t); vec_normalize(&v); vec_cross_product(&u, &v, &n); vec_normalize(&u); m->m11 = u.x; m->m12 = u.y; m->m13 = u.z; m->m14 = 0.f; m->m21 = v.x; m->m22 = v.y; m->m23 = v.z; m->m24 = 0.f; m->m31 = n.x; m->m32 = n.y; m->m33 = n.z; m->m34 = 0.f; mat_make_translation(&a, -o->x, -o->y, -o->z); mat_mul(m, &a); }
/** * Calculate vertex normal vector */ int MeshData::calc_vex_norm(int vex_id, double *v) { int ele_n, *ele; double v1[3], v2[3], v3[3]; int i1, i2, i3, ei; int i, j; double l; // clear v for(i=0; i<3; i++) v[i] = 0.0; // get elements which contain given vertex ele_n = 40; ele = new int[ele_n]; get_ele_by_vex(vex_id, &ele_n, ele); // for each element for(i=0; i<ele_n; i++) { ei = ele[i]; i1 = ele_arr[ei*3+0]; i2 = ele_arr[ei*3+1]; i3 = ele_arr[ei*3+2]; // v2 - v1 v1[0] = vex_arr[i2*3+0] - vex_arr[i1*3+0]; v1[1] = vex_arr[i2*3+1] - vex_arr[i1*3+1]; v1[2] = vex_arr[i2*3+2] - vex_arr[i1*3+2]; // v3 - v1 v2[0] = vex_arr[i3*3+0] - vex_arr[i1*3+0]; v2[1] = vex_arr[i3*3+1] - vex_arr[i1*3+1]; v2[2] = vex_arr[i3*3+2] - vex_arr[i1*3+2]; // (v2-v1)x(v3-v1) vec_cross_product(v1, v2, v3); v[0] += v3[0]; v[1] += v3[1]; v[2] += v3[2]; } // average normal vector v[0] /= ele_n; v[1] /= ele_n; v[2] /= ele_n; // normalize length l = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] /= l; v[1] /= l; v[2] /= l; delete ele; return 0; }
static void createObjectCoordSystem(CoordinateSystem<float> *pXYZ,const float Z[3]) { static const double cc=1./64.; float X[3],Y[3]; if (Z[0]==0 && Z[1]==0 && Z[2]>=0) { X[0]=1; X[1]=0; X[2]=0; Y[0]=0; Y[1]=1; Y[2]=0; } else if (Z[0]>-cc && Z[0]<cc && Z[1]>-cc && Z[1]<cc) { /*X= [0 1 0] x Z*/ X[0]=Z[2]; X[1]=0; X[2]=-Z[0]; } else { /*X= [0 0 1] x Z*/ X[0]=-Z[1]; X[1]=Z[0]; X[2]=0; } vec_cross_product(Y,Z,X); pXYZ->setGlobal(); pXYZ->setAxis(X,Y,Z); }
int MeshData::calc_ele_norm(void) { int i; int i1, i2, i3; double v1[3], v2[3], v3[3]; double vl; if( ele_norm == NULL ) { ele_norm = new double[ele_num*3]; } // for each element for(i=0; i<ele_num; i++) { i1 = ele_arr[i*3+0]; i2 = ele_arr[i*3+1]; i3 = ele_arr[i*3+2]; // v2 - v1 v1[0] = vex_arr[i2*3+0] - vex_arr[i1*3+0]; v1[1] = vex_arr[i2*3+1] - vex_arr[i1*3+1]; v1[2] = vex_arr[i2*3+2] - vex_arr[i1*3+2]; // v3 - v1 v2[0] = vex_arr[i3*3+0] - vex_arr[i1*3+0]; v2[1] = vex_arr[i3*3+1] - vex_arr[i1*3+1]; v2[2] = vex_arr[i3*3+2] - vex_arr[i1*3+2]; // (v2-v1)x(v3-v1) vec_cross_product(v1, v2, v3); vl = sqrt(v3[0]*v3[0] + v3[1]*v3[1] + v3[2]*v3[2]); ele_norm[i*3+0] = v3[0] / vl; ele_norm[i*3+1] = v3[1] / vl; ele_norm[i*3+2] = v3[2] / vl; } return 0; }
void mesh_init_poly_normals(struct mesh *mesh) { struct polygon *p, *end; struct vector u, v; int *vtx_index; struct vertex *vtx; vtx = mesh->vtx; end = &mesh->poly[mesh->npoly]; for (p = mesh->poly; p != end; p++) { assert(p->nvtx >= 3); vtx_index = p->vtx_index; vec_sub(&u, &vtx[vtx_index[1]].pos, &vtx[vtx_index[0]].pos); vec_sub(&v, &vtx[vtx_index[2]].pos, &vtx[vtx_index[0]].pos); vec_cross_product(&p->normal, &u, &v); vec_normalize(&p->normal); } }
void BSplineSurf::recalcCoords(float ds,float dt) { float s,t; float out[3]; int ns,nt; myVector<float> sv; myVector<float> tv; for (s=U[0]; s<U[1]; s+=ds) { sv.append(s); } sv.append(U[1]); for (t=V[0]; t<V[1]; t+=dt) { tv.append(t); } tv.append(V[1]); total_coords=sv.length()*tv.length(); coords=(float(*)[3])malloc(total_coords*sizeof(float[3])); total_coords=0; for (ns=0; ns<sv.length(); ns++) { s=sv.at(ns); for (nt=0; nt<tv.length(); nt++) { t=tv.at(nt); getParamPoint(s,t,coords[total_coords]); total_coords++; } } myVector<int> N; int striplen; for (ns=0; ns<sv.length()-1; ns++) { N.append(0); striplen=N.length()-1; for (nt=0; nt<tv.length(); nt++) { N.append(nt+tv.length()*ns); N.append(nt+ tv.length()*(ns+1)); } N.at(striplen)=tv.length()*2; } N.append(0); free(strip); strip=(int*)malloc(N.length()*sizeof(int)); memcpy(strip,N.getData(),N.length()*sizeof(int)); free(normals); normals=(float(*)[3])calloc(total_coords,sizeof(float[3])); int *ar,totta,k; ar=strip; while (ar[0]) { totta=ar[0]; ar++; for (k=2; k<totta; k++) { float g1[3],g2[3],g3[3]; vec_diff(g1,coords[ ar[k-2] ],coords[ ar[k-1] ]); vec_diff(g2,coords[ ar[k-1] ],coords[ ar[k] ]); vec_cross_product(g3,g1,g2); vec_normalize(g3); if (k&1) { vec_flip(g3,g3); } vec_sum(normals[ ar[k] ],normals[ ar[k] ],g3); if (k==2) { vec_sum(normals[ ar[0] ],normals[ ar[0] ],g3); vec_sum(normals[ ar[1] ],normals[ ar[1] ],g3); } } ar+=totta; } for (k=0; k<total_coords; k++) { vec_normalize(normals[k]); } }