Jump to content

  • Log In with Google      Sign In   
  • Create Account


flammable

Member Since 11 Mar 2009
Offline Last Active Today, 08:11 AM
-----

Topics I've Started

Avoiding unnecessary recalculation

06 August 2013 - 08:03 AM

Hey,

 

I could use some of your input on a problem I'm having (I'm using Java).

 

I'm writing a Node class which keeps track of the transformation of objects in my game world. This class contains position, rotation and scale fields for getting and setting the objects transformation and a transformation matrix for quick and easy calculations.

The problem lies in the fact that this matrix must be updated to match the current transformation every frame, but only when necessary. If the transformation of the node has not changed I would like not to recalculate the transformation matrix. As scene's in my game consist of a mixure of static and dynamic objects I feel such a optimisation can be worthwhile.

 

Well... in C++ this would easily be solved by a construction like:

class Node
{
    private:

    Vector position;

    bool isDirty;

    public:

    void setPosition(const Vector& p)
    {
         position = p;
         isDirty = true;
    }

    void move(const Vector& p)
    {
         position += p;
         isDirty = true;
    }

    const Vector& getPosition() const
    {
        return position;
    }

    void update()
    {
        if (isDirty)
             recalculate();
    }
}

However in Java you can't have const references thus making it possible to do: node.getPosition().set(0, 0). This makes the approach using a isDirty flag quite inpractical. Now I'm looking into other solutions:

 

  • Still use the isDirty flag and let the getPosition() method set the isDirty flag to true aswell. This would work and is quite easy but would also lead to some unnecessary recalculation of the transformation matrix.
  • Use the implementation as above and make it a rule not to modify the value returned by getPosition. This could also work but is not at all safe and will lead to untraceable bugs if you forget the rule.
  • Store the previous transformation state of the node and do a comparison with the current one to see if recalculation is needed. I'm not really a fan of this solution as it makes the Node class quite a lot bigger and introduces a lot of 'epsilon comparisons' to the update method.
  • Store a hashcode of the previous transformation state and compare this to the hashcode of the current transformation. I'm not sure about this one either. It introduces extra calculation in cases where the transformation matrix needs to be updated and there is a risk of a 'hashcode collision' which would lead to completely untraceable bugs (I have no idea what the chance on this is though)
  • Just recalculate the transformation matrix every frame.

I was hoping you guys might have an other solution or have some opinions about the solutions I came up with.

 

Thanks in advance.


2 c++ problems

09 August 2011 - 01:28 PM

Hey, I'm having two problems while trying to make a game (I'm using Visual Studio 2010 Express)

1) Trouble with renaming a namespace:
What I'm trying to do is put all classes in an namespace of an library I'm using into my own namespace, so I don't have to work with different namespaces.

what i'm doing is:
namespace Engine
{
	using namespace sf;
}

// namespace Engine = sf; doesn't work because the namespace already exists
But If I do this I get all kinds of errors about types that are not convertable when using templates (smart pointers). Like:
error C2440: 'initializing' : cannot convert from 'boost::shared_ptr<T>' to 'boost::shared_ptr<T>'

with
[
T=sf::RenderWindow
]
and
[
T=Engine::RenderWindow
]
I do understand why this error occurs but is there a work around or do I have to use 2 namespaces?

2) A bad combination of inheritance, polymorphism and void pointers.

I have a listener class with callback functions which other classes inherit from, using virtual functions the overridden function is called, quite standard. But the catch is:
The physics engine I'm using stores userdata as void* pointers, what I try to do is store the listener in the userdata (as void*) and then cast it to the listener class pointer and call the callback function but that where it goes wrong.

This is the simplified problem:
class Listener
{
	public:
	virtual void onEvent() = 0;
};

class MyListener : public Listener
{
	public:
	virtual void onEvent() {};
};

int main()
{
	MyListener* listener = new MyListener();
	PhysicsBody.userData = static_cast<void*>(listener);

	do things
}

void onEvent(PhysicsBody body)
{
	Listener* listener = static_cast<Listener*>(body.userData);
	listener->onEvent(); // Runtime error about memory violation;

	// dynamic_cast<Listener*>(body.userData) // gives a compilation error
}
I'm guessing the error is caused because the casting to void* discards the runtime information about the pointer and then when you cast it back try to use it again. But the question is what to do about it? I'm quite clueless and there don't seem to be any solution without completely redesign my programming.

Thanks in advance.

Design patterns

25 August 2010 - 09:19 AM

Hey, I got 2 questions regarding design pattern related to game programming.

All of my previous projects we're a complete mess (the programming part) but they we're quite small so it was manageble (but it was absolutely no joy to work with). Now I'm planning to make a more complicated game and I want to keep it manageable. I found a power-point about the design of game which was quite good but because there was no speech I think I missed some points.

1) My first question is about a queue design: According to the power-point it is better to let all the game entities communicate with each other through a Queue. something like:

Bad:
Player < ---- > Enemy (and a lot more of entities like: bullets, pick ups etc)

Good:
Player <---> Queue <----> Enemy


Well indeed the queue design looks nicer but I don't understand how it should be implemented. What does the player "say" to the queue and what does the queue "say" to the enemy (for example)?

2) The second question is about the model view controller pattern. I understand (mostly) how it works but how is it used in a game context?
A PlayerModel keeps the position of the player, a PlayerView draws a model at that position and a PlayerController changes the positon when the user pushes a key? But what if the game logic needs the model of the player to determine if the player is visible for an enemy? (I now realise that my question makes clear I don't understand how the MVC pattern works)

3) Can you think of some open-source projects I can take a look at to get a idea of how these things are done?

Thanks in advance.

ps: I know this post has a "Write games not engines" factor.

[c++] problem with a global instance of a class

03 March 2010 - 07:43 AM

Hey I've a problem, I'll first explain what I try to do. Create a class and a global instance of that class that can be accessed from everywhere I include the right header file, like how std::cout works (as far as I understand). I figured that the extern keyword was needed in this case and what I've done is this:
class Test_
{
	public:
		void greet()
		{
			std::cout << "Hello World!";
		}

};

extern Test_ Test;

and that gives the following linker error (I'm using visual studio c++ 2008):
1>main.obj : error LNK2001: unresolved external symbol "class Test_ Test" (?Test@@3VTest_@@A)
1>C:\Documents and Settings\gebruiker\Bureaublad\test\Debug\test.exe : fatal error LNK1120: 1 unresolved externals

I noticed that everything linked fine when I changed the last line into this:
extern Test_ Test = Test_();

but in the real case this isn't practical, and std::cout seems to do without it (but I'm sure I'm missing something). I hope someone can help, thanks in advance.

Most elegant way for solving a problem with references.

03 August 2009 - 08:43 AM

Hey, I was wondering what is the most elegant way (if there is one) to solve the following:
void Example(std::string& text)
{
/// Do something...
}

class A
{
    A();
    A(int);
    A(A&);
    ~A();

    A operator = (A& rhs)
    {
         M = rhs.M;
         return *this;
    }

    A SomeFunction()
    {
         A Temp;
         Temp.M = 5;
         return Temp;
    }

    int M;
};

int main()
{
     A First;
     A Second;
     Second = A.SomeFunction();              /// <== gives an error.
     Example(std::string("Hey"));            /// <== gives an error.
} 



compiling this code gives the errors: error: no match for 'operator=' in 'Second = A.SomeFunction()' note: candidates are: void A::operator=(A&) error no match for 'Example(std::string)' in 'Example(std::string("Hey"))' What causes the errors is easy: there are no versions of the functions/operators that take a instance of the class instead of the reference. But I just don't know what is the best, most efficient and elegant way to bypass this problem. What I came up with myself: -Just overloading the functions to take a instance of the class. That isn't very efficient because a copy needs to be made (the real class is quite larger than the exaple class so that isn't a good solution). -Create the class before you pass it to the function. Not very nice and in case of the error with class A even impossible. I'm using a GNU GCC compiler. I belive that the virtual studio compiler would just compile the code without a warning (not sure). Also many open source libarys (irrlicht for example) have classes only with operators that take references and functions that return a new instance of that class. for example: CMatrix4<float> New = Old.getTranspose() is totaly impossible with my compiler. I hope some can help me with finding a solution (or just can tell me one of the two I already came up with is just fine). Thanks in advance.

PARTNERS