Jump to content
  • Advertisement
Sign in to follow this  
mind in a box

Copying a nested thing...

This topic is 2899 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all!

Please take a look at this code:


struct JointInfoStruct
{
private:
float FinalRotation;
D3DXVECTOR2 FinalPosition;

public:
D3DXVECTOR2 Position;
float Rotation;
JointInfoStruct* Parent;
vector<JointInfoStruct *> Children;
};

struct FrameInfoStruct
{
vector<JointInfoStruct *> Frames;

void CopyFrame(JointInfoStruct* In, JointInfoStruct* Out)
{
//???
}
};



The FrameInfoStruct holds the frames of a skeletal animation. Now I need to copy one frame, and I have no idea how to do that.
Well, I have one, but I'm so confused about it, so I ask here before I do something wrong.

when I just memcpy the parent of all joints, the Children vector will hold wrong values. Because it holds pointers. But when I want to go through it I need many for-loops and such stuff. And this must be there and that must be here and the other thing has to go next to the first and the..., ahh!

That stuff confuses me very much, please tell me how before my brain explodes [sad]

Share this post


Link to post
Share on other sites
Advertisement
Imagine that your JointInfoStruct class had a member function clone() that would return a new instance of JointInfoStruct that is a clone of the struct it was called on. If you were implementing such a clone() function you could call clone() on each of the children to fill the vector of the cloned copy.

Share this post


Link to post
Share on other sites
Ok.. I'm not sure if that is right:

struct JointInfoStruct
{
private:
float FinalRotation;
D3DXVECTOR2 FinalPosition;

public:
D3DXVECTOR2 Position;
float Rotation;
JointInfoStruct* Parent;
vector<JointInfoStruct *> Children;

JointInfoStruct* Clone(JointInfoStruct* NewParent)
{
JointInfoStruct* Out=new JointInfoStruct;

//Copy data like Position, Rotation, ...
memcpy(Out,this,sizeof(JointInfoStruct));

//Clear the vector, for the case memcpy copied something over to it
Out->Children.clear();

//Set our new parent
Out->Parent=NewParent;

//Copy children
for(int i=0;i<Children.size();i++)
{
Out->Children.push_back(Children->Clone(Out));
}

return Out;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by mind in a box
memcpy(Out,this,sizeof(JointInfoStruct));

No. Never use memcpy() like that unless you're dealing with a POD type. Since JointInfoStruct contains a vector, it's not POD.

Share this post


Link to post
Share on other sites
Don't use memcpy to copy class instances. Use the type's copy constructor. That's what it's there for.


JointInfoStruct* JointInfoStruct::clone() const
{
// this uses JointInfoStruct's compiler-generated copy constructor
return new JointInfoStruct( *this );
}





Note, however, that this will give you a shallow copy. If you need a deep copy, you will have to provide a custom copy constructor.


P.S. Read this if you aren't sure what deep / shallow copying means.

Share this post


Link to post
Share on other sites
Google is my friend, I'm sorry [sad]

Quote:

Don't use memcpy to copy class instances. Use the type's copy constructor. That's what it's there for.


It's a struct, will this work with it as well? Also, a swallow copy doesn't really copies the data, or does it? The Wiki says they are linked together then. And when I would change a position of a Joint in another frame all would change, right?

(5 Minutes of thinking later, GameDev is still down, OLE Error or so:
Could it be that a swallow copy just means to assign the address of something to a pointer? No, I don't need that.)


I guess I'm better with writing all variables into that copy function. Gives less confusion for me [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by mind in a box
Quote:

Don't use memcpy to copy class instances. Use the type's copy constructor. That's what it's there for.


It's a struct, will this work with it as well?
A class is exactly the same as a struct with the exception that the default access type for a struct is public, and for a class it's private.

Quote:
Original post by mind in a box
Also, a swallow copy doesn't really copies the data, or does it? The Wiki says they are linked together then. And when I would change a position of a Joint in another frame all would change, right?

(5 Minutes of thinking later, GameDev is still down, OLE Error or so:
Could it be that a swallow copy just means to assign the address of something to a pointer? No, I don't need that.)
Nitpick: It's "shallow" copy, not "swallow" [smile].

A shallow copy like memcpy() does a byte-for-byte copy, which generally doesn't work with non-POD types. A std::vector will contain at least a pointer to the memory the vector has allocated. If you do a shallow copy of a std::vector, you'll get two vectors that both think they own the same chunk of memory (Since each vectors data pointer has the same value). That'll blow up when one vector is destroyed and it deletes the memory, leaving the other vector pointing at invalid (deleted) memory.

Share this post


Link to post
Share on other sites
The only difference between a struct and a class is that, in the struct, access is public by default, whereas in the class it's private by default. Other than that, there is NO difference at all, so yes it will work with structs, too.

Anyway, I'll try to give a simple example to show you how to accomplish deep copying.


class SomeClass
{
// ...
};


class MyClass
{
public:
// custom copy constructor ... implements deep copying
MyClass( const MyClass& other );

private:
int m_int;

std::vector< double > m_vectorOfDoubles;

SomeClass* m_pointerToSomeClass;
};

MyClass::MyClass( const MyClass& other ) :
m_int( other.m_int )
m_vectorOfDoubles( other.m_vectorOfDoubles ),

// do not just copy the pointer ... make a new instance that is a copy of the instance
// the pointer points to. this in turn uses the copy constructor of class SomeClass
m_pointerToSomeClass( new SomeClass( *other.m_pointerToSomeClass ) )
{
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!