From: Alan N. <ala...@us...> - 2012-07-24 22:13:37
|
Update of /cvsroot/vapor/vapor/lib/params In directory vz-cvs-3.sog:/tmp/cvs-serv26244/lib/params Modified Files: animate.cpp animate.h animationparams.cpp glutil.cpp glutil.h Log Message: Fixed many problems with scene stretching, improved accuracy of some matrix operations. Index: glutil.cpp =================================================================== RCS file: /cvsroot/vapor/vapor/lib/params/glutil.cpp,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** glutil.cpp 12 Jul 2012 20:16:25 -0000 1.34 --- glutil.cpp 24 Jul 2012 22:13:35 -0000 1.35 *************** *** 65,68 **** --- 65,74 ---- 0.0, 0.0, 0.0, 1.0, }; + GLdouble idmatrixd[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + }; *************** *** 122,125 **** --- 128,142 ---- vcopy(temp, cross); } + void vcross(const double *v1, const double *v2, double *cross) + { + /* Vector cross product. + */ + double temp[3]; + + temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); + temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); + temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]); + vcopy(temp, cross); + } *************** *** 217,220 **** --- 234,246 ---- m2[row] = m1[row]; } + void mcopy(double *m1, double *m2) + { + /* Copy a 4x4 matrix + */ + int row; + + for(row = 0 ; row < 16 ; row++) + m2[row] = m1[row]; + } *************** *** 243,246 **** --- 269,291 ---- mcopy(temp, prod); } + void mmult(GLdouble *m1, GLdouble *m2, GLdouble *prod) + { + /* Multiply two 4x4 matricies + */ + int row, col; + GLdouble temp[16]; + + + /* + * Use OpenGL style matrix mult -- Wes. + */ + for(row = 0 ; row < 4 ; row++) + for(col = 0 ; col < 4 ; col++) + temp[row*4 + col] = (m1[row*4] * m2[col] + + m1[1+row*4] * m2[col+4] + + m1[2+row*4] * m2[col+8] + + m1[3+row*4] * m2[col+12]); + mcopy(temp, prod); + } *************** *** 305,308 **** --- 350,411 ---- return 1; } + int minvert(GLdouble *mat, GLdouble *result) + { + // Invert a 4x4 matrix + + int i, j, k; + double temp; + double m[8][4]; + + mcopy(idmatrixd, result); + // mat[i,j] is row j, col i: + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + m[i][j] = mat[i+4*j]; + m[i+4][j] = result[i+4*j]; + } + } + + // Work across by columns (i is col index): + + for (i = 0; i < 4; i++) { + //Find largest entry in the column, below the diagonal: + double maxval = 0.f; + int pivot = -1; + for (int rw = i; rw < 4; rw++){ + if (abs(m[i][rw]) > maxval){ + maxval = abs(m[i][rw]); + pivot = rw; + } + } + if(pivot < 0) return 0; //otherwise, can't invert! + + if (pivot != i){ //Swap i and pivot row: + for (k = i; k < 8; k++) { + temp = m[k][i]; + m[k][i] = m[k][pivot]; + m[k][pivot] = temp; + } + } + + + // Divide original row by pivot element, which is now the [i][i] element: + + for (j = 7; j >= i; j--) + m[j][i] /= m[i][i]; + + // Subtract other rows, to make row i be the only row with nonzero elt in col i: + + for (j = 0; j < 4; j++) + if (i != j) + for (k = 7; k >= i; k--) + m[k][j] -= m[k][i] * m[i][j]; + } + //copy back the last 4 columns: + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + result[i+4*j] = m[i+4][j]; + return 1; + } void qnormal(float *q) *************** *** 385,389 **** http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion */ ! #define M_EPSILON 0.00000001f void rotmatrix2q(float* m, float *q ){ float trace = m[0] + m[5] + m[10] + 1.0f; --- 488,492 ---- http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion */ ! #define M_EPSILON 0.00000001 void rotmatrix2q(float* m, float *q ){ float trace = m[0] + m[5] + m[10] + 1.0f; *************** *** 417,420 **** --- 520,554 ---- } + void rotmatrix2q(double* m, double *q ){ + double trace = m[0] + m[5] + m[10] + 1.0; + if( trace > M_EPSILON ) { + double s = 0.5 / sqrt(trace); + q[3] = 0.25 / s; + q[0] = ( m[9] - m[6] ) * s; + q[1] = ( m[2] - m[8] ) * s; + q[2] = ( m[4] - m[1] ) * s; + } else { + if ( m[0] > m[5] && m[0] > m[10] ) { + double s = 2.0 * sqrt( 1.0 + m[0] - m[5] - m[10]); + q[0] = 0.25 * s; + q[1] = (m[1] + m[4] ) / s; + q[2] = (m[2] + m[8] ) / s; + q[3] = (m[6] - m[9] ) / s; //???? minus? + } else if (m[5] > m[10]) { + double s = 2.0 * sqrt( 1.0 + m[5] - m[0] - m[10]); + q[0] = (m[1] + m[4] ) / s; + q[1] = 0.25 * s; + q[2] = (m[6] + m[9] ) / s; + q[3] = (m[2] - m[8] ) / s; + } else { + double s = 2.0 * sqrt( 1.0 + m[10] - m[0] - m[5] ); + q[0] = (m[2] + m[8] ) / s; + q[1] = (m[6] + m[9] ) / s; + q[2] = 0.25 * s; + q[3] = (m[1] - m[4] ) / s;//?? off by minus?? + } + } + } + void rvec2q( *************** *** 600,604 **** vcopy(trans, mtrx+12); } ! /* * make a modelview matrix from viewer position, direction, and up vector --- 734,746 ---- vcopy(trans, mtrx+12); } ! void ! makeTransMatrix(float *trans, double* mtrx){ ! for (int i = 0; i<12; i++) mtrx[i] = 0.; ! mtrx[0] = 1.; ! mtrx[5] = 1.; ! mtrx[10] = 1.; ! mtrx[15] = 1.; ! for (int i = 0; i<3; i++) mtrx[i+12] = (double)trans[i]; ! } /* * make a modelview matrix from viewer position, direction, and up vector *************** *** 650,653 **** --- 792,851 ---- if(!rc) assert(rc);//Only catch this in debug mode } + /* + * make a modelview matrix from viewer position, direction, and up vector + * Vectors must be nonzero + * side-effect: will alter input values if not valid. + */ + void + makeModelviewMatrixD(float* vpos, float* vdir, float* upvec, double* mtrx){ + double vtemp[3]; + double left[3] = {-1.f, 0.f, 0.f}; + double ydir[3] = {0.f, 1.f, 0.f}; + double right[3]; + double dupvec[3], dvdir[3],dvpos[3]; + for (int i = 0; i<3; i++){ + dupvec[i] = upvec[i]; + dvdir[i] = vdir[i]; + dvpos[i] = vpos[i]; + } + + //Normalize the vectors: + vnormal(dupvec); + vnormal(dvdir); + //Force the up vector to be orthogonal to viewDir + vcopy(dvdir, vtemp); + vscale(vtemp, vdot(dvdir, dupvec)); + //Subtract the component of up in the viewdir direction + vsub(dupvec, vtemp, dupvec); + //Make sure it's still valid + if (vdot(dupvec,dupvec) == 0.f) { + //First try up = viewdir x left + vcross(dvdir, left, dupvec); + if (vdot (dupvec, dupvec) == 0.f) { + //try viewdir x ydir + vcross(dvdir, ydir, dupvec); + } + } + vnormal(dupvec); + //calculate "right" vector: + vcross(dvdir, dupvec, right); + //Construct matrix: + double minv[16]; + //Fill in bottom row: + minv[3] = 0.; + minv[7] = 0.; + minv[11] = 0.; + minv[15] = 1.; + //copy in first 3 elements of columns + vcopy(right, minv); + vcopy(dupvec, minv+4); + //third col is neg of viewdir + + vcopy(dvdir, minv + 8); + vscale(minv+8, -1.); + vcopy(dvpos, minv+ 12); + int rc = minvert(minv, mtrx); + if(!rc) assert(rc);//Only catch this in debug mode + } void matrix4x4_vec3_mult( const GLfloat m[16], Index: glutil.h =================================================================== RCS file: /cvsroot/vapor/vapor/lib/params/glutil.h,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** glutil.h 12 Jul 2012 20:16:25 -0000 1.27 --- glutil.h 24 Jul 2012 22:13:35 -0000 1.28 *************** *** 87,91 **** --- 87,93 ---- ); PARAMS_API void makeModelviewMatrix(float* vpos, float* vdir, float* upvec, float* matrix); + PARAMS_API void makeModelviewMatrixD(float* vpos, float* vdir, float* upvec, double* matrix); PARAMS_API void makeTransMatrix(float* transVec, float* matrix); + PARAMS_API void makeTransMatrix(float* transVec, double* matrix); PARAMS_API void vscale (float *v, float s); PARAMS_API void vscale (double *v, double s); *************** *** 93,96 **** --- 95,99 ---- PARAMS_API void vhalf (const float *v1, const float *v2, float *half); PARAMS_API void vcross (const float *v1, const float *v2, float *cross); + PARAMS_API void vcross (const double *v1, const double *v2, double *cross); PARAMS_API void vreflect (const float *in, const float *mirror, float *out); PARAMS_API void vtransform (const float *v, GLfloat *mat, float *vt); *************** *** 102,107 **** --- 105,113 ---- PARAMS_API bool pointOnRight(float* pt1, float* pt2, float* testPt); PARAMS_API void mcopy (GLfloat *m1, GLfloat *m2); + PARAMS_API void mcopy (double *m1, double *m2); PARAMS_API void mmult (GLfloat *m1, GLfloat *m2, GLfloat *prod); + PARAMS_API void mmult (GLdouble *m1, GLdouble *m2, GLdouble *prod); PARAMS_API int minvert (GLfloat *mat, GLfloat *result); + PARAMS_API int minvert (GLdouble *mat, GLdouble *result); //Some routines to handle 3x3 rotation matrices, represented as 9 floats, *************** *** 134,137 **** --- 140,144 ---- PARAMS_API void rvec2q(const float rvec[3],float radians,float q[4]); PARAMS_API void rotmatrix2q(float* m, float *q ); + PARAMS_API void rotmatrix2q(double* m, double *q ); PARAMS_API float getScale(GLfloat* rotmatrix); PARAMS_API void view2Quat(float vdir[3], float upvec[3], float q[4]); Index: animate.h =================================================================== RCS file: /cvsroot/vapor/vapor/lib/params/animate.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** animate.h 20 Jul 2012 21:44:58 -0000 1.3 --- animate.h 24 Jul 2012 22:13:35 -0000 1.4 *************** *** 79,83 **** animate(); ~animate (); ! void keyframeInterpolate(std::vector<Keyframe*>& key_vec, std::vector<Viewpoint*>& view_vec); void priorInterPolationCalcs(std::vector<Keyframe*>& key_vec, std::vector<Viewpoint*>& view_vec); void interpolate (float T[], int N,int startIndex,std::vector<Keyframe*>& key_vec); --- 79,83 ---- animate(); ~animate (); ! void keyframeInterpolate(std::vector<Keyframe*>& key_vec, std::vector<Viewpoint*>& view_vec,float stretchFactor); void priorInterPolationCalcs(std::vector<Keyframe*>& key_vec, std::vector<Viewpoint*>& view_vec); void interpolate (float T[], int N,int startIndex,std::vector<Keyframe*>& key_vec); Index: animationparams.cpp =================================================================== RCS file: /cvsroot/vapor/vapor/lib/params/animationparams.cpp,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** animationparams.cpp 23 Jul 2012 16:43:40 -0000 1.35 --- animationparams.cpp 24 Jul 2012 22:13:35 -0000 1.36 *************** *** 450,457 **** const float* strExts = DataStatus::getInstance()->getStretchedExtents(); const float* stretch = DataStatus::getInstance()->getStretchFactors(); float stretchedSize; float maxStretchedSize = -1.e30; - float dstWarp[3]; - int maxStretchedDim = -1; for (int i = 0; i<3; i++) { stretchedSize = strExts[i+3] - strExts[i]; --- 450,456 ---- const float* strExts = DataStatus::getInstance()->getStretchedExtents(); const float* stretch = DataStatus::getInstance()->getStretchFactors(); + float stretchedSize; float maxStretchedSize = -1.e30; for (int i = 0; i<3; i++) { stretchedSize = strExts[i+3] - strExts[i]; *************** *** 460,468 **** } } ! for (int i = 0; i<3; i++){ ! dstWarp[i] = stretch[i]/maxStretchedSize; } ! myAnimate->setDistanceWarp(dstWarp); ! myAnimate->keyframeInterpolate(keyframes, loadedViewpoints); //Test rotation interpolation of first pair of keyframes --- 459,505 ---- } } ! ! //Modify keyframes by stretching according to scene stretch factors. ! //Modify speeds by factor to make speed = 1 for crossing entire scene in one frame ! vector<Keyframe*> animKeyframes; ! ! for (int i = 0; i<keyframes.size(); i++){ ! Viewpoint* vp = new Viewpoint(); ! Keyframe* kFrame = new Keyframe(vp,keyframes[i]->speed * maxStretchedSize,keyframes[i]->timeStep,keyframes[i]->frameNum); ! Viewpoint* vkey = keyframes[i]->viewpoint; ! for (int j = 0; j<3; j++){ ! //The displacement between the camera and rotation center is stretched ! //The rotation center is not moved. ! float camdisp = stretch[j]*(vkey->getCameraPosLocal(j)-vkey->getRotationCenterLocal(j)); ! vp->setCameraPosLocal(j,vkey->getRotationCenterLocal(j)+camdisp); ! vp->setRotationCenterLocal(j,vkey->getRotationCenterLocal(j)); ! //force vdir to point from camera to rot center ! vp->setViewDir(j,vp->getRotationCenterLocal(j)-vp->getCameraPosLocal(j)); ! vp->setUpVec(j,keyframes[i]->viewpoint->getUpVec(j)); ! } ! vnormal(vp->getUpVec()); ! vnormal(vp->getViewDir()); ! kFrame->viewpoint = vp; ! animKeyframes.push_back(kFrame); } ! ! myAnimate->keyframeInterpolate(animKeyframes, loadedViewpoints, 1.f); ! //copy back the frame counts ! for (int i = 0; i<animKeyframes.size(); i++){ ! keyframes[i]->frameNum = animKeyframes[i]->frameNum; ! } ! ! //Undo stretch: ! for (int i = 0; i<loadedViewpoints.size(); i++){ ! Viewpoint* vp = loadedViewpoints[i]; ! for (int j = 0; j<3; j++){ ! float unstretch = 1./stretch[j]; ! float camdisp = unstretch*(vp->getCameraPosLocal(j)-vp->getRotationCenterLocal(j)); ! vp->setCameraPosLocal(j,vp->getRotationCenterLocal(j)+camdisp); ! } ! vnormal(vp->getUpVec()); ! vnormal(vp->getViewDir()); ! } ! //Test rotation interpolation of first pair of keyframes *************** *** 522,529 **** //Adjust time steps: ! for (int i = 0; i<keyframes.size()-1; i++){ ! int firstTstep = keyframes[i]->timeStep; ! int nextTstep = keyframes[i+1]->timeStep; ! int numFrames = keyframes[i]->frameNum; for (int j = 0; j<numFrames; j++){ float frameFraction = (float)j/(float)(numFrames); --- 559,566 ---- //Adjust time steps: ! for (int i = 0; i<animKeyframes.size()-1; i++){ ! int firstTstep = animKeyframes[i]->timeStep; ! int nextTstep = animKeyframes[i+1]->timeStep; ! int numFrames = animKeyframes[i]->frameNum; for (int j = 0; j<numFrames; j++){ float frameFraction = (float)j/(float)(numFrames); *************** *** 533,542 **** } //At the very end, use the timestep of the last keyframe: ! loadedTimesteps.push_back(keyframes[keyframes.size()-1]->timeStep); int num1 = loadedTimesteps.size(); int num2 = loadedViewpoints.size(); assert(num1 == num2); if (keyframingEnabled()) setEndFrameNumber(loadedViewpoints.size()-1); ! } void AnimationParams::enableKeyframing( bool onoff){ --- 570,585 ---- } //At the very end, use the timestep of the last keyframe: ! loadedTimesteps.push_back(animKeyframes[animKeyframes.size()-1]->timeStep); int num1 = loadedTimesteps.size(); int num2 = loadedViewpoints.size(); assert(num1 == num2); if (keyframingEnabled()) setEndFrameNumber(loadedViewpoints.size()-1); ! //Now we can clear it out: ! ! for (int i = 0; i<animKeyframes.size(); i++){ ! delete animKeyframes[i]->viewpoint; ! delete animKeyframes[i]; ! } ! animKeyframes.clear(); } void AnimationParams::enableKeyframing( bool onoff){ Index: animate.cpp =================================================================== RCS file: /cvsroot/vapor/vapor/lib/params/animate.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** animate.cpp 20 Jul 2012 21:44:58 -0000 1.5 --- animate.cpp 24 Jul 2012 22:13:35 -0000 1.6 *************** *** 10,14 **** #include "animate.h" #include <math.h> ! #include<vector> using namespace VAPoR; //constructor --- 10,14 ---- #include "animate.h" #include <math.h> ! #include <vector> using namespace VAPoR; //constructor *************** *** 46,50 **** /////////////////////////////////////////////////////////////////////////////////////////////////// ! void animate:: keyframeInterpolate(std::vector<Keyframe*>& key_vec, std::vector<Viewpoint*>& view_vec) { --- 46,50 ---- /////////////////////////////////////////////////////////////////////////////////////////////////// ! void animate:: keyframeInterpolate(std::vector<Keyframe*>& key_vec, std::vector<Viewpoint*>& view_vec,float stretchFactor) { *************** *** 60,69 **** incrementFactor= 1.0 / float(testPoints); ! ! //segment in between initialization ! for (int i=0; i < noVPs; i++) totalSegments[i]=0; ! ! //start doing the interpolation priorInterPolationCalcs(key_vec, view_vec); --- 60,75 ---- incrementFactor= 1.0 / float(testPoints); ! ! //Pre-steps ! for (int i=0; i < noVPs; i++) ! { ! //init of frames between two starting frames ! totalSegments[i]=0; ! //copy speed to a local store with stretch factor ! speed[i] = key_vec[i]->speed * stretchFactor; ! } ! ! //start doing the interpolation priorInterPolationCalcs(key_vec, view_vec); *************** *** 109,113 **** //checking for two consecutive speeds = 0 ! if (key_vec[i]->speed ==0 && key_vec[i+1]->speed ==0){ //push in the currrent keyframe into the vector --- 115,119 ---- //checking for two consecutive speeds = 0 ! if (speed[i] ==0 && speed[i+1] ==0){ //push in the currrent keyframe into the vector *************** *** 210,214 **** for (int i=1; i < noVPs-1;i++) { ! //camera --- 216,220 ---- for (int i=1; i < noVPs-1;i++) { ! //camera *************** *** 344,357 **** //No of frames ! int N = (int) ((2*distance[testPoints-1]/ (key_vec[startIndex]->speed +key_vec[startIndex+1]->speed)) + 0.5); // std::cout<<"No of frames... "<<N<<std::endl; ! float n = (2*distance[testPoints-1] )/(key_vec[startIndex]->speed + key_vec[startIndex+1]->speed); // std::cout<<"n "<<n<<std::endl; //correction factor float F = float (n/N); ! float s1 = F* key_vec[startIndex]->speed; ! float s2= F*key_vec[startIndex+1]->speed; N = (int) (2*distance[testPoints-1]/ (s1 +s2)); --- 350,363 ---- //No of frames ! int N = (int) ((2*distance[testPoints-1]/ (speed[startIndex] +speed[startIndex+1])) + 0.5); // std::cout<<"No of frames... "<<N<<std::endl; ! float n = (2*distance[testPoints-1] )/(speed[startIndex] + speed[startIndex+1]); // std::cout<<"n "<<n<<std::endl; //correction factor float F = float (n/N); ! float s1 = F*speed[startIndex]; ! float s2 = F*speed[startIndex+1]; N = (int) (2*distance[testPoints-1]/ (s1 +s2)); *************** *** 399,410 **** //Has to pass through the start key frame. T[0]=0; ! std::cout<<" "<<"%%Frame pos " <<T[0]<<" Distance== "<<dist_prime[0]<<std::endl; for (int i=1; i<N+1; i++){ T[i] = t_distanceFunc(dist_prime[i-1]); ! std::cout<<" "<<"%%Frame pos " <<T[i]<<" Distance== "<<dist_prime[i-1]<<std::endl; } ! std::cout<<"--------------------------------"<<std::endl; //value of num of segments totalSegments[startIndex]=N+1; --- 405,416 ---- //Has to pass through the start key frame. T[0]=0; ! //std::cout<<" "<<"%%Frame pos " <<T[0]<<" Distance== "<<dist_prime[0]<<std::endl; for (int i=1; i<N+1; i++){ T[i] = t_distanceFunc(dist_prime[i-1]); ! // std::cout<<" "<<"%%Frame pos " <<T[i]<<" Distance== "<<dist_prime[i-1]<<std::endl; } ! //value of num of segments totalSegments[startIndex]=N+1; |