crash when characters fall below level

jchmack

26-08-2007 21:38:58

i have a crash whenever one of my characters falls below the x/z axis passing through the origin (ie whenever his y becomes less than 0). At first i thought it might be something in the way i delete my characters but i tried to just create a blank app with a floor:

mScene = mWorld->createScene("Main", mSceneMgr, "gravity: yes, floor: yes, time-step-method: fixed");


it runs fine until i create a character:

GameCharacterCount++;
Name+=Ogre::StringConverter::toString(GameCharacterCount);

// Create character
NxOgre::CharacterParams Params;
Params.setToDefault();
Params.mType = NxOgre::CharacterParams::CT_Box;
Params.mSkinWidth = 0.5;

mCharacter = mScene->createCharacter(Name, InitialPosition, Params);
mCharacter->createNode();

// Create mesh
MeshNode = GetNode()->createChildSceneNode(Name+" MeshNode");
MeshEntity = mScene->getSceneManager()->createEntity(Name+" Entity",Mesh);
AdjustMesh();
MeshNode->attachObject(MeshEntity);


Then i get a crash saying something about the collisions and toActor(). Any idea?

jchmack

26-08-2007 21:44:48

ok it seems to do better if i dont have a floor:

mScene = mWorld->createScene("Main", mSceneMgr, "gravity: yes, floor: no, time-step-method: fixed");

but still something that is kinda weird....

edit: i was in debug mode when i was getting the crash don't know about release mode. Is NxOgre good to go in the debug mode? I've always ran in release and i feel like i get strange crashes in debug.

betajaen

26-08-2007 21:54:26

No crash for me:

mWorld = new World();
mScene = mWorld->createScene("Main", mSceneMgr, "gravity: yes, floor: yes");

NxOgre::CharacterParams Params;
Params.setToDefault();
Params.mType = NxOgre::CharacterParams::CT_Box;
Params.mSkinWidth = 0.5;

mCharacter = mScene->createCharacter("Foo", Ogre::Vector3(0,5,0), Params);
mCharacter->attachMesh("cube.1m.mesh");
mCharacter->getNode()->scale(0.25f,2.0f,0.25f);


I can give you a copy of NxOgre 0.9'34 if you wish, to check if the bug has been squished or not. Your using PhysX 2.7.2 I assume?

jchmack

26-08-2007 22:33:09

No crash for me:

I can give you a copy of NxOgre 0.9'34 if you wish, to check if the bug has been squished or not. Your using PhysX 2.7.2 I assume?


hmm i tried the exact same code in mine and (sometimes...) i get a crash pointing here in nxogreuserdata.h:

Actor* toActor()
{
return static_cast<Actor*>(Ptr);
}

are u in debug?

well to tell the truth it works fine with just one but as i add more i get crashes. ill do a bit more testing.

betajaen

26-08-2007 22:37:27

Yep I'm in Debug. But it should be returning the Character not an Actor (Characters aren't actors).

But try '34. I've private messaged you the link.

jchmack

26-08-2007 22:39:35

OK ill check it out =)

edit: just looking at all the changes to the actor/body system gives me hope =)

jchmack

26-08-2007 23:11:30

ok here are the new results. The issue with the character going through the floor is gone =). But it seems another issue has shown itself: It seems that if i stack up 4 characters (might be with more but i always crash with 4) on top of each other i get a crash:

NxControllerAction CharacterController::onShapeHit(const NxControllerShapeHit &hit) {
CharacterHitReport::Response response = CharacterHitReport::RS_None;
Character* character = static_cast<Character*>(hit.controller->getUserData());
Actor* actor = (static_cast<NxActorUserData*>(hit.shape->getActor().userData))->toActor();
ActorGroup* group = actor->getGroup(); //<<<<<<<<<<<HERE
Shape* shape = static_cast<Shape*>(hit.shape->userData);

// Go through any existing reporters.

for(CharacterHitReports::Iterator it = mHitReports.items.begin();it != mHitReports.items.end();++it) {

CharacterHitReport::Response r = (*it)->onActor(character, actor, shape, group, hit);

if (r != CharacterHitReport::RS_None) {
return (NxControllerAction) r;
}

}

// Fire up the final base reporter.
return (NxControllerAction) mBaseHitReport->onActor(character, actor, shape, group, hit);

}


i guess no huge stacks or pyramids of characters....
but way more importantly it seems that many of my older issues are fixed. Keep up the good work beta =)

edit: if you want to recreate my crash it seems to happen pretty consistently. I have a button set to create a character at Ogre::Vector3(0,5,0) I push it 4 times and i get a crash.

betajaen

26-08-2007 23:24:30

I'm glad your issues and your bugs have been fixed. You may notice a speed increase there as well. ;)

As for the "Character Stacking Bug" as I'm now calling it, I think I may know why. The NxActor in the Character is being reported as a onShapeHit, it has some NxActorUserdata, but it isn't an Actor; it's a Character, causing a big crash when it's trying to access a function that doesn't exist.

Why four or more actors? Perhaps it's down to skin width and the fake forces added, or the magic of the number four. Either way, try replacing the top half of that function with the following code, and run it through that magic button of yours. ;)

if (hit.shape->getActor().userData == 0)
return;

NxActorUserData* aud = static_cast<NxActorUserData*>(hit.shape->getActor().userData);
if (aud->getType() != NxActorUserData::T_Actor)
return;

CharacterHitReport::Response response = CharacterHitReport::RS_None;
Character* character = static_cast<Character*>(hit.controller->getUserData());

Actor* actor = aud->toActor();
ActorGroup* group = actor->getGroup();
Shape* shape = static_cast<Shape*>(hit.shape->userData);

jchmack

26-08-2007 23:39:16

Either way, try replacing the top half of that function with the following code, and run it through that magic button of yours. ;)


hmm im getting compiler errors when i replace that as you recommended. Could you please post the full function instead?

betajaen

26-08-2007 23:47:25

I didn't even try to compile the function, I just expected it to work:

NxControllerAction CharacterController::onShapeHit(const NxControllerShapeHit &hit) {

if (hit.shape->getActor().userData == 0)
return (NxControllerAction) CharacterHitReport::RS_None;

NxActorUserData* aud = static_cast<NxActorUserData*>(hit.shape->getActor().userData);
if (aud->getType() != NxActorUserData::T_Actor)
return (NxControllerAction) CharacterHitReport::RS_None;

CharacterHitReport::Response response = CharacterHitReport::RS_None;
Character* character = static_cast<Character*>(hit.controller->getUserData());

Actor* actor = aud->toActor();
ActorGroup* group = actor->getGroup();
Shape* shape = static_cast<Shape*>(hit.shape->userData);

// Go through any existing reporters.

for(CharacterHitReports::Iterator it = mHitReports.items.begin();it != mHitReports.items.end();++it) {

CharacterHitReport::Response r = (*it)->onActor(character, actor, shape, group, hit);

if (r != CharacterHitReport::RS_None) {
return (NxControllerAction) r;
}

}

// Fire up the final base reporter.
return (NxControllerAction) mBaseHitReport->onActor(character, actor, shape, group, hit);

}


I'm not sure "None" is a best response though; NxActors (usually created directly through the SDK) and maybe the characters will go through the character now, perhaps a "Push" is better.

jchmack

26-08-2007 23:59:03

ok the crash is gone. But after 4 or more characters stack the 5th and above just fall through the topmost character and land on the one below. In other words max of 4 players stacked.

edit: Also i was just about to ask you if you had changed the mesh system because some of my older meshes didn't seem to display properly. But with this little patch it seems to display fine lol.

edit2: i don't think i'm doing anything too fancy lol i basically have a button that calls this function:

void GameCharacter::Create(Scene *mScene,Vector3 InitialPosition)
{
GameCharacterCount++;
Name+=Ogre::StringConverter::toString(GameCharacterCount);

// Create character
NxOgre::CharacterParams Params;
Params.setToDefault();
Params.mType = NxOgre::CharacterParams::CT_Box;
Params.mSkinWidth = 0.5;
mCharacter = mScene->createCharacter(Name, Ogre::Vector3(0,5,0), Params);

// Create mesh
//mCharacter->attachMesh("cube.1m.mesh");
//mCharacter->getNode()->scale(0.25f,2.0f,0.25f);
mCharacter->attachMesh(Mesh);
MeshNode = mCharacter->getNode();
MeshEntity = mCharacter->getEntity();
AdjustMesh();
}

betajaen

27-08-2007 00:09:03

I expect that the Characters are being compressed, or being ever so slightly inside of each other for the NxActor inside to trigger a onShape hit. If you change both of those RS_None to RS_Push, they won't fall through each other.

The Skeleton Mesh system uses the new MeshManager class, but I haven't moved the NxOgreCooking.h code over to it.

You'll find some other speed increases, particularly the rendering code (which I'm proud about).

In the old system it used to loop through every Actor, and set the new position regardless if it moved or not, then another loop for Characters and move them if they have moved now. Now it gets a list of Actors from PhysX that have just moved, and moves them. It even supplies the NxActors in characters so that extra loop is eliminated as well. ;)

jchmack

27-08-2007 00:15:16

I expect that the Characters are being compressed, or being ever so slightly inside of each other for the NxActor inside to trigger a onShape hit. If you change both of those RS_None to RS_Push, they won't fall through each other.

The Skeleton Mesh system uses the new MeshManager class, but I haven't moved the NxOgreCooking.h code over to it.

You'll find some other speed increases, particularly the rendering code (which I'm proud about).

In the old system it used to loop through every Actor, and set the new position regardless if it moved or not, then another loop for Characters and move them if they have moved now. Now it gets a list of Actors from PhysX that have just moved, and moves them. It even supplies the NxActors in characters so that extra loop is eliminated as well. ;)


very nice =). I am currently starting the 5th iteration of my game engine so it still in its fledgling stages and i cant see a performance boost because i really don't have anything to compare it to. I think ill try the new nxogre with my older engine to see how it does performance wise.

edit: got a leak

1 memory leak found:

Alloc. Addr Size Addr Size BreakOn BreakOn
Number Reported Reported Actual Actual Unused Method Dealloc Realloc Allocated by
------ ---------- ---------- ---------- ---------- ---------- -------- ------- ------- ---------------------------------------------------
017268 0x0508B778 0x00000008 0x0508B768 0x00000028 0x00000000 new N N nxogrecharacter.cpp(96) NxOgre::Character::Character

the only new i can see in the ctor of character is:

mNxActorUserData = new NxActorUserData(this, NxActorUserData::T_Character);

should i just call delete mNxActorUserData in the dtor or is there a cleaner way

betajaen

27-08-2007 00:19:43

Whoops. Yep you can delete it that way.

jchmack

27-08-2007 00:24:19

ooooh man 0.9-34 is fast. My projectiles used to have small skips when i did large group creations but now they are non-existent (unless i do something ridiculous). Also the new raycaster works against character meshes too. I can finally trash the one i made. I was using a terrible frankenstein raycaster...... half physx, half NxOgre, and half ogre lol.

betajaen

27-08-2007 00:30:44

Want to see something really awesome?

Run this through Cake, or before you create your own scene:

NxOgre::Test* mTest = new NxOgre::Test(mWorld, mSceneMgr);
mTest->addTestCases();
mTest->startTesting();
mTest->stopTesting();
mTest->saveToLog();
delete mTest;


It's the new testing class. It will create 64 empty Scenes, then 8 more filled with 128 actors (each), and simulate each for 1 second each.

Look at the NxOgre.log after it's done. Insane!

betajaen

27-08-2007 00:35:49

What's even more insane is; in the time this thread was initially answered. I've finished off the Dominance Groups class, wrote the Scene Methods, fixed the bugs and tested it in Cake!

DominanceGroups with Characters will be another really handy feature; One way collisions with the character with lesser, unimportant Actors (such as rocks, pieces of wood, or small cakes) will be a cool feature to have in a game.