Night Elf
31-08-2007 23:01:52
Based on
this forum post I'm trying to iterate through raycast reports like this:
for (NxOgre::RayCastHit* hit = rayCaster.mReport.begin(); hit = rayCaster.mReport.next(); )
{ /* do something */ }
But the compiler complains that begin() and next() do not return pointers:
Error 1 error C2440: 'initializing' : cannot convert from 'NxOgre::RayCastHit' to 'NxOgre::RayCastHit *' e:\Dev\Behaviours.cpp 157
Error 2 error C2440: '=' : cannot convert from 'NxOgre::RayCastHit' to 'NxOgre::RayCastHit *' e:\Dev\Behaviours.cpp 157
If I change to this:
for (NxOgre::RayCastHit* hit = &rayCaster.mReport.begin(); hit = &rayCaster.mReport.next(); )
{ /* do something */ }
now I get an error inside NxOgre:
Error 1 error C2664: 'NxOgre::RayCastHit::RayCastHit(const NxOgre::RayCastHit &)' : cannot convert parameter 1 from 'int' to 'const NxOgre::RayCastHit &' c:\libs\nxogre\nxogre\include\NxOgreContainer.h 102
So, how should I iterate through a RayCastReport?
betajaen
31-08-2007 23:25:31
for (NxOgre::RayCastHit hit = rayCaster.mReport.begin(); hit = rayCaster.mReport.next(); )
{ /* do something */ }
Night Elf
31-08-2007 23:42:00
Are you sure? next() returns NULL when it gets to the end of the container... (Can't test it right now as my machine is busy compiling)
EDIT: I tried it and it doesn't compile. I get the following error:
Error 1 error C2451: conditional expression of type 'NxOgre::RayCastHit' is illegal e:\Dev\Behaviours.cpp 157
Which is understandable as the second part of the for must evaluate to a bool or an int to be able to serve as a condition...
betajaen
01-09-2007 00:02:32
Hmm. That's really odd. It's is "RayCastHit" and not "RayCastHit*"
typedef Container<NxString, RayCastHit> RayCastReport;
I'll have a fiddle tomorrow, and see how it works. But you may have to use the std::map iterator inside the container directly.
Night Elf
01-09-2007 00:58:13
Looking a how next() is implemented
TT next() {
if (mIterator == items.end())
return NULL;
return (mIterator++)->second.t;
}
I'd say NxOgre::Container should only be used store pointers as it returns NULL when the iterator reaches the end.
betajaen
01-09-2007 09:27:16
It's used to store both, but the iterator only works with pointer containers.
This is still not fixed in bleeding, is it?
betajaen
24-01-2008 20:01:42
Most likely I'll be replacing that with SharedList in BetajaenCC. Much better system.
lonwolf
08-02-2008 13:45:23
it has been a while since i used std::map, can any1 post a code on how to iterate with std::map or maybe you betajaen?
im trying somthing like
std::map<NxOgre::NxString,NxOgre::RayCastHit>::iterator i = rc->mReport.begin();
while(i)
{
//do something
i=rc->mReport.next();
}
but i can't compile the first line due to the fact that i forgot how to properly init a std::map container.. used it rarely anyways.. so a method to iterate through mReport can you post? i need to move all my kinematic bodies that are hit by a raycast but i can't itterate through the report atm.
any solution (even for dummies) will be grately appreciated.. it's a school project and i need to finish it asap so i can concentrate on my other exams..
hope to hearing from you soon

Lonwolf
edit:
full code
void Pad::move_bricks(Ogre::Vector3 p)
{
NxOgre::RayCaster* rc = new NxOgre::RayCaster(p,Vector3(0,1,0),30,NxOgre::RayCaster::RCT_ALL,mCurrentScene);
std::map<NxOgre::NxString,NxOgre::RayCastHit,std::less<Ogre::_StringBase>>::iterator i = rc->mReport.begin();
while(i)
{
//do smth
i = rc->mReport.next();
}
delete rc;
}
error list
Compiling...
1>Pad.cpp
1>.\src\Pad.cpp(96) : error C2440: 'initializing' : cannot convert from 'NxOgre::RayCastHit' to 'std::_Tree<_Traits>::iterator'
1> with
1> [
1> _Traits=std::_Tmap_traits<NxOgre::NxString,NxOgre::RayCastHit,std::less<Ogre::_StringBase>,std::allocator<std::pair<const NxOgre::NxString,NxOgre::RayCastHit>>,false>
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1>.\src\Pad.cpp(97) : error C2451: conditional expression of type 'std::_Tree<_Traits>::iterator' is illegal
1> with
1> [
1> _Traits=std::_Tmap_traits<NxOgre::NxString,NxOgre::RayCastHit,std::less<Ogre::_StringBase>,std::allocator<std::pair<const NxOgre::NxString,NxOgre::RayCastHit>>,false>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>.\src\Pad.cpp(100) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'NxOgre::RayCastHit' (or there is no acceptable conversion)
1> C:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(484): could be 'std::_Tree<_Traits>::iterator &std::_Tree<_Traits>::iterator::operator =(const std::_Tree<_Traits>::iterator &)'
1> with
1> [
1> _Traits=std::_Tmap_traits<NxOgre::NxString,NxOgre::RayCastHit,std::less<Ogre::_StringBase>,std::allocator<std::pair<const NxOgre::NxString,NxOgre::RayCastHit>>,false>
1> ]
1> while trying to match the argument list '(std::_Tree<_Traits>::iterator, NxOgre::RayCastHit)'
1> with
1> [
1> _Traits=std::_Tmap_traits<NxOgre::NxString,NxOgre::RayCastHit,std::less<Ogre::_StringBase>,std::allocator<std::pair<const NxOgre::NxString,NxOgre::RayCastHit>>,false>
1> ]
sorry for the long post
lonwolf
08-02-2008 14:10:03
ok i found an alternative, i hope this works (it compiles..)
NxOgre::RayCastReport::Iterator i;
for(i = rc->mReport.items.begin(); i!=rc->mReport.items.end();++i)
{
//etc
}
betajaen
08-02-2008 16:06:20
This is more "NxOgrey", because map will not be used in the future for containers:-
// With: Object*
Container<NxString, Object*> Objects;
Objects myObjects;
// ...
for (Object* object = myObjects.begin();object = myObjects.next();) {
// ...
}
// With: Object
Container<NxString, Object> Objects
Objects myObjects;
// ...
if (myObjects.count()) {
for (Object object = myObjects._begin();!myObjects._atEnd();object = myObjects._next()) {
// ...
}
}
lonwolf
08-02-2008 16:16:47
thnks for the info.. i hope i wont use map in the future cuz it gives me terrible headaches.. i've had a look at getClosestActor() and rewrote that so i can iterate through the report with my own function.. hope it helps some1, took me a while untill i've cleaned it up ..
btw any chance when the nxogre.org will go up again? it's pretty difficult to work with NxOgre this way.. im looking at the training programs, but i say a wiki would be easier.. though i haven't found the reason you closed the wiki.. anyway i'll struggle on finding these things on my own or with the forum
void Pad::move_bricks(Ogre::Vector3 p, NxString &x)
{
Vector3 dir=Vector3::ZERO;
dir.y=50;
NxOgre::RayCaster* rc = new NxOgre::RayCaster(p,dir.normalisedCopy(),30,NxOgre::RayCaster::RCT_ALL,mCurrentScene);
rc->castShape(NxOgre::RayCaster::AF_NONE);
if(rc->mReport.count()!=0)
{
NxOgre::RayCastReport::Iterator i;
for(i = rc->mReport.items.begin();i!=rc->mReport.items.end();++i)
{
Actor* a = (*i).second.t.mActor;
if(a!=0)
{
x=a->getName();
if(x[1]=='r')
{
Vector3 pos = a->getGlobalPosition();
pos.y-=3.01;
a->moveGlobalPosition(pos);
}
}
}
}
delete rc;
}
it returns the name of the last actor itterated and moves my bricks (note the b[1]=='r' <> "brick001").. it's a wierd solution, if i used dynamic bricks then they will all move crazy and the dps drops; if i changed the material, the ball would have lost cinematic energy <> velocity. Can't be static cuz i want them to drop when the first brick is destroyed.. AND the funny part is that KINEMATIC actors don't interact with gravity.. so i had to clamp the boxes 3.01 down the Y axis when the first one is destroyed..
a kinematic actor that could be affected by gravity would really simplify all this code
anyway it works, so here's a nice iteration without that std::map thingy