![]() |
| | #1 |
| Registered User Join Date: Apr 2007
Posts: 112
| rotating around object (looat) I wish to use glLookAt instead of rotatef. i started with : Code: // clear the screen & depth buffer glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); // clear the previous transform glLoadIdentity(); // set the camera position gluLookAt( xLookAt,yLookAt,zLookAt, // eye pos 0,0,0, // aim point 0,1,0); // up direction Code: if ((x < -6.28) || (x > 6.28))
{
x=0;
xLookAt = 0;
break;
}
x -= 0.1;
xLookAt = cos(x) * sin (z);
break;
the problem is that it changes the direction of movment instead continue move. i used the next code : Code: //------------------------------------------------------------
/// \file Main.cpp
/// \author Rob Bateman
/// \date 9-feb-2005
/// \brief This is a very simple example of a bezier patch
//------------------------------------------------------------
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
struct Point {
float x;
float y;
float z;
};
/// 4x4 grid of points.
Point Points[4][4] = {
{
{ 10,0,10 },
{ 5,0,10 },
{ -5,0,10 },
{-10,0,10 }
},
{
{ 10,0,5 },
{ 5,6,5 },
{ -5,6,5 },
{-10,0,5 }
},
{
{ 10,0,-5 },
{ 5,6,-5 },
{ -5,6,-5 },
{-10,0,-5 }
},
{
{ 10,0,-10 },
{ 5,0,-10 },
{ -5,0,-10 },
{-10,0,-10 }
}
};
unsigned int num_knots_u=8;
unsigned int num_knots_v=8;
unsigned int num_cvs_u=4;
unsigned int num_cvs_v=4;
unsigned int degree_u=3;
unsigned int degree_v=3;
unsigned int order_u=degree_u+1;
unsigned int order_v=degree_v+1;
float knots_u[] = {0,0,0,0,1,1,1,1};
float knots_v[] = {0,0,0,0,1,1,1,1};
unsigned int LOD=20;
float MinU() {
return knots_u[degree_u];
}
float MinV() {
return knots_v[degree_v];
}
float MaxU() {
return knots_v[num_knots_u-degree_u];
}
float MaxV() {
return knots_v[num_knots_v-degree_v];
}
//------------------------------------------------------------ CoxDeBoor()
//
float CoxDeBoor(float u,int i,int k,const float* Knots) {
if(k==1)
{
if( Knots[i] <= u && u <= Knots[i+1] ) {
return 1.0f;
}
return 0.0f;
}
float Den1 = Knots[i+k-1] - Knots[i];
float Den2 = Knots[i+k] - Knots[i+1];
float Eq1=0,Eq2=0;
if(Den1>0) {
Eq1 = ((u-Knots[i]) / Den1) * CoxDeBoor(u,i,k-1,Knots);
}
if(Den2>0) {
Eq2 = (Knots[i+k]-u) / Den2 * CoxDeBoor(u,i+1,k-1,Knots);
}
return Eq1+Eq2;
}
//------------------------------------------------------------ CalculateU()
//
Point CalculateU(float t,int row) {
Point p = {0,0,0};
// sum the effect of all CV's on the curve at this point to
// get the evaluated curve point
//
for(unsigned int i=0;i!=num_cvs_u;++i) {
// calculate the effect of this point on the curve
float Val = CoxDeBoor(t,i,order_u,knots_u);
if(Val>0.001f) {
// sum effect of CV on this part of the curve
p.x += Val * Points[row][i].x;
p.y += Val * Points[row][i].y;
p.z += Val * Points[row][i].z;
}
}
return p;
}
//------------------------------------------------------------ CalculateV()
//
Point CalculateV(float t,Point* pnts) {
Point p = {0,0,0};
// sum the effect of all CV's on the curve at this point to
// get the evaluated curve point
//
for(unsigned int i=0;i!=num_cvs_v;++i) {
// calculate the effect of this point on the curve
float Val = CoxDeBoor(t,i,order_v,knots_v);
if(Val>0.001f) {
// sum effect of CV on this part of the curve
p.x += Val * pnts[i].x;
p.y += Val * pnts[i].y;
p.z += Val * pnts[i].z;
}
}
return p;
}
//------------------------------------------------------------ Calculate()
//
Point Calculate(float u,float v) {
Point* temp = new Point[num_cvs_v];
for(unsigned int i=0;i!=num_cvs_v;++i) {
// first treat the surface as a set of 4 curves. Calculate
// a point on each of the curves and store the result.
//
temp[i] = CalculateU(u,i);
}
// having got 4 points, we can use it as a bezier curve
// to calculate the v direction
//
Point p = CalculateV(v,temp);
delete [] temp;
return p;
}
//------------------------------------------------------------ OnReshape()
//
void OnReshape(int w, int h)
{
if (h==0) {
h=1;
}
// set the drawable region of the window
glViewport(0,0,w,h);
// set up the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// just use a perspective projection
gluPerspective(45,(float)w/h,0.1,100);
// go back to modelview matrix so we can move the objects about
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//------------------------------------------------------------ Draw()
//
float x = 5;
float alpha = 0;
float y = 16;
float z = 20 ;
float xLookAt = x;
float yLookAt = y;
float zLookAt = z;
void OnDraw() {
// clear the screen & depth buffer
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
// clear the previous transform
glLoadIdentity();
// set the camera position
gluLookAt( xLookAt,yLookAt,zLookAt, // eye pos
0,0,0, // aim point
0,1,0); // up direction
glColor3f(1,0,1);
glPointSize(2);
glBegin(GL_POINTS);
// use the parametric time value 0 to 1
for(int i=0;i!=LOD;++i) {
// calculate the parametric u value
float u = (MaxU()-MinU())*(float)i/(LOD-1) + MinU();
for(int j=0;j!=LOD;++j) {
// calculate the parametric v value
float v = (MaxV()-MinV())*(float)j/(LOD-1) + MinV();
// calculate the point on the surface
Point p = Calculate(u,v);
// draw point
glVertex3f(p.x,p.y,p.z);
}
}
glEnd();
// currently we've been drawing to the back buffer, we need
// to swap the back buffer with the front one to make the image visible
glutSwapBuffers();
}
//------------------------------------------------------------ OnInit()
//
void OnInit() {
// enable depth testing
glEnable(GL_DEPTH_TEST);
}
//------------------------------------------------------------ OnExit()
//
void OnExit() {
}
//------------------------------------------------------------ OnKeyPress()
//
void OnKeyPress(unsigned char key,int,int) {
switch(key) {
// increase the LOD
case '+':
++LOD;
break;
// decrease the LOD
case '-':
--LOD;
// have a minimum LOD value
if (LOD<3)
LOD=3;
break;
case 'a':
// glPop
break;
case 'b':
if ((x < -6.28) || (x > 6.28))
{
x=0;
xLookAt = 0;
break;
}
x -= 0.1;
xLookAt = cos(x) * sin (z);
break;
default:
break;
}
// ask glut to redraw the screen for us...
//x = cos(y) * sin(z);
glutPostRedisplay();
}
//------------------------------------------------------------ main()
//
int main(int argc,char** argv) {
// initialise glut
glutInit(&argc,argv);
// request a depth buffer, RGBA display mode, and we want double buffering
glutInitDisplayMode(GLUT_DEPTH|GLUT_RGBA|GLUT_DOUBLE);
// set the initial window size
glutInitWindowSize(640,480);
// create the window
glutCreateWindow("Bezier Curve: +/- to Change Level of Detail");
// set the function to use to draw our scene
glutDisplayFunc(OnDraw);
// set the function to handle changes in screen size
glutReshapeFunc(OnReshape);
// set the function for the key presses
glutKeyboardFunc(OnKeyPress);
// run our custom initialisation
OnInit();
// set the function to be called when we exit
atexit(OnExit);
// this function runs a while loop to keep the program running.
glutMainLoop();
return 0;
}
Last edited by jabka; 06-13-2008 at 05:05 PM. Reason: no CODE elemnts |
| jabka is offline | |
| | #2 | |
| Frequently Quite Prolix Join Date: Apr 2005 Location: Canada
Posts: 7,629
| That double spaced code is just hard to read. Whitespace is good, but you can have too much of a good thing. A suggestion: don't create global variables with short names like "x" and "y". You might use them by accident. Quote:
Code: #ifdef PI #define CONSTANT_PI PI #elif defined(M_PI) #define CONSTANT_PI M_PI #else #define CONSTANT_PI 3.14159265358979323846264338327950288419716939937510582097 #endif Code: double PI = atan(1) * 4;
__________________ dwk Seek and ye shall find. quaere et invenies. "Simplicity does not precede complexity, but follows it." -- Alan Perlis "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra "The only real mistake is the one from which we learn nothing." -- John Powell Other boards: DaniWeb, TPS Unofficial Wiki FAQ: cpwiki.sf.net My website: http://dwks.theprogrammingsite.com/ Projects: codeform, xuni, atlantis, etc. New project: nort | |
| dwks is offline | |
| | #3 |
| Super Moderator Join Date: Aug 2001
Posts: 7,472
| To rotate around something always translate then rotate. |
| Bubba is offline | |
| | #4 |
| Registered User Join Date: Apr 2007
Posts: 112
| So not to use glLookAt ? moment i didn't understant : if i use glRotate then i rotate the object while i wish to rotate only the camera. |
| jabka is offline | |
| | #5 |
| Registered User Join Date: Jan 2008
Posts: 65
| What are you trying to do? Bubba is recommending you make a translation matrix and then multiply it by a rotation matrix, as that is how you would rotate one object about another. But for a camera, glLookAt, or more technically a view matrix will do the trick. edit: Was just looking at your code, it doesn't seem quite right. Code: if ((x < -6.28) || (x > 6.28))
{
x=0;
xLookAt = 0;
break;
}
x -= 0.1;
xLookAt = cos(x) * sin (z);
break;
Code: angle-=0.1;
if(angle<0)
angle+=6.28;
xLookAt = cos(angle) * radius;
yLookAt = sin(angle) * radius;
Last edited by Drac; 06-14-2008 at 08:16 PM. |
| Drac is offline | |
| | #6 |
| Registered User Join Date: Apr 2007
Posts: 112
| Still same effect back and forth . Also why do you change the y factor ? i wish to rotate around opengl y axis (math z axis). I think that it has connection to the fact cos is a par function ( same value for x and -x) . |
| jabka is offline | |
| | #7 |
| Super Moderator Join Date: Aug 2001
Posts: 7,472
| Perhaps a little bit of a math primer might help. I recommend buying a book on 3D mathematics from www.amazon.com. www.gamedev.net has several recommendations in their articles and books section that will guide you through the maze of books that are available. Given what I've seen here I don't think diving into rotations and translations would even help you at this point. |
| Bubba is offline | |
| | #8 |
| Registered User Join Date: Oct 2006 Location: UK/Norway
Posts: 464
| A bit off topic, but still within I think? Is there any other way to rotate a mesh then using a matrix? |
| h3ro is offline | |
| | #9 | ||
| Registered User Join Date: Jan 2008
Posts: 65
| Quote:
Quote:
| ||
| Drac is offline | |
| | #10 |
| Registered User Join Date: Apr 2007
Posts: 112
| [Fixed] or i hate typos First of all thnx for all the great help and special thanks to dimtrios5000 and Jarik D The fixed code (the new parts are ): Code: xLookAt = z * cos(y) * sin(x);
yLookAt = z * sin(y);
zLookAt = -1 * z * cos(y) * cos(x);
next for some reason i didn't noticed that i use 6.8 instead of 6.28 (the "glitch" source). |
| jabka is offline | |
| | #11 |
| Super Moderator Join Date: Aug 2001
Posts: 7,472
| That code will gimbal lock.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #12 |
| Registered User Join Date: Apr 2007
Posts: 112
| Sorry for asking (not native English speaker ) what is a "gimbal lock " ? I tried to google and understand that it has to do with Gyroscopes. In this code i had a problem to rotate around and object but to keep the angle to the base the same . |
| jabka is offline | |
| | #13 |
| Registered User Join Date: Jan 2008
Posts: 65
| |
| Drac is offline | |
| | #14 |
| Super Moderator Join Date: Aug 2001
Posts: 7,472
| Gimbal lock is when one or more axes are mapped onto each other. If you think of 3D rotations as 3 concentric rings, gimbal lock is when two or more of those rings line up. At this point a rotation on one axis will also yield a rotation on another axis. With Euler angles there is no way to avoid gimbal lock. In order to correct this you can use quaternions or you can perform axis-angle rotations. Both of these operate on the principle of rotating around an arbitrary axis as opposed to rotating around one of the three cardinal axes. Here is Direct3D code to rotate around the x axis. Perhaps others here could convert this to OpenGL code for you. Code:
D3DXVECTOR3 g_vecRight;
D3DXVECTOR3 g_vecUp;
D3DXVECTOR3 g_vecLook;
D3DXVECTOR3 g_vecPos;
//Reset all vectors
void ResetVectors()
{
g_vecRight = D3DXVECTOR3(1.0f,0.0f,0.0f);
g_vecUp = D3DXVECTOR3(0.0f,1.0f,0.0f);
g_vecLook = D3DXVECTOR3(0.0f,0.0f,1.0f);
g_vecPos = D3DXVECTOR3(0.0f,0.0f,0.0f);
}
//Make all vectors orthonormal to each other - 90 degrees to each other
void MakeOrtho()
{
D3DXVec3Normalize(&g_vecLook,&g_vecLook);
D3DXVec3Cross(&g_vecUp,&g_vecLook,&g_vecRight);
D3DXVec3Normalize(&g_vecUp,&g_vecUp);
D3DXVec3Cross(&Right,&Up,&Look);
D3DXVec3Normalize(&Right,&Right);
}
//Pitch - rotate about the x or right axis
void Pitch(float radians)
{
MakeOrtho();
//Rotation about x is a rotation about the right vector
D3DXMATRIX matRotX;
D3DXMatrixRotationAxis(&matRotX,&g_vecRight,radians);
D3DXVec3TransformCoord(&g_vecUp,&g_vecUp,&matRotX);
D3DXVec3TransformCoord(&g_vecLook,&g_vecLook,&matRotX);
}
//Get the camera view matrix
void getViewMatrix(D3DXMATRIX *outMat)
{
MakeOrtho();
float x = -D3DXVec3Dot(&g_vecPos, &g_vecRight);
float y = -D3DXVec3Dot(&g_vecPos, &g_vecUp);
float z = -D3DXVec3Dot(&g_vecPos, &g_vecLook);
(*outMat)(0,0) = g_vecRight.x;
(*outMat)(1,0) = g_vecRight.y;
(*outMat)(2,0) = g_vecRight.z;
(*outMat)(3,0) = x;
(*outMat)(0,1) = g_vecUp.x;
(*outMat)(1,1) = g_vecUp.y;
(*outMat)(2,1) = g_vecUp.z;
(*outMat)(3,1) = y;
(*outMat)(0,2) = g_vecLook.x;
(*outMat)(1,2) = g_vecLook.y;
(*outMat)(2,2) = g_vecLook.z;
(*outMat)(3,2) = z;
(*outMat)(0,3) = 0.0f;
(*outMat)(1,3) = 0.0f;
(*outMat)(2,3) = 0.0f;
(*outMat)(3,3) = 1.0f;
}
//Get the object view matrix (transpose of the camera view matrix)
void getObjectMatrix(D3DXMATRIX *outMat)
{
MakeOrtho();
(*outMatrix)(0,0) = g_vecRight.x;
(*outMatrix)(1,0) = g_vecUp.x;
(*outMatrix)(2,0) = g_vecLook.x;
(*outMatrix)(3,0) = g_vecPos.x;//x;
(*outMatrix)(0,1) = g_vecRight.y;
(*outMatrix)(1,1) = g_vecUp.y;
(*outMatrix)(2,1) = g_vecLook.y;
(*outMatrix)(3,1) = g_vecPos.y;//y;
(*outMatrix)(0,2) = g_vecRight.z;
(*outMatrix)(1,2) = g_vecUp.z;
(*outMatrix)(2,2) = g_vecLook.z;
(*outMatrix)(3,2) = g_vecPos.z;//z;
(*outMatrix)(0,3) = 0.0f;
(*outMatrix)(1,3) = 0.0f;
(*outMatrix)(2,3) = 0.0f;
(*outMatrix)(3,3) = 1.0f;
}
__________________ If you aim at everything you will hit something but you won't know what it is. Last edited by Bubba; 06-18-2008 at 05:05 PM. |
| Bubba is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| using this as synchronization object | George2 | C# Programming | 0 | 03-22-2008 07:49 AM |
| circular doubly linked list help | gunnerz | C++ Programming | 5 | 04-28-2007 08:38 PM |
| I believe I've found an official Answer to my Problem (Object Factories) | Shamino | Game Programming | 60 | 12-20-2005 11:36 PM |
| Question on l-values. | Hulag | C++ Programming | 6 | 10-13-2005 04:33 PM |
| A question about constructors... | Wolve | C++ Programming | 9 | 05-04-2005 04:24 PM |