Abstracting multiple math libraries with C++

Alexander Shukaev
  • Abstracting multiple math libraries with C++ Alexander Shukaev

    I would like to create some level of abstraction above math in my code. I mean I don't want to be dependant on the implementation of math operations or even on class names, which are provided by some math library. I will show you a simple example.

    Let's assume that we have 2 math libraries. Let's consider 3D-vector classes:

    Library A has 3D-vector class as "Vector3D" and its method "Subtract".

    Library B has 3D-vector class as "vector3" and its method "subtr".

    Now I want to be able to swtich between these 2 different implementations, but without changing any line of code. For, instance I would like to have it like this:

    My 3D-vector class name will be "vec3" and its method "sub". But behind "vec3" and "sub" it can be implementation from library A or library B, depending on what I choose with 1 line of code in the beginning of program or even on compilation stage.

    In other words it should look like a plugable system for math libraries.

    I think it's about programming patterns here right? It look like delegation or factory. Could make clear for me how to implement this approach and is it worth it?

  • The design pattern you are looking for is the adapter pattern (wikipedia).

    The adapter pattern (often referred to as the wrapper pattern or simply a wrapper) is a design pattern that translates one interface for a class into a compatible interface...

    One way to implement the adapter pattern is to create a generic interface (abstract) for the vector class, and then you could derive classes from it that call the correct functions.

    To switch between the concrete derived classes you could use a typedef. e.g. you would define

    typedef VectorDirectX Vector
    

    or

    typedef VectorOpenGL Vector
    

    and then you would only use Vector in your code. This would only work if you weren't planning on switching Vector classes at runtime.

    If you did need to switch between them at runtime you could use a factory, which would create the required class and return a pointer/reference to the base abstract class.

    In practice for performance reasons I'd rather rely on refactoring tools (e.g. Visual Assist) to rename functions and classes unless I'm working on a massive project or there's a legitimate reason why the classes would need to frequently change.

  • I strongly recommend not to put a layer of abstraction between your application and the math-lib, neither high level factories nor inheritance for different platforms, nor delegation nor similar patterns.

    You want your vector math code as optimized as possible.

    Unfortunetely layers of abstraction that make your design more user-friendly, have massive performance impacts, especially in low level code such as math libraries.

    So what can you do?

    Either use those libraries that do all the dirty work for you like: multi platform implementation, passing vectors via registers rather than the stack if possible, etc:

    1. Sony's vectormath SSE2 and Altivec
    2. Bullet's Linearmath SSE2

    Or use them as the inspiration for your own. Forget about fancy design patterns in this case, here performance is priority No. 1

  • since you are coding with c++ you can use some advance template features like this :

    struct vector3
    {
        void subtr(vector3 p){};
    };
    
    struct vector3D
    {
        void Subtract(vector3D p){};
    };
    
    template <bool t> class Vector3DWrapper{
        vector3D v3d;
    public:
        void subtract(Vector3DWrapper pv) {v3d.Subtract(pv.v3d);};
    };
    
    template <> class Vector3DWrapper<true> {
        vector3 v3;
    public:
        void subtract(Vector3DWrapper pv) {v3.subtr(pv.v3);};
    };
    

    now if you declare some vector from Vector3DWrapper<true> type it'll use all vector3d features and other wise it'll all be Vector3D features, the only thing is that this code will generate errors if want to set some Vector3DWrapper<false> variable to Vector3DWrapper<true> value, but this can also be solved by just implementing cast operators for these classes.

Tags
c++ mathematics architecture
Related questions and answers
  • with the Physics correctly... So my main question is: What would be a good combination of libraries to make an online game with? Im sure that many people have good combinations of libraries for making a game. The libraries that I would need are ones that fit the criteria of making a simple 3d game(online): 3D Graphics(including a model loader of some sort(if it works with blender that would be even...) Also if there are any other libraries that work well with these I would like to know. Any answers would be very helpful. and details would be even nicer =) Thanks in advance. -Molma

  • caps. Sweet. Still, I have some worries regarding possible Field of View and Line of Sight issues. C) The total overhaul variant. Or, I could just create borders and corners as separate containers...After spending time today to jot down some notes regarding the implementation of walls into my tile-based game, I've suddenly realized it's not going to be as simple as I imagined before. While the current stage of my work is not even close to actually making the wall-related code, I've come up with three different ways to do it. Right now I'm unsure which one of my ideas will work best

  • GameSubsystems) can implement registerComponent(Component*). pro. Components and GameSubystems know nothing about each other. con. In C++ it would look like ugly and slow typeid-switch... Components. 3: Component registers itself in GameSubsystem(s). We know at compile-time that there is a GameSubsystemRenderer, so let's ComponentImageRender will call something like...I'm creating a component-based game object system. Some tips: GameObject is simply a list of Components. There are GameSubsystems. For example, rendering, physics etc. Each GameSubsystem contains

  • I want to use a shader just for learning purposes but I have a few questions about it. I have the following code: Vertext shader: const float Eta = 0.66; // Ratio of indices of refraction...? Other thing is the uniform keyword. That means I have to pass a value from my code to my shader right? In this case I have to pass a cubemap. I guess I can figure out how to create one of those... ecPosition = gl_ModelViewMatrix * gl_Vertex; vec3 ecPosition3 = ecPosition.xyz / ecPosition.w; vec3 i = normalize(ecPosition3); vec3 n = normalize(gl_NormalMatrix * gl_Normal); Ratio

  • over-thinking it. If anyone thinks they can help, please take a look at the code below and help me try to improve on this if you can. I would like to refrain from using a library to handle this (as I want to learn on my own) or the something like the SAT (Separating Axis Theorem) if at all possible. Thank you in advance for your help! void world1Level1CollisionDetection() { for(int i; i < blocks... loading, etcetera. I am also using OpenGL via the FreeGLUT library in conjunction with SDL to display graphics. My method of collision detection is AABB (Axis-Aligned Bounding Box), which is really all

  • I've decided I want to write a central ResourceManager/ResourceCache class for my hobby game engine, but am having trouble designing a caching scheme. The idea is that the ResourceManager has...). If the resource isn't loaded, then the manager will mark the object to be loaded at the next opportunity, (usually at the end of drawing the frame). Note that, although my system does do some reference... in advance of first use. Here is a bit a sketch of the classes I am using: typedef unsigned int ResourceId; // Resource is an abstract data type. class Resource { Resource(); virtual

  • know if my speculations are ok, as I don't have much experience with 3d animations yet. I want to make a well decision as any option I choose would require a lot of work to get it to render and I don't want to find out in the end that I have to rewrite everything again, as a lot of other objects will be working with these data. Sorry if it's a too subjective matter, but I need some insight. I'm... with different types of objects in the same scene. I was also thinking about making a MeshNode class and then make a Mesh object that contains them, but then I have some conflict on where to store some data

  • ; } } toWorldXForm is the object's world transform and toParentXForm is the object's transform relative to the parent. I want to do this using a method within my object class (the code above...I'm trying to implement a basic scene graph in DirectX using C++. I am using a left child-right sibling binary tree to do this. I'm having trouble updating each node's world transformation relative to its parent (and its parent's parent etc.). I'm struggling to get it to work recursively, though I can get it to work like this: for(int i = 0; i < NUM_OBJECTS; i++) { // Initialize

  • I've been thinking about adding 3d support in my roguelike. It would still be top-down like other roguelikes, yet it would have layers, such that things like platforms, tunnels, and bridges, etc... trying to have a 3d field of view routine for a 2d roguelike. The roguelike does have a 3d space, and I want to determine what the player can see, even if what the player can see can't logically be displayed. Let me worry about how to handle that problem. I would be grateful for some advice in how to approach this problem. Perhaps this is utterly crazy, and I should just make a 2d roguelike... Update