Jump to content

  • Log In with Google      Sign In   
  • Create Account


taz0010

Member Since 05 Nov 2008
Offline Last Active Jun 28 2014 10:58 PM
-----

#5036021 make an object that is pointing in a direction rotate to point in another dir...

Posted by taz0010 on 24 February 2013 - 01:15 AM

You have your old and new direction vectors, so the problem is simply a matter of building the rotation matrix to rotate the first vector onto the second. You use the cross and dot product to get the rotation axis and angle.

 

Assuming that oldV and newV are normalised:


axisOfRotation = crossProduct(oldV, newV).normalise(); // Depending on whether your library requires normalised rotation axes

angleOfRotation = arccos(dotProduct(oldV, newV));

 

Whatever library you're using should have a function that builds a rotation matrix from an axis and angle of rotation, so there's no need to manually code a whole bunch of math.




#4996175 Calculating angles of rotation

Posted by taz0010 on 01 November 2012 - 07:32 AM

I'd do it like this:

1) Project the destination vector onto the XZ axis. Do this simply by setting the y component to zero. The projected vector will no longer be normalised.
2) Get the angle between the object's vector and the vector resulting from 1), and rotate around the y axis by this amount.
3) Now you can rotate your object onto the destination vector using the method outlined earlier in this thread (cross product vectors to get rotation axis, dot product to find angle). This will cause the object to point at the destination vector without any undesired rotation along the object's local x axis.


#4989963 Bit Flags vs. Boolean

Posted by taz0010 on 13 October 2012 - 09:26 PM

One thing to keep in mind is that accessing bit fields will require the compiler to produce additional bit masking instructions, which will *increase* the memory footprint of your instruction code. If you try to use bit fields as a general rule instead of a situational optimisation, you'll end up with slower code.

Also, the alignment issues are subtle. Most types want to align on 4 byte boundaries, so AFAIK if you have a structure containing, say, an integer, and any less than 5 flags, then converting these flags to single bits won't save any space at all.


#4987326 Is that way of using constructor really better ?

Posted by taz0010 on 05 October 2012 - 11:40 PM

Most modern compilers will optimize the trivial stuff. So I only stick important things (large items, parent classes, references, ect...) in the initializer list, as I really don't like them. My big issue is that the order items are initlialized in the initializer list is not the same order as they are listed. Which for dependent items can really lead to some hard to track down bugs.


Why is this being voted down? His gripe about the initialiser list order not being the actual initialisation order is perfectly valid. It's intuitive to assume that the variables are going to be initialised in the order that the initialisation code is written - which is exactly the case whenever you initialise something using the equals sign.

Also mentioned in this topic, ordering your members for alignment or caching reasons can potentially break your code if one member was initialised using the value of another. And since headers are used, the potential error will not even be visible in the file where the initialisation code is actually written.

Personally if I have primitive variables that I need to initialise in a specific order, I'm not going to rely on the class definition order to do it, and that means good old fashioned assignment with the = operator.


#4902536 c++ : Deleting object (not just its pointer) from vector

Posted by taz0010 on 13 January 2012 - 08:16 PM

You always need to read the documentation to make sure you aren't causing memory leaks when using API functions. Functions with "create" in their name typically allocate memory, and functions with "get" sometimes increment reference counts. The documentation will tell you if you need to call the corresponding "free" or "release" functions.


#4892748 Any overhead when inheriting from class with only static members?

Posted by taz0010 on 11 December 2011 - 04:30 AM

The compiler should skip v-table generation if a class has no virtual functions. Compile your project with optimisations on and check the assembly code. This is the only way to ensure that the desired "micro optimisations" are actually being performed.


#4884154 static Vector in a GameObject Class

Posted by taz0010 on 15 November 2011 - 07:27 AM

Global state (which is what we're talking about - not necessary global variables) makes sense when you're dealing with some sort of restriction imposed from outside your software entirely. For example, in the Windows API there are some functions that need to be called before certain functions are usable. The initialisation function only needs to be called once per *process*, so I emply a "construct on first use" system where the first class instance created will call the initialisation function, and set a static variable so future instances of the class don't duplicate the function call.

This does not violate encapsulation principles because the operation is hidden from outside the class, and has no bearing on the result of any publically accessable function calls on the instance. So you can construct any number of these objects and use them, and it doesn't matter which object did something special in response to global state as they all behave the same from the perspective of the calling code.




#4884147 Poll: if () with single inner statement. What do you do? What do you do?

Posted by taz0010 on 15 November 2011 - 07:01 AM

Indentation is such a powerful tool for showing code structure that including the braces is not necessary and simply wasted space. And, as pointed out already, coding IDEs these days will indent automatically, so when you add a second line to a single statement IF without braces, the lack of indentation is an immediate tipoff. I always put the closing brace on it's own line for multiple statement blocks, so any incorrect omission of braces is immediately apparent.


if(condition){
   Action();
   Action2();
}
AlwaysExecuted();

if(condition)
   Action();
   Action2();             <-- Oh oh! Where's the closing } ? Better add one now!
AlwaysExecuted();


I don't think I've ever seen a block of code above and not immediately thought "It's missing braces", for the simple reason that it doesn't match my coding style so I can see it's not what I indented to do at first glance.




#4883700 Poll: if () with single inner statement. What do you do? What do you do?

Posted by taz0010 on 14 November 2011 - 02:05 AM

I don't use { } unless I have to. Space is a valuable commodity and the last thing I want is for a function to scroll off the page because half of the lines are comprised of single braces. I rarely put code on the same line as the conditional though. I find that it makes the code a little harder to read, while omitting the braces and always - always indenting, provides more than enough clarity.

But I love binary IF as it's amazing for writing concise code. A somewhat contrived example, but;

if(a > b)
{
  x = c;
}
else
{
  x = d;
}

vs:

x = (a > b ? c : d);

8 lines vs 1...





#4883156 static Vector in a GameObject Class

Posted by taz0010 on 12 November 2011 - 12:52 AM

Using static objects in this way is not a very good idea. (See: Global Variables)

You're better off declaring the vector somewhere else and passing the reference in the GameObject constructor. One of the advantages here is you might later on decide you need to create multiple "everything" vectors (more likely than you think), in which case you'll be out of luck if it's a static member.




#4881322 Why not use return type "void"?

Posted by taz0010 on 07 November 2011 - 03:09 AM

Though, speaking strictly from an OOP point of view, having void* userdata pointers is a bit sketchy...

But it definitely is one of those times where it can be useful to bend the rules a bit.

But does c++ offer any alternative at all when it comes to storing data of an unknown type? Seems the cleanest method is to wrap your userdata in a object and cast the void* return value to a pointer to the object. Although I suppose the API could return a pointer to a UserData class, marked pure virtual. Then you could derive from that class to create your user data containers. dynamic_cast would add a layer of safety


#4877159 Good practices: power and log functions

Posted by taz0010 on 26 October 2011 - 06:49 AM

The debug version of MSVC's STL is so inefficient that my debug builds are closer to 100x slower than release. I once stepped through the assembly and counted 5 critical sections just to create an iterator. I know people keep saying not to write your own implementation of the STL, but debugging is getting to be a serious problem.




#4839208 Dynamic memory and very large c++ vectors

Posted by taz0010 on 22 July 2011 - 10:28 PM

Calling push_back inside a loop is generally the slower way of populating a vector, as the function must check that there's enough room, increment counters, etc. Even when you reserve so there's no reallocation, the logic that handles the reallocation case still sits of the control path of push_back, making the function fairly large and not a candidate for inlining.

If you are able to copy all the elements to the vector using it's iterator constructor (takes a begin() and end() iterator), you should do so. The magic of templates allows you to use this constructor to copy elements from a primitive array, which is very convenient and fast.

Otherwise, if the vector type has a trivial default constructor and no destructor, it is efficient to construct the vector with the number of elements you need, then use a loop to copy the actual elements across.

If your classes are complex (allocate memory), then make sure they have move constructors and move assignment operators, which will greatly improve their performance when vectors are concerned.




#4837944 Separating Axis Theorem in 3D between convex polygons

Posted by taz0010 on 20 July 2011 - 07:05 AM

First off, since you're working in 3D, the separating axis is actually a separating plane.

I've been solving a similar problem very efficiently using the following method:

Intersect polygon A with the plane of polygon B, and intersect polygon B with the plane of polygon A. If each plane intersects the other's polygon, then you will have 2 collinear line segments representing the intersection regions. If not then the polygons do not intersect at all, so you can just choose the non-intersecting plane as your separating plane.
Now you need only check whether these line segments overlap to determine if the convex polygons are in intersection. This is similar to the SAT test, except you only have to look at a single axis. The axis in question is given by the cross product of the plane normals, or simply by constructing a vector from the plane-polygon intersection points (although I recommend using the cross product for stability reasons). You can determine the overlap by projecting the intersection points onto this vector.

You can use the line segment as the plane normal and choose a point between the two segments to construct the plane equaltion. If you need a separating axis instead then you'll need to choose an arbitrary vector on the plane. You can just rotate the plane normal (i.e. the line segment) 90 degrees around one of the unit axes, but make sure you don't choose an axis that the normal is already aligned with. The simplest thing to do is find the component of the normal with the smallest absolute value and rotate around the corresponding axis.




#4835878 Floating Point Accuracy

Posted by taz0010 on 15 July 2011 - 08:42 PM

I guess I'm asking, if I multiply A (a float, representing a whole number) by B (a float) and then devide A by B, am I going to get my original number back always?


As long as A, B, and A*B are all representable exactly, then (A * B) / A = B

I'm not sure why you're using floats when you're intending to store integers inside them. FYI casting from a float to an integer is a relatively expensive operation.






PARTNERS