HowToC:FollowAnObject
From S2PLOT
(Difference between revisions)
												
			
			| Revision as of 23:35, 19 August 2008 Dbarnes (Talk | contribs) ← Previous diff  | 
				Current revision Dbarnes (Talk | contribs) (→How to follow an object with the camera)  | 
			||
| Line 5: | Line 5: | ||
| 1. use a handle callback to register the most recently selected handle: | 1. use a handle callback to register the most recently selected handle: | ||
| <code><pre> | <code><pre> | ||
| - | // define an S2PLOT OpenGL callback function */ | + | int camfollow; // initialised to -1 in main | 
| - | void openglcb(void) { | + | unsigned char *selected; // array storing selected state of all handles | 
| - | // store the state | + | void pickcb(int *id) { | 
| - | glPushAttrib(GL_ALL_ATTRIB_BITS); | + | // ... | 
| + | // toggle state: | ||
| + | selected[*id] = (selected[*id] + 1) % 2; | ||
| + | if (selected[*id]) { | ||
| + | camfollow = *id; | ||
| + | } else { | ||
| + | camfollow = -1; | ||
| + | } | ||
| + | s2togglehandle(*id); | ||
| + | } | ||
| + | </pre></code> | ||
| - | // turn on blending | + | 2. in the standard dynamic callback, set the camera position if required | 
| - | glEnable(GL_BLEND); | + | XYZ *iP; // array storing positions of all handles | 
| - | glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); | + | <code><pre> | 
| - | + | void callback(double *t, int *kc) { | |
| - | // draw a transparent orange quad | + | // ... | 
| - | glBegin(GL_QUADS); | + | if (camfollow >= 0) { | 
| - | glColor4f(0.8, 0.3, 0.0, 0.5); | + | // a. fetch current camera position, up and view direction vectors | 
| - | glVertex3f(-3., -3., -3.); | + | XYZ position, up, vdir; | 
| - | glVertex3f(-3., 3., -3.); | + | ss2qc(&position, &up, &vdir, 1); | 
| - | glVertex3f( 3., 3., -3.); | + | // b. calculate new right vector | 
| - | glVertex3f( 3., -3., -3.); | + | XYZ vright = CrossProduct(vdir, up); | 
| - | glEnd(); | + | // c. calculate new view direction vector | 
| - | + | vdir = VectorSub(position, iP[camfollow]); | |
| - | // restore the state | + | Normalise(&vdir); | 
| - | glPopAttrib(); | + | // d. calculate new up vector and set new camera position | 
| + | up = CrossProduct(vright, vdir); | ||
| + | ss2sc(position, up, vdir, 1); | ||
| + | } | ||
| + | // ... | ||
| } | } | ||
| </pre></code> | </pre></code> | ||
Current revision
[edit]
How to follow an object with the camera
Using handles, you can easily detect when an object has been right-clicked. With two pretty simple bits of code, you can then make the camera keep focussed on that object.
1. use a handle callback to register the most recently selected handle:
int camfollow; // initialised to -1 in main
unsigned char *selected; // array storing selected state of all handles
void pickcb(int *id) {
  // ...
  // toggle state:
  selected[*id] = (selected[*id] + 1) % 2;
  if (selected[*id]) {
    camfollow = *id;
  } else {
    camfollow = -1;
  }
  s2togglehandle(*id);
}
2. in the standard dynamic callback, set the camera position if required XYZ *iP; // array storing positions of all handles
void callback(double *t, int *kc) {
  // ...
  if (camfollow >= 0) {
    // a. fetch current camera position, up and view direction vectors
    XYZ position, up, vdir;
    ss2qc(&position, &up, &vdir, 1);
    // b. calculate new right vector
    XYZ vright = CrossProduct(vdir, up);
    // c. calculate new view direction vector
    vdir = VectorSub(position, iP[camfollow]);
    Normalise(&vdir);
    // d. calculate new up vector and set new camera position
    up = CrossProduct(vright, vdir);
    ss2sc(position, up, vdir, 1);
  }
  // ...
}
						
			
		