void Math::QuatRotation(Vec3 & vOut, const Quat & q, const Vec3 & v) { //NVIDIA SDK implementation Vec3 uv, uuv; Vec3 qv(q.x, q.y, q.z); VecCross(uv, qv, v); VecCross(uuv, qv, uv); uv *= (2.0f * q.w); uuv *= 2.0f; vOut = v + uv + uuv; }
/************* * DESCRIPTION: Modify given normal by "bumping" it. * INPUT: norm normal * dpdu delta u * dpdv delta v * fu * fv * OUTPUT: none *************/ void MakeBump(VECTOR *norm, VECTOR *dpdu, VECTOR *dpdv, float fu, float fv) { VECTOR tmp1, tmp2; VecCross(norm, dpdv, &tmp1); tmp1.x *= fu; tmp1.y *= fu; tmp1.z *= fu; VecCross(norm, dpdu, &tmp2); tmp2.x *= fv; tmp2.y *= fv; tmp2.z *= fv; VecSub(&tmp1, &tmp2, &tmp1); VecAdd(norm, &tmp1, norm); VecNormalizeNoRet(norm); }
//末端力转化到关节力矩,输入末端轨迹R1,R2,l1,l2,输出ts,te void TransformF(const float* R1, const float* R2, const float* l1,const float* l2, const float *F, float *ts, float *te) { float P1[3]; float P2[3]; float P[3]; MatMultVec(R1, l1, P1); MatMultVec(R2, l2, P2); VecAdd(P1,P2,P); VecCross(F,P,ts); float tmp[3]; VecCross(F,P2,tmp); te[0] = -VecDot(tmp,R1); te[1] = 0; te[2] = 0; }
// pyramid number CalculateVolumePyramid(const vector3& a, const vector3& b, const vector3& c, const vector3& d, const vector3& e) { number result = 0; // UG_LOG("a: " << a << " b: " << b << " c: " << c << " d: " << d << " e: " << e << endl) //fixme check for a set of volumes that this condition is met! // check a,b,c,d are in same plane // fixme why does this check only work in x,y plane?! // vector3 r, n, x; // VecCross(n, a, b); // VecNormalize(n, n); // // VecSubtract(r, a, b); // VecSubtract(x, c, r); // number dot = VecDot(x, n); // // UG_LOG("dot pyra: " << dot<< endl) // UG_ASSERT(dot < SMALL, // "pyramid volume calculation needs all base are points in one plane!"); vector3 center, h_, h, c1, c2, da, ba, cb, cd; VecSubtract(da, d, a); VecSubtract(ba, b, a); VecSubtract(cb, c, b); VecSubtract(cd, c, d); VecCross(c1, da, ba); VecCross(c2, cb, cd); number A = 0.5 * VecLength(c1) + 0.5 * VecLength(c2); // UG_LOG("A pyra: " << A <<endl) vector3 arr[] = { a, b, c, d }; CalculateCenter(center, arr, 4); number height = DistancePointToPlane(e, center, c1); // VecSubtract(h_, e, center); // VecAdd(h, h_, center); // VecSubtract(h, e, center); // VecLength(h); // UG_LOG("pyra h: " << height << endl) result = 1.0 / 3.0 * A * height; // UG_LOG("pyra vol: " << result << endl) return result; }
D3DMATRIX* MatrixLookAtLH( D3DMATRIX *pOut, const D3DVECTOR *pEye, const D3DVECTOR *pAt, const D3DVECTOR *pUp ) { D3DVECTOR vecX, vecY, vecZ; // Compute direction of gaze. (+Z) VecSubtract(&vecZ, pAt, pEye); VecNormalize(&vecZ, &vecZ); // Compute orthogonal axes from cross product of gaze and pUp vector. VecCross(&vecX, pUp, &vecZ); VecNormalize(&vecX, &vecX); VecCross(&vecY, &vecZ, &vecX); // Set rotation and translate by pEye pOut->_11 = vecX.x; pOut->_21 = vecX.y; pOut->_31 = vecX.z; pOut->_41 = -VecDot(&vecX, pEye); pOut->_12 = vecY.x; pOut->_22 = vecY.y; pOut->_32 = vecY.z; pOut->_42 = -VecDot(&vecY, pEye); pOut->_13 = vecZ.x; pOut->_23 = vecZ.y; pOut->_33 = vecZ.z; pOut->_43 = -VecDot(&vecZ, pEye); pOut->_14 = 0.0f; pOut->_24 = 0.0f; pOut->_34 = 0.0f; pOut->_44 = 1.0f; return pOut; }
void make_view_matrix(Vec p1, Vec p2, Matrix m) { Flt d, len, l1; Vec up, out, left; Vec upv={0,1,0}; //Log( "make_view_matrix()...\n"); //Line between p1 and p2 form a LOS Line-of-sight. //A rotation matrix is built to transform objects to this LOS. // //Diana Gruber //http://www.makegames.com/3Drotation/ // m[0][0]=1.0; m[0][1]=0.0; m[0][2] =0.0; m[1][0]=0.0; m[1][1]=1.0; m[1][2] =0.0; m[2][0]=0.0; m[2][1]=0.0; m[2][2] =1.0; VecSub(p2, p1, out); // len = out[0]*out[0] + out[1]*out[1] + out[2]*out[2]; if (len == 0.0) { MakeVector(0.0,0.0,1.0,out); } else { l1 = 1.0 / sqrt(len); out[0] *= l1; out[1] *= l1; out[2] *= l1; } // m[2][0] = out[0]; m[2][1] = out[1]; m[2][2] = out[2]; // d = out[0] * upv[0] + out[1] * upv[1] + out[2] * upv[2]; up[0] = upv[0] - d * out[0]; up[1] = upv[1] - d * out[1]; up[2] = upv[2] - d * out[2]; len = up[0]*up[0] + up[1]*up[1] + up[2]*up[2]; if (len == 0.0) { MakeVector(0, 0, 1, up); } else { l1 = 1.0 / sqrt(len); up[0] *= l1; up[1] *= l1; up[2] *= l1; } m[1][0] = up[0]; m[1][1] = up[1]; m[1][2] = up[2]; //make left vector. VecCross(up, out, left); m[0][0] = left[0]; m[0][1] = left[1]; m[0][2] = left[2]; }
Mapping * LinearMappingCreate( Vector *center, Vector *vaxis, Vector *uaxis) { Mapping *res; RSMatrix m; Vector n; res = (Mapping *)Malloc(sizeof(Mapping)); res->flags = OBJSPACE; res->method= LinearMapping; if (center) res->center = *center; else res->center.x = res->center.y = res->center.z = 0.; if (uaxis && vaxis) { VecCross(uaxis, vaxis, &n); /* this is wrong, since uaxis and vaxis * give U and V in world space, and we * need the inverse. */ ArbitraryMatrix( uaxis->x, uaxis->y, uaxis->z, vaxis->x, vaxis->y, vaxis->z, n.x, n.y, n.z, res->center.x, res->center.y, res->center.z, &m); MatrixInvert(&m, &res->m); res->uaxis = *uaxis; res->vaxis = *vaxis; VecNormalize(&res->uaxis); VecNormalize(&res->vaxis); } else { VecScale(-1., res->center, &n); TranslationMatrix(n.x, n.y, n.z, &res->m); res->uaxis.x = res->vaxis.y = 1.; res->uaxis.y = res->uaxis.z = res->vaxis.x = res->vaxis.z = 0.; } return res; }
int WoodBase::Draw(){ int i; int edge[][4]={ {0,1,2,3}, {0,4,5,1}, {1,5,6,2}, {2,6,7,3}, {3,7,4,0}, {7,6,5,4}, }; GLfloat vtex[][2]={ {0.0,0.0}, {1.0,0.0}, {1.0,1.0}, {0.0,1.0} }; glPushMatrix(); glEnable(GL_TEXTURE_2D); glBindTexture( GL_TEXTURE_2D, myTex->texture ); glBegin(GL_QUADS); for(i=0;i<6;i++){ Vec3d t=VecCross(vertex[edge[i][1]]-vertex[edge[i][0]],vertex[edge[i][3]]-vertex[edge[i][0]]); t/=t.length(); glNormal3d(t.x,t.y,t.z); glColor4d(color[i].r,color[i].g,color[i].b,color[i].a); GLfloat material[] = {(float)color[i].r,(float)color[i].g,(float)color[i].b,(float)color[i].a}; glMaterialfv(GL_FRONT_AND_BACK , GL_AMBIENT_AND_DIFFUSE , material); for(int j=0;j<4;j++){ glTexCoord2f(vtex[j][0],vtex[j][1]); glVertex3d(vertex[edge[i][j]].x,vertex[edge[i][j]].y,vertex[edge[i][j]].z); } } glEnd(); glDisable(GL_TEXTURE_2D); glPopMatrix(); return 0; }
VOID PolyRead(OBJECT *po, FILE *pf) { INT i, j; /* Indices. */ INT instat; /* Read status. */ INT *vindex; INT totalverts; /* Total # of vertices in poly mesh. */ CHAR normstr[5]; /* Face/vertex normal flag string. */ BOOL pnormals; /* Face normals present? */ VEC3 pnorm; /* Polygon normal accumulator. */ VEC3 *vlist, *vptr, *vp; /* Ptr to vertex list. */ VEC3 *vptmp, *vptmp2; /* Ptr to vertex list. */ VEC3 tmppnt, tmppnt2, cross; POLY *pp; /* Ptr to polygon data. */ ELEMENT *pe; /* Ptr to polygon element. */ pe = po->pelem; /* Allocate space for object data. */ instat = fscanf(pf, "%ld", &totalverts); if (instat != 1) { printf("Error in PolyRead: totalverts.\n"); exit(-1); } pp = GlobalMalloc(sizeof(POLY)*po->numelements, "poly.c"); vlist = GlobalMalloc(sizeof(VEC3)*(totalverts + 1), "poly.c"); vptr = vlist; /* Are polygon face normals supplied? */ instat = fscanf(pf, "%s\n", normstr); if (instat != 1) { printf("Error in PolyRead: face normal indicator.\n"); exit(-1); } pnormals = (normstr[2] == 'y' ? TRUE : FALSE); /* Read vertex list. */ for (i = 0; i < totalverts; i++) { instat = fscanf(pf, "%lf %lf %lf", &(*vptr)[0], &(*vptr)[1], &(*vptr)[2]); if (instat != 3) { printf("Error in PolyRead: vertex %ld.\n", i); exit(-1); } vptr++; } (*vptr)[0] = HUGE_REAL; (*vptr)[1] = HUGE_REAL; (*vptr)[2] = HUGE_REAL; /* Read polygon list. */ for (i = 0; i < po->numelements; i++) { instat = fscanf(pf, "%ld", &(pp->nverts)); if (instat != 1) { printf("Error in PolyRead: vertex count.\n"); exit(-1); } if (pp->nverts > MAX_VERTS) { printf("Polygon vertex count, %ld, exceeds maximum.\n", pp->nverts); exit(-1); } if (pnormals) { instat = fscanf(pf, " %lf %lf %lf", &(pp->norm[0]), &(pp->norm[1]), &(pp->norm[2])); if (instat != 3) { printf("Error in PolyRead: face normal %ld.\n", i); exit(-1); } } pp->vptr = vlist; pp->vindex = GlobalMalloc(sizeof(INT)*pp->nverts, "poly.c"); vindex = pp->vindex; for (j = 0; j < pp->nverts; j++) { instat = fscanf(pf, "%ld", vindex++); if (instat != 1) { printf("Error in PolyRead: vertex index %ld.\n", i); exit(-1); } } /* If not supplied, calculate plane normal. */ vindex = pp->vindex; vptr = vlist; if (!pnormals) { vp = vptr + (*vindex); VecZero(pnorm); for (j = 0; j < pp->nverts - 2; j++) { vptmp = vptr + (*(vindex + 1)); vptmp2 = vptr + (*(vindex + 2)); VecSub(tmppnt, (*vptmp), (*vp)); VecSub(tmppnt2, (*vptmp2), (*vptmp)); VecCross(cross, tmppnt, tmppnt2); VecAdd(pnorm, pnorm, cross); vp = vptmp; vindex += 1; } VecSub(tmppnt, (*vptmp2), (*vp)); vindex = pp->vindex; vp = vptr + (*vindex); VecSub(tmppnt2, (*vp), (*vptmp2)); VecCross(cross, tmppnt, tmppnt2); VecAdd(pnorm, pnorm, cross); vp = vptr + (*vindex); VecSub(tmppnt, (*vp), (*vptmp2)); vptmp = vptr + (*(vindex + 1)); VecSub(tmppnt2, (*vptmp), (*vp)); VecCross(cross, tmppnt, tmppnt2); VecAdd(pnorm, pnorm, cross); VecScale(pp->norm, 1.0/VecLen(pnorm), pnorm); } /* Calculate plane equation d. */ vp = pp->vptr + *(pp->vindex); pp->d = -(pp->norm[0]*(*vp)[0] + pp->norm[1]*(*vp)[1] + pp->norm[2]*(*vp)[2]); pe->data = (CHAR *)pp; pe->parent = po; PolyElementBoundBox(pe, pp); pp++; pe++; } }
//求雅克比矩阵。 void SolveJacob(const float* MechPara, const float* R1, const float* R2, float* jacob_s, float* jacob_e) { float A1[3],A2[3],A3[3],A4[3],B1[3],B2[3],B3[3],B4[3],B5[3],B6[3],C1[3],C2[3]; const float l1 = MechPara[0]; //const float l2 = MechPara[1]; const float d1 = MechPara[2]; const float r1 = MechPara[3]; const float d2 = MechPara[4]; const float r2 = MechPara[5]; const float d3 = MechPara[6]; const float r3 = MechPara[7]; const float alphaa1 = MechPara[8]; const float psta2 = MechPara[9]; const float psta3 = MechPara[10]; const float alphaa4 = MechPara[11]; const float alphab1 = MechPara[12]; const float alphab2 = MechPara[13]; const float alphab3 = MechPara[14]; const float alphab4 = MechPara[15]; const float alphab5 = MechPara[16]; const float alphab6 = MechPara[17]; const float alphac1 = MechPara[18]; const float alphac2 = MechPara[19]; SolveTmpVec(r1,alphaa1,d1,A1); SolveTmpVec(r1,alphaa4,d1,A4); SolveTmpVec(r2,alphab1,d2,B1); SolveTmpVec(r2,alphab2,d2,B2); SolveTmpVec(r2,alphab3,d2,B3); SolveTmpVec(r2,alphab4,d2,B4); SolveTmpVec(r2,alphab5,d2,B5); SolveTmpVec(r2,alphab6,d2,B6); SolveTmpVec(r3,alphac1,d3,C1); SolveTmpVec(r3,alphac2,d3-84,C2); A2[0] = psta2; A2[1] = r1; A2[2] = d1; A3[0] = psta3; A3[1] = -r1; A3[2] = d1; float A[3] = {0,0,0}; float B[3]; float tmpl[3]; tmpl[0] = tmpl[1] = 0; tmpl[2] = l1; MatMultVec(R1,tmpl,B); float B1_r[3], B2_r[3], B3_r[3], B4_r[3], B5_r[3], B6_r[3], C1_r[3], C2_r[3], ld1[3], ld2[3], ld3[3], ld4[3], ld5[3], ld6[3]; MatMultVec(R1,B1,B1_r); MatMultVec(R1,B2,B2_r); MatMultVec(R1,B3,B3_r); MatMultVec(R1,B4,B4_r); MatMultVec(R1,B5,B5_r); MatMultVec(R1,B6,B6_r); MatMultVec(R2,C1,C1_r); MatMultVec(R2,C2,C2_r); VecAdd(B,C1_r,C1_r); VecAdd(B,C2_r,C2_r); VecSub(B1_r,A1,ld1); VecSub(B2_r,A2,ld2); VecSub(B3_r,A3,ld3); VecSub(B4_r,A4,ld4); VecSub(C1_r,B5,ld5); VecSub(C2_r,B6,ld6); Normalization(ld1); Normalization(ld2); Normalization(ld3); Normalization(ld4); Normalization(ld5); Normalization(ld6); float B1_r_A[3], B2_r_A[3], B3_r_A[3], B4_r_A[3], C1_r_B[3], C2_r_B[3]; VecSub(B1_r,A,B1_r_A); VecSub(B2_r,A,B2_r_A); VecSub(B3_r,A,B3_r_A); VecSub(B4_r,A,B4_r_A); VecSub(C1_r,B,C1_r_B); VecSub(C2_r,B,C2_r_B); float tmp[3]; VecCross(B1_r_A,ld1,tmp); jacob_s[0] = tmp[0]; jacob_s[4] = tmp[1]; jacob_s[8] = tmp[2]; VecCross(B2_r_A,ld2,tmp); jacob_s[1] = tmp[0]; jacob_s[5] = tmp[1]; jacob_s[9] = tmp[2]; VecCross(B3_r_A,ld3,tmp); jacob_s[2] = tmp[0]; jacob_s[6] = tmp[1]; jacob_s[10] = tmp[2]; VecCross(B4_r_A,ld4,tmp); jacob_s[3] = tmp[0]; jacob_s[7] = tmp[1]; jacob_s[11] = tmp[2]; VecCross(C1_r_B,ld5,tmp); jacob_e[0] = tmp[0]; jacob_e[2] = tmp[1]; jacob_e[4] = tmp[2]; VecCross(C2_r_B,ld6,tmp); jacob_e[1] = tmp[0]; jacob_e[3] = tmp[1]; jacob_e[5] = tmp[2]; }
/************* * DESCRIPTION: Do the precalculations * INPUT: time actual time * OUTPUT: none *************/ void TRIANGLE::Update(const float time) { VECTOR ptmp, anorm; float k; TIME t; if(actor) { if(time != this->time) { if((actor->time.begin != this->time) || (actor->time.end != time)) { t.begin = this->time; t.end = time; actor->Animate(&t); } // animated triangle actor->matrix->MultVectMat(&p[0]); actor->matrix->MultVectMat(&p[1]); actor->matrix->MultVectMat(&p[2]); actor->rotmatrix->MultVectMat(&vnorm[0]); actor->rotmatrix->MultVectMat(&vnorm[1]); actor->rotmatrix->MultVectMat(&vnorm[2]); } } VecSub(&p[1], &p[0], &e[0]); VecSub(&p[2], &p[1], &e[1]); VecSub(&p[0], &p[2], &e[2]); // Find plane normal VecCross(&e[0], &e[1], &ptmp); norm = ptmp; if (VecNormalize(&norm) == 0.f) { return; } d = dotp(&norm, &p[0]); if(vnorm) { if (VecNormalize(&vnorm[0]) == 0.f || VecNormalize(&vnorm[1]) == 0.f || VecNormalize(&vnorm[2]) == 0.f) { return; } if (dotp(&vnorm[0], &norm) < 0.f) VecScale(-1.f, &vnorm[0], &vnorm[0]); if (dotp(&vnorm[1], &norm) < 0.f) VecScale(-1.f, &vnorm[1], &vnorm[1]); if (dotp(&vnorm[2], &norm) < 0.f) VecScale(-1.f, &vnorm[2], &vnorm[2]); #if 0 if (dotp(&vnorm[0], &norm) < 0.f) { // Reverse direction of surface normal on Phong // triangle if the surface normal points "away" // from the first vertex normal. // Note that this means that we trust the vertex // normals rather than trust that the user gave the // vertices in the correct order. VecScale(-1.f, &norm, &norm); VecScale(-1.f, &ptmp, &ptmp); d = -d; VecScale(-1.f, &e[0], &e[0]); VecScale(-1.f, &e[1], &e[1]); VecScale(-1.f, &e[2], &e[2]); } #endif } // Find "dominant" part of normal vector. anorm.x = Abs(ptmp.x); anorm.y = Abs(ptmp.y); anorm.z = Abs(ptmp.z); // Scale edges by dominant part of normal. This makes intersection // testing a bit faster. flags &= ~OBJECT_NORMALS; if (anorm.x > anorm.y && anorm.x > anorm.z) { flags |= OBJECT_XNORMAL; k = 1.f / ptmp.x; } else { if (anorm.y > anorm.z) { flags |= OBJECT_YNORMAL; k = 1.f / ptmp.y; } else { flags |= OBJECT_ZNORMAL; k = 1.f / ptmp.z; } } VecScale(k, &e[0], &e[0]); VecScale(k, &e[1], &e[1]); VecScale(k, &e[2], &e[2]); }
/* ����ϵ�¹��λ���ٶȵõ������������� */ void Get_KplInfo(double Kepler[6],double orbInfo[6]) { double rVector[3],r,vVector[3],v; double x,y,z,xdot,ydot,zdot,hVector[3]; double esinE,ecosE,E; double orb_a,orb_e,orb_i,orb_o,orb_o2,orb_u,orb_u2,orb_w,orb_M; double normal_Vector[3],NVector[3],n,MVector[3],m; double half_xE,half_f,f; int i,j,k; for (i=0;i<3;i++) { rVector[i] = orbInfo[i]; x = rVector[0]; y = rVector[1]; z = rVector[2]; vVector[i] = orbInfo[i+3]; xdot = vVector[0];ydot = vVector[1];zdot = vVector[2]; } r = norm(rVector,3); v = norm(vVector,3); VecCross(hVector,rVector,vVector); //h = norm(hVector,3); orb_a = GM*r/(2*GM-r*v*v); esinE = sqrt(1/(GM*orb_a))*(x*xdot+y*ydot+z*zdot); ecosE = 1-r/orb_a; E = atan(esinE/ecosE)*180/PI; if ((esinE > 0) && (ecosE < 0)) { E = E+180; } else if ((esinE < 0) && (ecosE > 0)) { E = E+360; } else if ((esinE < 0) && (ecosE < 0)) { E = E+180; } orb_e = (1-r/orb_a)/cos(E*PI/180); orb_i = acos((x*ydot-y*xdot)/(sqrt(GM*orb_a*(1-orb_e*orb_e))))*180/PI; normal_Vector[0] = 0;normal_Vector[1] = 0;normal_Vector[2] = 1; VecCross(NVector,normal_Vector,hVector); n = norm(NVector,3); for (j=0;j<3;j++) { NVector[j] = NVector[j]/n; } orb_o=acos(NVector[0])*180/PI; orb_o2=acos(NVector[1])*180/PI; if ((orb_o2 >= 0) && (orb_o2 <= 90)) { orb_o = orb_o; } else if ((orb_o2 > 90) && (orb_o2 <= 180)) { orb_o = 360-orb_o; } VecCross(MVector,hVector,NVector); m = norm(MVector,3); for (k=0;k<3;k++) { MVector[k] = MVector[k]/m; } orb_u=acos((rVector[0]*NVector[0]+rVector[1]*NVector[1]+rVector[2]*NVector[2])/r)*180/PI; orb_u2=acos((rVector[0]*MVector[0]+rVector[1]*MVector[1]+rVector[2]*MVector[2])/r)*180/PI; if ((orb_u2 >= 0) && (orb_u2 <= 90)) { orb_u = orb_u; } else if ((orb_u2 > 90) && (orb_u2 <= 180)) { orb_u = 360-orb_u; } half_xE=E*PI/(2*180); half_f=atan(sqrt((1+orb_e)/(1-orb_e))*tan(half_xE)); if ((half_xE > PI/2) && (half_xE < PI)) half_f=half_f+PI; f=2*half_f*180/PI; orb_w=orb_u-f; if (orb_w < 0) orb_w = orb_w +360; orb_M=(E*PI/180-orb_e*sin(E*PI/180))*180/PI; Kepler[0] = orb_a; Kepler[1] = orb_e; Kepler[2] = orb_i; Kepler[3] = orb_o; Kepler[4] = orb_w; Kepler[5] = orb_M; return; }