teleporter problem (animator) [FIXED]
teleporter problem (animator) [FIXED]
I have a problem with teleporting.
The situation is
...|---|
|-| T |-|
|.........|
|.........|
|.........|
|-------|
...|--|
|_|...|-|
|.........|
|.........|
|.........|
|-------|
. = space
You go in to the T and then you go to the back of the other one. The problem is you only go to the back of the one with the T.
If I remove all the animators it works but then I can't put them back.
Any ideas?
The situation is
...|---|
|-| T |-|
|.........|
|.........|
|.........|
|-------|
...|--|
|_|...|-|
|.........|
|.........|
|.........|
|-------|
. = space
You go in to the T and then you go to the back of the other one. The problem is you only go to the back of the one with the T.
If I remove all the animators it works but then I can't put them back.
Any ideas?
Last edited by Catprog on Fri Mar 30, 2007 5:20 am, edited 1 time in total.
Animators don't work well when you move the node that they are animating. The simplest solution is to remove the old animator, move the node, create a new animator that is a clone of the previous one, and add the clone back to the original node. Here is some code that should work with the collision response animator...
You would use it like this...
Code: Select all
scene::ISceneNodeAnimator*
ISceneNodeAnimatorCollisionResponse_clone(scene::ISceneNodeAnimator* anim, scene::ISceneNode* node, scene::ISceneManager* smgr)
{
if (! (anim && node && smgr))
return 0;
if (anim->getType() != scene::ESNAT_COLLISION_RESPONSE)
return 0;
scene::ISceneNodeAnimatorCollisionResponse* src =
(scene::ISceneNodeAnimatorCollisionResponse*)anim;
scene::ISceneNodeAnimatorCollisionResponse* dst =
smgr->createCollisionResponseAnimator(src->getWorld(),
node,
src->getEllipsoidRadius(),
src->getGravity(),
src->getEllipsoidTranslation()
); // someone forgot to expose methods for accessing sliding speed!
return dst;
}
Code: Select all
// find/get the collsion response animator
scene::ISceneNodeAnimator* anim = //...
anim->grab(); // make sure it won't be deleted until we want it to
node->removeAnimator(anim);
// teleport/move node to new location
scene::ISceneNodeAnimator* clone =
ISceneNodeAnimatorCollisionResponse_clone(anim, node, smgr);
// we no longer need the original
anim->drop();
node->addAnimator(clone);
clone->drop();
You use iterators [irr::core::list<T>::Iterator]...
You have to be very careful if you call a function that modifies the list that you are iterating over. If you are about to call a function that removes the item you are iterating over, you should advance the iterator before you remove, and make sure not to advance the iterator again or you'll skip the next item in the list...
Code: Select all
core::list<ISceneNodeAnimator*>::Iterator beg = node->getAnimators().begin();
core::list<ISceneNodeAnimator*>::Iterator end = node->getAnimators().end();
for (; beg != end; ++beg)
{
// (*beg) will be a pointer to an animator
}
Code: Select all
while (beg != end)
{
ISceneNodeAnimator* animator = *beg;
++beg;
if (you want to remove the animator)
node->removeAnimator(animator);
}
Unhandled exception at 0x00404e54 in TerrainRendering.exe: 0xC0000005: Access violation reading location 0xcccccccc.
The error occurs at
irrlist.h
void clear()
SKListNode* next = node->next;
When called by
The error occurs at
irrlist.h
void clear()
SKListNode* next = node->next;
When called by
Code: Select all
irr::core::list <scene::ISceneNodeAnimator*> animList =
camera->getAnimators();
Use a reference instead of making a copy.
The reason it doesn't work is someone didn't test their code before they submitted. The list copy constructor calls the assignment operator without initializing any of the members. The bug was fixed before Irrlicht 1.3. You could go and fix the list copy constructor yourself. It is a pretty easy change to make. You don't need to recompile Irrlicht if you make the change either.
Travis
Code: Select all
// notice the 'const' and '&' here
const core::list <scene::ISceneNodeAnimator*>& animList = camera->getAnimators();
Code: Select all
//! copy constructor
list(const list<T>& other)
: root(0), last(0), size(0) // add this line
{
*this = other;
}
I know this is an old thread but im struggling here and need some help.
Im pretty much trying to do the same thing, but i need multiple "teleports"
I have three rooms, red room, green room, and blue room. I need to be able to go from red to green, from green to blue, from blue to red.
I can create a one way teleport no problem using this code, however i encounter error's when dealing the animator. For some reason, it doesnt like the grab function.
Here is the code ive implemented.
This is the actual error message i get:
Unhandled exception at 0x00f64276 in ProjectFPS.exe: 0xC0000005: Access violation reading location 0x0cd2afe8.
Im pretty much trying to do the same thing, but i need multiple "teleports"
I have three rooms, red room, green room, and blue room. I need to be able to go from red to green, from green to blue, from blue to red.
I can create a one way teleport no problem using this code, however i encounter error's when dealing the animator. For some reason, it doesnt like the grab function.
Here is the code ive implemented.
Code: Select all
if(selectedSceneNode == sphere) //First room teleport
{
sAnim = anim; //sAnim is the animator for the first room
sAnim->grab();
camera->removeAnimator(sAnim);
camera->setPosition(vector3df(-270,60,230)); //Move to Blue Room
ISceneNodeAnimator* clone =
ISceneNodeAnimatorCollisionResponse_clone(sAnim, camera, smgr);
sAnim->drop();
camera->addAnimator(clone);
clone->drop();
}
else if(selectedSceneNode == gSphere) //Second Room
{
gAnim = anim; //2nd room animator
gAnim->grab();
camera->removeAnimator(gAnim);
camera->setPosition(vector3df(-100,60,230)); // Move to green room
ISceneNodeAnimator* clone =
ISceneNodeAnimatorCollisionResponse_clone(gAnim, camera, smgr);
sAnim->drop();
camera->addAnimator(clone);
clone->drop();
}
Unhandled exception at 0x00f64276 in ProjectFPS.exe: 0xC0000005: Access violation reading location 0x0cd2afe8.
In the second context you mistyped sAnim instead of gAnim, 3rd line from the bottom. Problem might be unrelated though.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
Ive figured it out :> lol
I only had to add a single line,
anim = clone;
Where anim is the original animator applied to the camera. The issue was, the 2nd time i ran the "teleport" function, it would try to remove the original animator, but that had already been removed. Therefore, by making the original animator a copy of the new animator, i can continue to remove it. So simple lol
Code is like so:
I only had to add a single line,
anim = clone;
Where anim is the original animator applied to the camera. The issue was, the 2nd time i ran the "teleport" function, it would try to remove the original animator, but that had already been removed. Therefore, by making the original animator a copy of the new animator, i can continue to remove it. So simple lol
Code is like so:
Code: Select all
if(selectedSceneNode == sphere || selectedSceneNode == bSphere || selectedSceneNode == gSphere )
{
ISceneNodeAnimator* newAnim = anim;
newAnim->grab();
camera->removeAnimator(newAnim);
if(selectedSceneNode == sphere)
{
camera->setPosition(vector3df(-270,60,230)); //Move to Blue Room
}
else if(selectedSceneNode == bSphere)
{
camera->setPosition(vector3df(0,60,0)); //Move to Original Room
}
else if(selectedSceneNode == gSphere)
{
camera->setPosition(vector3df(5000,60,0)); //Move to RedRoom
}
ISceneNodeAnimator* clone =
ISceneNodeAnimatorCollisionResponse_clone(newAnim, camera, smgr);
newAnim->drop();
camera->addAnimator(clone);
anim = clone;
clone->drop();
}
Hi,
I found another simpler solution for beginners who have the same problems.
This solution works with version 1.7.x
Most needed now to clone the annimator. You have to use ISceneNodeAnimatorCollisionResponse and setTargetNode() method.
Bye
I found another simpler solution for beginners who have the same problems.
This solution works with version 1.7.x
Most needed now to clone the annimator. You have to use ISceneNodeAnimatorCollisionResponse and setTargetNode() method.
Code: Select all
//add the animator to the respective node
irr::scene::ISceneNodeAnimatorCollisionResponse* anim = smgr->createCollisionResponseAnimator(
selector, node);
//...
//teleport/move node to new location
node->setPosition(core::vector3df(x,y,z));
//force the animator to update its last target position for the node
anim->setTargetNode(node);