I'm trying to program a simple animation using GLUT and OpenGL in c++. I've created three functions for this purpose: catSpline(), fillArray(), and fixedAngle(). catSpline() returns a GLfloat value, fillArray() is a void function that consists of a series of loops that fills a series of arrays with GLfloat values produced using catSpline, and fixedAngle() will return a 16-unit array. Here is the code for these three methods:
GLfloat * fixedAngle(GLfloat initialX, GLfloat initialY, GLfloat initialZ, GLfloat rotX, GLfloat rotY, GLfloat rotZ)
{
ArrayXXf z(4,4); //initializing the 4x4 rotation matrixes
ArrayXXf y(4,4);
ArrayXXf x(4,4);
x<<1, 0, 0, 0,
0, cos(rotX), -sin(rotX), 0,
0, sin(rotX), cos(rotX), 0,
0, 0, 0, 1;
y<<cos(rotY), 0, sin(rotY), 0,
0, 1, 0, 0,
-sin(rotY), 0, cos(rotY), 0,
0, 0, 0, 1;
z<< cos(rotZ), -sin(rotZ), 0, 0,
sin(rotZ), cos(rotZ), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
ArrayXXf fin(4,4);
fin = x * y * z;
fin(0,3) = initialX;
fin(1,3) = initialY;
fin(2,3) = initialZ;
//now we've moved the translational information into the final matrix
// std::cout << fin;
fin(3,3) = 1;
GLfloat * arr;
arr = (GLfloat *) malloc(16*sizeof(GLfloat));
arr[0] = fin(0,0);
arr[1] = fin(0,1);
arr[2] = fin(0,2);
arr[3] = fin(0,3);
arr[4] = fin(1,0);
arr[5] = fin(1,1);
arr[6] = fin(1,2);
arr[7] = fin(1,3);
arr[8] = fin(2,0);
arr[9] = fin(2,1);
arr[10] = fin(2,2);
arr[11] = fin(2,3);
arr[12] = fin(3,0);
arr[13] = fin(3,1);
arr[14] = fin(3,2);
arr[15] = fin(3,3);
return arr;
}
GLfloat catSpline(GLfloat x1, GLfloat x2, GLfloat x3, GLfloat x4, GLfloat t)
{
ArrayXXf M(4,4); //4x4 M matrix
ArrayXXf P(4,1); //matrix to hold keyframe x values
P(0,0) = x1;
P(1,0) = x2;
P(2,0) = x3;
P(3,0) = x4;
//keyframe x values
M(0,0) = -0.5;
M(0,1) = 2-(-0.5);
M(0,2) = -0.5-2;
M(0,3) = 0.5;
M(1,0) = 2*0.5;
M(1,1) = 0.5-3;
M(1,2) = 3-(2*0.5);
M(1,3) = -0.5;
M(2,0) = -0.5;
M(2,1) = 0;
M(2,2) = 0.5;
M(2,3) = 0;
M(3,0) = 0;
M(3,1) = 1;
M(3,2)=0;
M(3,3)=0;
ArrayXXf T(1,4);
T(0,0) = t*t*t; //you can't cube a float, but you can get the same result by doing this
T(0,1) = t*t;
T(0,2) = t;
T(0,3)=1;
//now the T matrix is filled
ArrayXXf TM(1,4);
TM(0,0) = (T(0,0) * M(0,0)) + (T(0,1) * M(1,0)) + (T(0,2) * M(2,0)) + (T(0,3) * M(0,3));
TM(0,1) = (T(0,0) * M(0,1)) + (T(0,1) * M(1,1)) + (T(0,2) * M(2,1)) + (T(0,3) * M(3,1));
TM(0,2) = (T(0,0) * M(0,2)) + (T(0,1) * M(1,2)) + (T(0,2) * M(2,2)) + (T(0,3) * M(3,2));
TM(0,3) = (T(0,0) * M(0,3)) + (T(0,1) * M(1,3)) + (T(0,2) * M(2,3)) + (T(0,3) * M(3,3));
//first multiply T amd M
GLfloat TMP;
TMP = (TM(0,0) * P(0,0)) + (TM(0,1) *P(1,0)) + (TM(0,2) * P(2,0)) + (TM(0,3) * P(3,0));
return TMP;
}
void fillArrays()
{
/* zRot = catSpline(2, 4, 5, 6);
yRot = catSpline(1, 4, 6, 7);
xRot = catSpline(6, 3, 2, 6);
xArr = catSpline(9, 4, 3, 10);
yArr = catSpline(1, 2, 4, 8);
zArr = catSpline(8, 3, 1, 3);*/
for(int j=0; j>=100; j++)
{
xArr[j] = catSpline(2, 4, 5, 6, t);
t+=0.1;
}
for(int i=0; i>=100; i++)
{
yArr[i] = catSpline(2, 4, 5, 6, ty);
ty+=0.1;
}
for(int k=0; k>=100; k++)
{
xArr[k] = catSpline(2, 4, 5, 6, tz);
tz += 0.1;
}
for(int a=0; a>=100; a++)
{
xRot[a] = catSpline(2, 4, 5, 6, rx);
rx += 0.1;
}
for(int b=0; b>=100; b++)
{
yRot[b] = catSpline(2, 4, 5, 6, ry);
rz += 0.1;
}
for(int c=0; c>=100; c++)
{
zRot[c] = catSpline(2, 4, 5, 6, rz);
rz += 0.1;
}
}
The way I use these three functions is in a loop called Render, I set up OpenGL for displaying an animation of a teapot model, call fillArrays(), and then attempt to store the result of a single fixedAngle call (using a few entries form the arrays filled in just before) in a new array called foo. This seems to be the cause of the errors, with foo only containing a pointer address rather than pointing to the actual array so I can use it. This is the code I'm using to call these functions:
fillArrays();
GLfloat * foo;
foo = (GLfloat *) malloc(16*sizeof(GLfloat));
foo = fixedAngle(xArr[tp], yArr[tp], zArr[tp], xRot[tp], yRot[tp], zRot[tp]);
glLoadMatrixf(foo);
After having used multiple print statements to print out the results of my functions, I know that the problem has to be how I set up the pointers somewhere. Can anyone help me return the array correctly?
Please note: if some of the matrix syntax seems unfammiliar, it's because I'm using a c++ library called Eigen to do some of the matrix math. Once again, after having rigorously printed out the results of the functions, I know that the functions that use Eigen syntax are producing the right values.
foo, then immediately assigned other allocated memory tofoo. That's sure to be a memory leak one day. That's likely not the cause of your error, though.std::vector<GLfloat>- as long as you usepush_back, or give the constructor an appropriate initial size or explicitly callresize()before indexing with[], you basically can't screw it up. Hmmm.....x<<1, 0, 0, 0,...;do?