I apologize for the inconvenience, but all of my internal links are broken, due to my Wordpress installation being compromised, as indicated by my host NameCheap.

I do have a backup of everything, so nothing was lost.  To be on the safe side, however, I'm not restoring WordPress in it's entirety; instead deciding to start from scratch in the hopes that whatever weakness was there, in an installed theme or plugin, will be left behind.

I will at some point get around to restoring all of the links, and in the mean time will do a little cleaning up.  I also have some new projects I'll be making posts about, including an open source tool I'm starting up for game developers like myself.  Good night all. *salute*

Gameloft

I'm going to be a programmer at Gameloft's new studio in New Orleans!! :D I've lived on my own in Troy, NY, for 6 months on a co-op with 1st Playable Productions.  This time, I'll be much farther away from home, and for a much longer period of time.  So, this will be pretty exciting, and I'll be working on a variety of mobile games for Android and iOS! I start December 1st, wish me luck.

The sake of this post is going to be steps I've personally learned to take in optimizing a function, so please feel free to fill me in on something I don't know, add further comments or ask questions. I'm still an aspiring programmer, and thought it would be cool to have a "full fledged" math library that I could tie into my game engine that's cross-platform in nature.  As such, I thought if I ever needed my own data type, it would be useful to be able to perform mathematical operations on it, which means I might need my own math library; of course I could try converting to a format supported for the hardware, as it'd typically be faster, but at this point I'm more concerned about learning what goes on behind the math library.  And for whatever reason, if you needed a higher precision, then you'd need a custom math library anyway.

So, recently I started looking up how to program a sin function; I didn't find much, but I did find a Wikipedia article that detailed a mathematical model for sin, which you can find here: Trigonometric functions - Series definitions.  You can view the function below:

Now I'm going to write this function in C++, and the main question we're looking at here is: How do I go about optimizing a function?(Not so much concerned about language semantics as basic fundamentals you should try to apply in just about any language) Here's the function quickly typed up, notice I chose to write it as an iterative function than as a recursive function.  A recursive function will always be slower than an iterative function, which are not the details of this post, but it has to do with the stack and storing return variables and unwrapping the stack, etc.

  1. Try to always write your performance function as an iterative function rather than a recursive one.
// size_t n, is the number of loops; the higher number of loops, the higher the precision
template <class T>
inline T MathUtil<T>::Sin(const T& val, const size_t n)
{
	T num = val;

	for(size_t i = 1; i <= n; ++i)
	{
		size_t odd = 2 * i + 1;

		// Factorial is written elsewhere
		num += powf(-1, i) * powf(val, odd) / Factorial(odd);
	}

	return num;
}

Which you could use like this:

double result = Sin<>(1.0,12);
// or:
result = Sin<double>(1,12);

So this is a very simple function, and in release mode runs close to what the real thing does.  Here's the results in debug: my sin: 3.57916ms std sin: 0.346908ms   If you look back to the image, you'll see (-1)^n.  This function merely alternates the addition and subtraction of our function, which can be simplified to this:

// size_t n, is the number of loops; the higher number of loops, the higher the precision
template <class T>
inline T MathUtil<T>::Sin(const T& val, const size_t n)
{
	T num = val;

	for(size_t i = 1; i <= n; ++i)
	{
		size_t odd = 2 * i + 1;

		// Factorial is written elsewhere
		if(i % 2 == 0)
		{
			num += powf(val, odd) / MathUtil::Factorial(odd);
		}
		else
		{
			num -= powf(val, odd) / MathUtil::Factorial(odd);
		}
	}

	return num;
}

This results in new times (remember, times will vary): my sin: 2.68451ms std sin: 0.348312ms Notice this does help our performance, though it's frankly a minimal change.  There are a few more things we can simplify out that are crucial, we're redoing the factorial calculations, as well as the power calculations every loop.  We can add these operations up through the loop.  Look back to the image, you'll notice as we through the loop, we'll start with 1!, then 3!, then 5!.  We're iterating through odd numbers, and we can compound the operations as 5! contains 3!: 5 * 4 * 3!.  3! contains 1!: 3 * 2 * 1!.  So we just need to have a variable to store the factor total, and the number we're currently on; multiply the stored total by the number - 1 and the number, as shown before.  Again, if we're in the loop at number 7, then we have 5! stored from the previous loop, multiply that by 6 then by 7.  In the next loop 7! x 8 then by 9.  Etc.  We can also do this with the odd exponent.  We now have the new function below.

// size_t n, is the number of loops; the higher number of loops, the higher the precision
template <class T>
inline T MathUtil<T>::Sin(const T& val, const size_t n)
{
	T num = val;

	size_t factNum = 3;
	size_t factTot = 1;

	T mult = val;

	for(size_t i = 1; i <= n; ++i, factNum += 2)
	{
		mult *= -val * val;

		factTot *= factNum - 1;
		factTot *= factNum;

		num += mult / static_cast<T>(factTot);
	}

	return num;
}

So we got rid of the factorial and power functions all together. So this is something you want to keep in mind when trying to make functions faster, try to minimize your function calls as much as possible, I chose "val * val" instead of "pow(val,2)" for this reason. You remember how we have to alternate adding and subtracting over the odd numbers? I do this by negating val and storing it in the variable mult which will flip sign every loop, doing just what I wanted; this is better than the first two solutions. Here's the results: my sin: 0.586781ms std sin: 0.351613ms

  1. Minimize function calls as much as possible, get rid of any that you can.  

And as we already started to do...

  1. Try to simplify the mathematical operations, using any tricks based off of patterns and mathematical properties you notice.

Anything else we can do? Look back at the image of our functions and refer to some of the variables we're now using. We're trying to simplify the exponential and factorial calculations using a factorial total and mult for the exponential totals. As we're using multiplication, we can concatenate the results from an earlier part of the equation and use it for a later one so we have to do less calculations.

// size_t n, is the number of loops; the higher number of loops, the higher the precision
template <class T>
T Sin(const T val, const size_t n)
{
	const T val2 = -val * val;

	T num = val;

	T mult = val;

	size_t factTot = 1;

	const size_t odd = 2 * n + 1;
	for(size_t f = 3; f <= odd; f += 2)
	{
		mult *= val2;

		factTot *= f - 1;
		factTot *= f;

		num += mult / static_cast<T>(factTot);
	}

	return num;
}

I'm still looking into other ways to improve this function, but this is all of what I have thus far.  Notice I moved "-val * val" to it's own variable so it's doing one less negation and multiplication every loop of the algorithm; it doesn't affect t he performance that much, but it's something that seems to me should be done.  I'm currently reading this paper on Optimizing C++, which I highly suggest you give it a read, as well as consider reading this site on Writing Efficient C.  You'll notice that in Optimizing C++ they mention that it's a performance hit to switch between integers and floats, however, the extra time in the algorithm to calculate factTot and f as the float calculations override that performance concern, so what I have above is the best way from what I've tried, by casting factTot to double, or whatever type you're using, and dividing it by mult. The following is the test code I used to generate my results:

Benchmark std = Benchmark();
for(int i = 0; i < 100000; ++i)
{
	std.Start();
	double result6 = sin(1.0);
	std.Stop();
}
Sleep(50);
for(int i = 0; i < 100000; ++i)
{
	std.Start();
	double result6 = sin(1.0);
	std.Stop();
}
Sleep(100);
for(int i = 0; i < 100000; ++i)
{
	std.Start();
	double result2 = sin(1.0);
	std.Stop();
}

sTrace(make_string() << "std    Sin:" << std.Get_AvgMicroSeconds() << "ms");
sTrace(make_string() << "std MinSin:" << std.Get_MinMicroSeconds() << "ms");
sTrace(make_string() << "std MaxSin:" << std.Get_MaxMicroSeconds() << "ms");

Benchmark mys = Benchmark();
for(int i = 0; i < 100000; ++i)
{
	mys.Start();
	double result6 = Sin<double>(1,6);
	mys.Stop();
}
Sleep(50);
for(int i = 0; i < 100000; ++i)
{
	mys.Start();
	double result6 = Sin<double>(1,6);
	mys.Stop();
}
Sleep(100);
for(int i = 0; i < 100000; ++i)
{
	mys.Start();
	double result6 = Sin<double>(1,6);
	mys.Stop();
}

sTrace(make_string() << "my    Sin:" << mys.Get_AvgMicroSeconds() << "ms");
sTrace(make_string() << "my MinSin:" << mys.Get_MinMicroSeconds() << "ms");
sTrace(make_string() << "my MaxSin:" << mys.Get_MaxMicroSeconds() << "ms");

What the results show you is the average run-time, the minimum run-time, and the maximum run-time during my benchmarks.  Here is my first set of results in debug x64:

std    Sin:0.15552ms
std MinSin:0ms
std MaxSin:61.4676ms

my    Sin:0.194272ms
my MinSin:0ms
my MaxSin:61.4675ms

Here is my second set of results in debug mode x64:

std    Sin:0.154726ms
std MinSin:0ms
std MaxSin:48.567ms

my    Sin:0.192029ms
my MinSin:0ms
my MaxSin:55.7761ms

Here is a result from a release build x64:

std    Sin:0.0923657ms
std MinSin:0ms
std MaxSin:48.9464ms

my    Sin:0.0920976ms
my MinSin:0ms
my MaxSin:24.2835ms

Here the next result from the same release build x64:

std    Sin:0.0919509ms
std MinSin:0ms
std MaxSin:4.55315ms

my    Sin:0.0920293ms
my MinSin:0ms
my MaxSin:10.624ms

Result from release build x32:

std    Sin:0.190925ms
std MinSin:0ms
std MaxSin:184.78ms

my    Sin:0.187989ms
my MinSin:0ms
my MaxSin:173.777ms

Result from the same release build x32:

std    Sin:0.183714ms
std MinSin:0ms
std MaxSin:25.4215ms

my    Sin:0.183407ms
my MinSin:0ms
my MaxSin:77.0233ms

Just as a disclaimer, for those of you who don't know, these kind of benchmarks aren't an end-all be-all of determining what is or isn't better.  Also, my benchmark util has it's own overhead so your own results may be different if you compare algorithms, though the results should be comparatively similar.  And, obviously these functions didn't take 0ms, it has to do with the accuracy of the timer, which uses the Windows function QueryPerformanceCounter and QueryPerformanceFrequency, which I've read are accurate only to 1ms and these measurements are smaller than that.  I'm running an Intel Core i7 920 and during these tests was clocked at just 2.8322GHz. It seems this algorithm runs close enough to the standard solution, however, keep in mind that depending on the hardware you're using that the standard function could be calculated using hardware and could be even faster; unless of course my build is already doing that, then I'd be impressed at how well this algorithm is running.  You can also use this algorithm with smaller precision Sin<double>(1,3) instead of Sin<double>(1,6).  In case you couldn't gather, the first number is the number we're taking the sin of; and the second number represents the amount of looping being done to increase the precision, so the higher the number the higher the precision.  Realize however, there is a point where these floating point calculations won't be accurate due to the limitations of double and float.  There should be a function to calculate the level of precision necessary for each data type for this algorithm, I just don't have it at my fingertips at the moment.  Frankly these numbers start to not mean too much as it's hard to get accurate results, but this was more of an academic goal than anything, so it's up to you if you'd find something like this useful.  Honestly, this endeavor was so I could learn how to program a sin and cos function so I can program a compile time version which has no run time costs; it has limited uses, but is still something that is cool and useful.  I'll detail this in a later post, but for now, here's the cos version of this algorithm, which builds off of even numbers instead of odd numbers.

// size_t n, is the number of loops; the higher number of loops, the higher the precision
template <class T>
T Cos(const T val, const size_t n)
{
	T cosResult = 1;

	size_t factorialTotal = 1;

	T multiplicationTotal = 1;

	const T val2 = -val * val;

	const size_t even = 2 * n;
	for(size_t f = 2; f <= even; f += 2)
	{
		multiplicationTotal *= val2;

		factorialTotal *= f - 1;
		factorialTotal *= f;

		cosResult += multiplicationTotal / static_cast<T>(factorialTotal);
	}

	return num;
}

This is used similarly to the sin function, Cos(1,6) or Cos<>(1.0,6).   I have done everything I sought out to do with this post, and I'll continue to experiment and see if I come up with anything else while doing more reading on C++ optimization, thinking if there are other algorithmic shortcuts I can make (Yes I realize there wasn't tooo much optimization I did here, it was merely doing what I needed to, to reduce the factorial calculations and other multiplication.  Also, again, these basic steps for optimization are general things to keep in mind. ).  I'll post updates when I find something, or if you have something you'd like to contribute please feel free, this is a good learning opportunity for all of us! (: [UPDATE - 11/9/2011] I forgot how large factorial results could get, and recently realized that as I'm compiling for Win32, size_t won't get me far for storing said results.  So, rather than just changing it to a long long or something, I'm changing it to be the same datatype as specified by the template, even if it means a little calculation cost time of not using integers.  Actually, if I used a custom datatype with a large precision, I would need to do this anyway, otherwise the function wouldn't be very precise. Anyway, this update comes as I somehow stumbled across this site:  super fast trig functions.  And a disclaimer for this thread, they're not really any faster than the built in solution unless you are willing to lose precision, which the specified functions don't specify as they loop until "INFINITY".  If you want super fast trig functions, you should look into something like Cordic functions, as mentioned in the Game Engine Gems 1, the important part being that you only need to use integers to calculate sin; though of course, it's an approximation, and there are other integer based methods besides this one as well if you do a little digging. So, here's the final sin function with the little tweaks:

template <class T>
T Sin(const T val, const T n)
{
	const T val2 = val * val;

	T num = val;

	T mult = val;

	T factTot = 1;

	const T odd = 2 * n + 1;
	for(T f = 3; f <= odd; f += 2)
	{
		mult *= -val2;

		factTot *= f * (f - 1);

		num += mult / factTot;
	}

	return num;
}

I realized from reading the mentioned thread on super fast trig functions, that I can cut a few things out of my function. I'm maintaining a variable for storing the exponents and the factorial results, which can both be cached in a single variable with the risk of the loss of a little precision, which isn't a big deal from what I've tested; actually, it still provides pretty accurate results.

template <class T>
T Sin(const T val, const T n)
{
	const T val2 = -val * val;

	T num = val;

	T expDivFact = val;

	const T odd = 2 * n + 1;
	for(T f = 3; f <= odd; f += 2)
	{
		expDivFact = expDivFact * val2 / (f * (f - 1));

		num += expDivFact;
	}

	return num;
}

So, the above Sin function is probably the fastest using the theory of Taylor series; though of course there might be other tweaks one could make.   If you want something faster look into this: CORDIC.

Just a shoutout, I'm not dead, just trying to figure out things in my life!  I'm working on a blogpost concerning a multi-threaded load balancing server, am re-organizing and working more on my Warp engine, though with starting anew I may rename the engine and lead it in a slightly different direction.

Concerning what I'm trying to figure out: I had lost hope in going to gradschool given that I would be in debt for a ridiculous amount of money with my combined debt from undergrad and the cost of the program as well as the cost of living.  However, financial aid may save me, maybe.  I was planning on applying to various game development companies, but I'm not going to say as to not hurt my chances. ;P  Even with the possibility of financial aid saving me, I've grown a bit fond of the idea of getting a job now, as there's going to be a lot more competition in 2 years from all the new game development programs that have popped up.  So, maybe I will just try getting a job in the industry, as it'll be harder down the line.

I just bought Masters of Doom, and I must say it's quite good thus far.  The book concerns the two Johns, John Carmack, and John Romero, the founders of Id Software, the creator's of Doom, and pioneers of the First Person Shooter (otherwise known as the FPS, for those of you who don't know).  So, important guys.  I've found it interesting and comforting to know that both of them at my age hadn't quite settled down yet, so I still have some time. ;p  Just graduating, and the condition of the job market, I can't help but feel a little anxious.  I would also like to point out that this book is so far quite inspiring, and as the fire of my passion has been a bit lacking in fuel, this is re-ignited it a bit.  So I must say I'm glad I picked up this book! :)

I'm possibly starting a new project, though thinking about the undertakings I'm planning on scaling it back a bit.  Essentially I'm looking into creating a Farscape fan-game, mainly for educational purposes, at this point anyway.  The Farscape game that was made, was a let down to fans, it seems.  As such, I wanted to take a stap at it, modeling the game after Mass Effect and the Star Wars role-playing games, possibly bringing the game into an MMO form.  I've been doing networking lately, and would love to setup the possibility of players running dedicated servers and having a Farscape universe that they could sculpt and explore.  Of course, the reason I want to scale back, is that I realize there is a lot of content creation that would be needed; and right now the art assets needed for the game, are too great in magnitude to make this feasible with the small number of people that would originally be involved.  If anything, I'm going to start by making a tech-demo of sorts and using it to attract people who want to devote time and effort to the project.  You can find a thread concerning project ideas here: Farscape video game? We're trying to gather ideas, so please feel free to post there or on this page! :D

 

Anyway, I'm working on designing an interface for my networking solution, then reprogramming the backend so a server can support more users, and use the appropriate Windows functions to calculate how many connections can be supported on a port.  So, I'll be messing around with lots of C++ networking, and doing research and coming up with ideas for how to deal with security issues that may arise.  Look forward to more details!

This class should have been posted long ago.  So, seeing how popular my C++ Vector2 class page has been, I've decided to finally post this for your needs.  This version is similar to the "improvements" on the Vector2 class, supposedly helping encapsulation; frankly, that's up for you to decide.

 

Remember, you can hover over the source area and click the "<>" looking image (top right) to pop the source code into a new window to more easily view and copy the code.

Vector3.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_Vector3
#define w_Vector3

#include <cmath>

namespace _Warp
{
	typedef float	Scalar;
	typedef int		Bool;

	class Vector3
	{
	public:
		Scalar X;
		Scalar Y;
		Scalar Z;

		Vector3();
		Vector3(Scalar x, Scalar y, Scalar z);

		Vector3		operator+(const Vector3&amp; vector) const;
		Vector3		operator-(const Vector3&amp; vector) const;
		Vector3		operator-() const;
		Vector3		operator*(Scalar num) const;
		Vector3		operator/(Scalar num) const;

		Vector3&amp;	operator+=(const Vector3&amp; vector);
		Vector3&amp;	operator-=(const Vector3&amp; vector);
		Vector3&amp;	operator*=(Scalar num);
		Vector3&amp;	operator/=(Scalar num);

		Bool		operator==(const Vector3&amp; vector) const;
		Bool		operator!=(const Vector3&amp; vector) const;

		static const Vector3 Zero;
		static const Scalar	Epsilon;
	};

	inline Bool Vector3::operator==(const Vector3&amp; vector) const
	{
		return X == vector.X &amp;&amp; Y == vector.Y &amp;&amp; Z == vector.Z;
	}

	inline Bool Vector3::operator!=(const Vector3&amp; vector) const
	{
		return X != vector.X || Y != vector.Y || Z != vector.Z;
	}

	inline Vector3 Vector3::operator+(const Vector3&amp; vector) const
	{
		return Vector3(X + vector.X, Y + vector.Y, Z + vector.Z);
	}

	inline Vector3 Vector3::operator-(const Vector3&amp; vector) const
	{
		return Vector3(X - vector.X, Y - vector.Y, Z - vector.Z);
	}

	inline Vector3 Vector3::operator-() const
	{
		return Vector3(-X,-Y,-Z);
	}

	inline Vector3 Vector3::operator*(Scalar num) const
	{
		return Vector3(X * num, Y * num, Z * num);
	}

	inline Vector3 Vector3::operator/(Scalar num) const
	{
		return Vector3(X / num, Y / num, Z / num);
	}
}
#endif

Vector3.cpp:

#include "Vector3.h"

#include <limits>

namespace _Warp
{
	const Vector3 Vector3::Zero = Vector3(0,0,0);
	const Scalar Vector3::Epsilon = std::numeric_limits::epsilon();

	Vector3::Vector3()
	{
	}

	Vector3::Vector3(Scalar x, Scalar y, Scalar z)
		: X( x )
		, Y( y )
		, Z( z )
	{
	}

	Vector3& Vector3::operator+=(const Vector3& vector)
	{
		X += vector.X;
		Y += vector.Y;
		Z += vector.Z;
		return *this;
	}

	Vector3& Vector3::operator-=(const Vector3& vector)
	{
		X -= vector.X;
		Y -= vector.Y;
		Z -= vector.Z;
		return *this;
	}

	Vector3& Vector3::operator*=(Scalar num)
	{
		X *= num;
		Y *= num;
		Z *= num;
		return *this;
	}

	Vector3& Vector3::operator/=(Scalar num)
	{
		this-&gt;X /= num;
		this-&gt;Y /= num;
		this-&gt;Z /= num;
		return *this;
	}
}

Vector3Util.h

/*  __      __   ___     _____    ____
 *  \ \    / /  / _ \   |  __ \  |    |
 *   \ \/\/ /  / / \ \  | | / /  |  __|
 *    \_/\_/  /_/   \_\ |_| \_\  |_|
 *      Take it to the next Level
 *
 *  Copyright (c) 2009 Brian Ernst.
 */

#ifndef w_Vector3Util
#define w_Vector3Util

#include "Vector3.h"

// These two files are not detailed out in this blog post.
#include "Quaternion.h"
#include "TMatrixUtil.h"

namespace _Warp
{
	Scalar len(const Vector3& vect);
	Scalar len2(const Vector3& vect);

	void Clamp(Vector3& vect,Scalar length);
	void Normalize(Vector3& vect);
	void Normalize_s(Vector3& vect);
	void SetLength(Vector3& vect, Scalar length);
	void SetLength_s(Vector3& vect, Scalar length);

	Scalar	Dot(const Vector3& vec1, const Vector3& vec2);
	Scalar	GetAngle(Vector3 vec1, Vector3 vec2);

	Vector3	ToNormalized(const Vector3& vect);
	Vector3	ToNormalized_s(const Vector3& vect);
	Vector3	ToPolar(Scalar x, Scalar y, Scalar z);
	Vector3	ToCartesian(Scalar radius, Scalar angle, Scalar z);
	Vector3	Cross(const Vector3& vec1, const Vector3& vec2);
	Vector3	Rotate(const Vector3& vec1, Scalar angle, const Vector3& axis);

	Vector3 ToEuler(Vector3 axis, Scalar angle);

	inline Scalar len(const Vector3& vect)
	{
		return sqrt(vect.X * vect.X + vect.Y * vect.Y + vect.Z * vect.Z);
	}

	inline Scalar len2(const Vector3& vect)
	{
		return vect.X * vect.X + vect.Y * vect.Y + vect.Z * vect.Z;
	}

	inline void Normalize(Vector3& vect)
	{
		vect /= len(vect);
	}

	inline void SetLength(Vector3& vect, Scalar length)
	{
		vect *= length / len(vect);
	}

	inline Scalar	Dot(const Vector3& vec1, const Vector3& vec2)
	{
		return vec1.X * vec2.X + vec1.Y * vec2.Y + vec1.Z * vec2.Z;
	}

	inline Vector3 ToNormalized(const Vector3& vect)
	{
		return vect / len(vect);
	}

	// This uses a Quaternion combined with the Matrix Utility, neither of which are detailed out in this post.
	inline Vector3	Rotate(const Vector3& vec1, Scalar angle, const Vector3&amp; axis)
	{
		return TransformCoord(Quaternion::FromAxis(axis.X,axis.Y,axis.Z,angle).Get_RotationMatrix(),vec1);
	}

	inline Vector3	ToPolar(Scalar x, Scalar y, Scalar z)
	{
		return Vector3(
			atan2(y,x),
			sqrt(x * x + y * y),
			z);
	}

	inline Vector3	ToCartesian(Scalar radius, Scalar angle, Scalar z)
	{
		return Vector3(
			radius * cos(angle),
			radius * sin(angle),
			z);
	}

	inline Vector3	Cross(const Vector3& vec1, const Vector3& vec2)
	{
		return Vector3(
			vec1.Y * vec2.Z - vec1.Z * vec2.Y,
			vec1.Z * vec2.X - vec1.X * vec2.Z,
			vec1.X * vec2.Y - vec1.Y * vec2.X);
	}
}

#endif

Vector3Util.cpp

#include "Vector3Util.h"

#include "../Constants.h"

namespace _Warp
{
	void Clamp(Vector3& vect,Scalar length)
	{
		Scalar vecLength = len2(vect);

		if(vecLength &lt;= length * length)
		{
			return;
		}

		vect *= length / sqrt(vecLength);
	}

	void Normalize_s(Vector3& vect)
	{
		Scalar vecLength = len2(vect);

		if(vecLength == 0)
		{
			return;
		}

		vect /= sqrt(vecLength);
	}

	void SetLength_s(Vector3& vect, Scalar length)
	{
		Scalar vecLength = len2(vect);

		if(vecLength == 0)
		{
			return;
		}

		vect *= length / sqrt(vecLength);
	}

	inline Scalar	GetAngle(Vector3 vec1, Vector3 vec2)
	{
		if(vec1 == vec2)
		{
			return 0.0f;
		}

		Normalize_s(vec1);
		Normalize_s(vec2);

		Scalar dot = Dot(vec1, vec2) / (len(vec1) * len(vec2));

		dot = dot > 1.0f ? 1.0f : ( dot < -1.0f ? -1.0f : dot );

		return std::acos(dot);
	}

	Vector3 ToNormalized_s(const Vector3& vect)
	{
		Scalar vecLength = len2(vect);

		if(vecLength == 0)
		{
			return vect;
		}

		vecLength = sqrt(vecLength);

		return Vector3(vect.X / vecLength, vect.Y / vecLength, vect.Z / vecLength);
	}

	// Thanks to Martin Baker for this solution
	// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToEuler/index.htm
	Vector3 ToEuler(Vector3 axis, Scalar angle)
	{
		Vector3 out = Vector3();

		Scalar s = sin(angle);
		Scalar c = cos(angle);
		Scalar t = (Scalar)1.0 - c;

		if ((axis.X * axis.Y * t + axis.Z * s) > (Scalar)0.998)// north pole singularity detected
		{
			out.Y = 2 * atan2(axis.X * sin(angle/2), cos(angle/2));
			out.Z = static_cast<Scalar>(W_PI_2);
			out.X = 0;
			return out;
		}
		if ((axis.X * axis.Y * t + axis.Z * s) < (Scalar)-0.998)// south pole singularity detected
		{
			out.Y = (Scalar)-2.0 * atan2(axis.X * sin(angle / (Scalar)2.0), cos(angle / (Scalar)2.0));
			out.Z = -static_cast<Scalar>(W_PI_2);;
			out.X = 0;
			return out;
		}
		out.Y = atan2(axis.Y * s - axis.X * axis.Z * t , 1 - (axis.Y * axis.Y + axis.Z * axis.Z ) * t);
		out.Z = asin(axis.X * axis.Y * t + axis.Z * s) ;
		out.X = atan2(axis.X * s - axis.Y * axis.Z * t , 1 - (axis.X * axis.X + axis.Z * axis.Z) * t);
		return out;
	}
}

You'll notice in the Vector3Util I have some functions ending with "_s", like "Noramlize_s"; this is a notation I'm trying to mean, in this case, a safe normalize function call (won't result in a divide by zero error).  So, if you know the vector you're using can't possibly be zero, use the standard Normalize function, if not, then feel free to use Normalize_s.  Please let me know if you have a comment on the notation!

Anyway, this Vector3 class and utility are code I use in my personal game development, and in other school projects that I may have, and have used it and my personal math libs in a ray tracer.  Concerning the util, I'm still tweaking it, making decisions on how to wrap it in a namespace (like it's own _Math namespace, which was taken out for this post), or perhaps on whether I feel I really need a separate util instead of having them as member functions, which would be more convenient with intellisense at hand. If you're wondering what I'm talking about, check out this article at Dr Dobbs on encapsulation.  I personally have to give it another read and determine if I agree with it or not and really want to stick with that methodology.

 

Please leave your thoughts and suggestions!
[I'll be uploading the upgraded version of this Vector3 class sometime soon, I realize there are parts of this version that may be a little rough/unfinished, and after that I'll include the source files for you to download]

Archive