Camera code

Member
Posts: 45
Joined: 2002.04
Post: #1
I am in the process of writing some camera functions for my terrain editor so i can uh actually move around and edit things... Rasp

anyways, right now I am just writing a simple trig based camera system, I figure I won't need much else, but my concern is speed.. trig functions are a big hit when you them them over and over again..

as of now I have a rotation function that performs simple calls to cosine and sine functions. I get hicups in the drawing, ie: when I have a key pressed it is not a continously updated movement it is stilted and I must keep re-pressing the key to move..

this is not an issue with key repeating, i have my GLUT environment setup to handle key repeating.. I have a feeling it is an issue with the trig functions since it does the same thing when I use the mouse to do the rotation..


I do not really want to get into rotational, and translational matrices yet.. my brain is already on over drive trying to learn Cocoa, OGL & GLUT... if I can avoid having to "re-learn" their use for a while the better..

any ideas on this?

anyways I am off to bed..

Hank-

/* Drunk...... fix later.... */
Quote this message in a reply
Member
Posts: 268
Joined: 2005.04
Post: #2
Have you used a profiler like Shikari (the CHUD tools) on your code yet? Trig functions like sin and cos really shouldn't be slowing down your code that much. Most likely something else is the culprit.
Quote this message in a reply
furballphat
Unregistered
 
Post: #3
If you do need to do a lot of the same trig function again, you could always make a lookup table. Write all the trig values into a big array and just read them off there. That should give a small speedup.
Quote this message in a reply
Tycho
Unregistered
 
Post: #4
My guess is that the problems with smoothness come from using key repeating. When you use key repeating, you don't get a keydown event every frame, only every fifth of a second or something like that.

You really should re-learn matrices. When you call trig functions for every vertex, you are actually using the same values every time. A matrix is really just a way of cacheing(sp?) those values.
Quote this message in a reply
Member
Posts: 177
Joined: 2002.08
Post: #5
You mean he should use GL transformations Rasp

The camera movement should be changed from "update once when a key event is received" to a system that starts a repeating timer or loop when a key-down event is received, and stops repeating when a key-up is received.
Quote this message in a reply
lpetrich
Unregistered
 
Post: #6
You may have to bite the bullet and learn transformation matrices. However, they are not as complicated as they might at first seem, and to get from world to camera coordinates, you need to calculate the appropriate matrices only once per frame.

And as to speeding up trigonometric functions, one can do the trick that the Marathon engine does: create an in-memory trig table. One converts the angle value to an index in that table by multiplying by TRIG_TABLE_SIZE/(2*PI) (radians) or TRIG_TABLE_SIZE/360 (degrees) and then rounding off and finding the remainder after dividing by TRIG_TABLE_SIZE. That latter operation is E-Z is TRIG_TABLE_SIZE is a power of two: one does a bitwise and with (TRIG_TABLE_SIZE - 1)

const int TRIG_TABLE_SIZE_EXP = 9; // Marathon-engine value
const int TRIG_TABLE_SIZE = 1 << TRIG_TABLE_SIZE_EXP;
const int TRIG_TABLE_SIZE_MASK = TRIG_TABLE_SIZE - 1;

inline int FindTrigTableEntry(float AngleDegrees)
{
return (int((TRIG_TABLE_SIZE/float(360))*AngleDegrees) & TRIG_TABLE_SIZE_MASK);
}

Furthermore, if one wishes to improve one's trig-table's range, once can use two tables, one for the high bits and one for the low bits of one's integerized value:

const int TRIG_TABLE_HIGH_BITS = 5;
const int TRIG_TABLE_LOW_BITS = 4;
const int TRIG_TABLE_TOTAL_BITS = TRIG_TABLE_HIGH_BITS + TRIG_TABLE_LOW_BITS;

const int TRIG_TABLE_HIGH_SIZE = 1 << TRIG_TABLE_HIGH_BITS;
const int TRIG_TABLE_LOW_SIZE = 1 << TRIG_TABLE_LOW_BITS;
const int TRIG_TABLE_TOTAL_SIZE = 1 << TRIG_TABLE_TOTAL_BITS;

const int TRIG_TABLE_LOW_SIZE_MASK = TRIG_LOW_TABLE_SIZE - 1;
const int TRIG_TABLE_HIGH_SIZE_MASK = TRIG_HIGH_TABLE_SIZE - 1;
const int TRIG_TABLE_TOTAL_SIZE_MASK = TRIG_TOTAL_TABLE_SIZE - 1;

struct TrigTableEntry
{
short Hi, Lo;
};

inline TrigTableEntry FindTrigTableEntry(float AngleDegrees)
{
int TotalAngle = int((TRIG_TABLE_SIZE/float(360))*AngleDegrees) & TRIG_TABLE_SIZE_MASK;

TrigTableEntry Entry;
Entry.Hi = TotalAngle >> TRIG_TABLE_LOW_BITS;
Entry.Lo = TotalAngle & TRIG_TABLE_LOW_SIZE_MASK;
}

void FindSinCos(TrigTableEntry& Entry, float& S, float& C)
{
float S_Hi = TT_Sin_Hi[Entry.Hi];
float C_Hi = TT_Cos_Hi[Entry.Hi];
float S_Lo = TT_Sin_Lo[Entry.Lo];
float C_Lo = TT_Cos_Lo[Entry.Lo];

// Some familiar trigonometric identities:
S = S_Hi*C_Lo + C_Hi*S_Lo;
C = C_Hi*C_Lo - S_Hi*S_Lo;
}
Quote this message in a reply
Post Reply