How do you manage two vector from two different api's(Box2D and SFML)

Started by
8 comments, last by Hodgman 11 years ago

Hi, i'm using box2d and sfml and i have two different vector here (b2vec2 and sf::Vector2f).

I'm trying to combine two vector type in my game classes, what i've done now is making my own game vector utility whit all basic vector operation and casting ability to b2vec2 and sf::Vector2f and it's to far from efficient since i no longer able to pass the vector by pointer or refference and must pass it using value which expensive operation.

i'm also thinking about make b2vec2 as my global vector for game objects and create a converter for convert it to sfml if it needed sometime.

any advice or example's on how you manage this ?

thanks smile.png

Advertisement

If you need to keep all vector classes intact, then the safest way is to roll your own vector class and write conversion functions. Usually this is not the case. It'd also add conversion overhead.

If the classes share the same members (eg, x, y, z) and overloads, you can get away with writing global copy functions and just using them directly (one type at a time and on a per-component basis if you need to use them interchangeably). I'd advise against this, however, as it'll create a mess.

As a matter of speed and clarity, for instance idTech uses macro-based vector operators, which automatically resolve into inline code and are inherently faster. You could adopt the same approach. Eg:

vec2d v0, v1, v2;

v2 = v0 * v1;

becomes:

#define VecMult2D(a, b, res) (res[0] = (a[0]) * (b[0]), res[1] = (a[1]) * (b[1]))

VecMult2D(v0, v1, v2);

You'd no longer be dependent on member functions and your "vector class" would degenerate into a simple POD. Furthermore, you could mix vec2dA and vec2dB if both of them provide a bracket operator overload. Eg:

vec2dA v0;

vec2dB v1;

myvec2d v2;

VecMult2D(v0, v1, v2);

Not that this would be a good idea. The biggest problem with this is likely converting code from operator-oriented form into macro-oriented form, which can and will be a true hassle.

A third and most likely simplest option would be to rename one to the other or both to your own. Once again, if the operator overloads and members are the same, the conversion is actually pretty simple in most IDE-s: use Replace All (usually Ctrl+H or Ctrl+Shift+H) and rename one class name to the other (or, again, both to your own class). If you have differences in member names, then the conversion can be a real PITA, though.

A fourth and most efficient way is to use some form of refactoring. I don't know what native refactoring capabilities are like in IDE-s, but VisualAssist X (can be pricey, but is well worth the investment if you have the money) excels in stuff like this.

There is no automatic way to handle this.

Both Box2D and SFML are open source. Recompile one of them to use the other's vector.

Or, depending on how the two vectors are laid out, maybe it might be possible to cast them? I don't know whether that's safe or not, I typically avoid all except polymorphism casts and int casts, so my casting knowledge isn't great.
They both just have x and y floats and that's it (besides the functions). Can a reference to one be safely cast to a reference to the other?

http://www.sfml-dev.org/documentation/2.0/classsf_1_1Vector2.php
http://www.learn-cocos2d.com/api-ref/2.0/Box2D/html/structb2_vec2.html

For 2 element vectors its probably not that big of a performance problem to copy 2 floats compared to copying a pointer thats same size or twice the size of a float. If you actually use the floats at some point they need to get read anyway.

I would just pick one of the vector types that feels more comfortable to use or where you estimate less conversions would be needed if you need to call one of those librarys more often. Later if its really too slow you can always profile and see if you need to improve this or something else.

I would go with a class implicit conversion operator. The class would be my own Vector2/3 class.

Or inherit from one of the vectors, and add your own conversion to the other one. Just be sure you don't create one of your class vectors but then delete it with the base class vector you may get memory leak since it's probably not have a virtual dtor.

If this post or signature was helpful and/or constructive please give rep.

// C++ Video tutorials

http://www.youtube.com/watch?v=Wo60USYV9Ik

// Easy to learn 2D Game Library c++

SFML2.2 Download http://www.sfml-dev.org/download.php

SFML2.2 Tutorials http://www.sfml-dev.org/tutorials/2.2/

// Excellent 2d physics library Box2D

http://box2d.org/about/

// SFML 2 book

http://www.amazon.com/gp/product/1849696845/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=1849696845&linkCode=as2&tag=gamer2creator-20

Both Box2D and SFML are open source. Recompile one of them to use the other's vector.

Or, depending on how the two vectors are laid out, maybe it might be possible to cast them? I don't know whether that's safe or not, I typically avoid all except polymorphism casts and int casts, so my casting knowledge isn't great.
They both just have x and y floats and that's it (besides the functions). Can a reference to one be safely cast to a reference to the other?

http://www.sfml-dev.org/documentation/2.0/classsf_1_1Vector2.php
http://www.learn-cocos2d.com/api-ref/2.0/Box2D/html/structb2_vec2.html

If they were literally identical, just varying by name, you could get away with casting. In the real world, no, very bad idea.

thanks all for your aswers, smile.png

I would just pick one of the vector types that feels more comfortable to use or where you estimate less conversions would be needed if you need to call one of those librarys more often. Later if its really too slow you can always profile and see if you need to improve this or something else.

i think i will chose this way and try to separate between gameplay object class and graphics class, in my problem i will use b2vec2 more because my game using box2d to program its gameplay and create a converter function for it for sfml related use. well, hope it's the most efficient way

Both Box2D and SFML are open source. Recompile one of them to use the other's vector.

this a good idea but, it'll be a problem with me since sfml using template to define it's vector and i'm still don't know how to use it. moreover b2vec2 using struct to define it's vector and of course it'll make me confusing

wintertime's solution is a good one - I was making the mistake of assuming that performance was already a problem.


Both Box2D and SFML are open source. Recompile one of them to use the other's vector.

this a good idea but, it'll be a problem with me since sfml using template to define it's vector and i'm still don't know how to use it. moreover b2vec2 using struct to define it's vector and of course it'll make me confusing


Just use SFML's sf::Vector2f typedef, and it'll work fine. The fact that SFML's vector struct/class is a template doesn't harm anything.

For example, if SFML had a templated struct like this:
template <typename Type>
struct MyStruct
{
    Type x;
    Type y;
};
Then it's really, as the name implies, just a "template" that the actual struct is generated from.

Doing this:
MyStruct<int> myIntStruct;
Tells it to generate a struct, using the template, with 'int' instead of 'Type', like this:
/* template <typename Type> */
struct MyStruct_ForInts 
{
    /* Type */ int x;
    /* Type */ int y;
};

MyStruct_ForInts myIntStruct;
Then they can create a second almost-identical struct, with floats instead:
MyStruct<float> myFloatStruct;
Which creates:
struct MyStruct_ForFloats
{
    float x;
    float y;
};

MyStruct_ForFloats myFloatStruct;
The actual name is generated by the compiler, but MyStruct<float> is the generated "name" of the class type that you, as the programmer, use in your code. So you don't actually use 'MyStruct_ForFloats variableName;', you use 'MyStruct<float> variableName;'

This is just to explain templates - I'd still use wintertime's suggestion.

wintertime's solution is a good one - I was making the mistake of assuming that performance was already a problem.

yes, i will use it

This is just to explain templates

Wow, that was very good explanation,rolleyes.gif

thanks, really appreciate it smile.png


Or, depending on how the two vectors are laid out, maybe it might be possible to cast them? I don't know whether that's safe or not, I typically avoid all except polymorphism casts and int casts, so my casting knowledge isn't great.
They both just have x and y floats and that's it (besides the functions). Can a reference to one be safely cast to a reference to the other?

If they were literally identical, just varying by name, you could get away with casting. In the real world, no, very bad idea.
If they're both POD, then under the hood you're basically just casting a pointer to float to a different type of pointer to float, which is valid enough. You can throw in some compile time assertions that the sizes/layouts of the two classes remain identical so that the code will fail to compile should the classes change in the future.

This topic is closed to new replies.

Advertisement