[Solved] Explosion

Caphalor

18-02-2007 11:16:07

Hi, I'm developing a simple FPS Shooter with NxOgre and I have a question.
In my "game", you can walk arround and shoot green balls (later they will be replaced with fireballs), which collide with the world and the objects (at the moment only some cubes) in it. I managed to delete the balls when they hit something, but after deleting, there should be a small explosion. The particle effect isn't important yet, I only want to know how to implement an invisible explosion, so that the cubes fly away. ;)

And another question: I can't run my NxOgre applications on another PC, although I copied all off the Dll Files which are in my folder here where I run my applications. I also installed the PhysX System Software, but I always get a typical Windows error "The application could not be started because the application configuration is not correct" (translation from german), what could I have forgotten?


PS: NxOgre rules. :D:D:D

PPS: Sorry for my bad English. :(

betajaen

18-02-2007 11:55:14

Explosions are a force, so you'll need to add a force for each body that goes away from the explosion centre.

This is code from a newer piece of NxOgre your using, but it should get you started:

void body::moveAway(pose p, float force) {
NxVec3 fc = p.v - mActor->getGlobalPosition();
fc *= force;
fc -= mActor->getPointVelocity(mActor->getGlobalPosition());
mActor->addForceAtPos(-fc, mActor->getGlobalPosition());
}



If your using VS2005 there are a few hoops you have to go through to make your compiled application to work on other computers. There are quite a few good threads about this on the main forum.

PS: It does so.

Caphalor

18-02-2007 12:19:30

Thanks, but must I check for every body whether it is in the explosion range? Or is there an easier solution?

betajaen

18-02-2007 12:35:24

An intersection.

It'll give you a nice stl vector of all the bodies in a specific area, from there you can use a slightly modified above code with it.

Caphalor

18-02-2007 21:36:38

Thanks, it works. :)
Two other questions:

1. When I compile my Application, Visual Studio 2005 says that body::moveAway is an unresolved external symbol, but when I execute the .exe it works.

2. When I try to delete the ball which collided with something in the state machine, I get an error. So I added a string member variable "BodyDeletelist" to the scene class, in which I save the name of the body which shall be deleted. In the NewFrame function, I delete the body which is in the list:
if (mScene->BodyDeletelist != "")
{
mScene->destroyBody(mScene->BodyDeletelist);
mScene->BodyDeletelist = "";
}



That works, but when the ball is very near to the player (for example when I shoot at the ground), I get an error. When (in which function) can I delete bodies without any danger? :o
PS: I am an idiot, I think the error is because the player is in explosion range....

betajaen

18-02-2007 21:40:10

Oh you don't directly have to add that code into Body, just make use it in your application.

It's probably trying to delete the Player, which is a NxActor which bodies use. A better way would be just to add a new state saying DELETE_ME to the body, then the state machine removes it.

Caphalor

18-02-2007 21:54:04

Please forget my second question, I am an idiot:


std::cout << "Delete" << std::endl;

intersection *myIntersection = new intersection(new intersection::Sphere(_body->getGlobalPosition(), 5), _body->owner);
pose TempPose(_body->getGlobalPosition(), _body->getGlobalOrientation());

std::cout << myIntersection->iterator->count() << std::endl;



Thats a part of the code which is called when the state status of a body with the state DESTROYABLE (the balls) is Clear.
When the player is in the intersection range, I only get the "Deleted" message and then the error, not the count. So the intersection must be responsible for the error. But why?

betajaen

18-02-2007 22:04:40

I believe the intersection code is casting the NxActor userdata into a body, when it should be a character causing a crash.

You could fix it your self if you wanted to. In the intersection code in NxOgre, only pass on the NxActors with the name "NxB".

Caphalor

19-02-2007 18:33:44

Hm, it seems as if every body, also the player, is named NxB??

bool intersection::onEvent(NxU32 nbShapes, NxShape** shapes) {

if (iterator)
delete iterator;

iterator = new bodyIterator();

while (nbShapes--) {
NxActor* actor = &shapes[nbShapes]->getActor();
if (actor->getName() == "NxB")
{
body *b = static_cast<nxOgre::body*>(actor->userData);
iterator->Bodies[b->getName()] = b;
std::cout << "Tada" << std::endl;
}
}

iterator->first();

return true;
}


I don't get the error, but explosions aren't working anymore. :(

betajaen

19-02-2007 18:42:49

It shouldn't be, technically the character's name shouldn't be anything. As I forgot to put it in.

There may be another way of working out what NxActor is causing the crash. Dumping the positions to the console, and comparing it to the NxActor of the character.

[Edit]

I see some code. Try this:

while (nbShapes--) {
NxActor* actor = &shapes[nbShapes]->getActor();
std::cout << actor->getName() << ":" << actor->getGlobalPosition().x << ", " << actor->getGlobalPosition().y << ", " << actor->getGlobalPosition().z << std::endl;
}

Caphalor

19-02-2007 20:38:36


bool intersection::onEvent(NxU32 nbShapes, NxShape** shapes) {

if (iterator)
delete iterator;

iterator = new bodyIterator();

while (nbShapes--) {
std::cout << "Loop Start!" << std::endl;
NxActor* actor = &shapes[nbShapes]->getActor();
std::cout << actor->getName() << ":" << actor->getGlobalPosition().x << ", " << actor->getGlobalPosition().y << ", " << actor->getGlobalPosition().z << std::endl;
body *b = static_cast<nxOgre::body*>(actor->userData);
std::cout << b->getName() << std::endl;
iterator->Bodies[b->getName()] = b;
std::cout << "Loop end!" << std::endl;
}

iterator->first();

return true;
}


The last message I get is "Loop Start". :(

betajaen

19-02-2007 21:10:21

Wow. It must be the character then. However I can't see how it's crashing if the Characters shape's actor is an actual actor.

I think an investigation is needed, I'll have a fiddle later and see if I come up with something.

Caphalor

19-02-2007 21:30:48

Don't spend too much work on it, it's probably only one of my normal stupid errors. :D

Caphalor

20-02-2007 17:38:11

I think I solved my problem:

- In NxOgre_Scene.h I declared a new NxVec3 variable mPlayerPosition
- In the Newframe function of my application I synchronized mPlayerPosition with the Player Position
- In intersection::onEvent I changed the following:

while (nbShapes--) {
std::cout << shapes[nbShapes]->getGlobalPosition().x << std::endl;
if (shapes[nbShapes]->getGlobalPosition() == mScene->mPlayerPosition)
{
std::cout << "Player in explosion range!" << std::endl;
continue;
}


Of course that's not a very good solution, but it seems to work....

betajaen

20-02-2007 17:41:46

Nope ;). I have a slighty more less hacky solution by using groups.

Caphalor

20-02-2007 17:51:41

Great to hear, and if you describe your solution with a little bit more details, I will replace mine with yours. :D

betajaen

20-02-2007 17:54:59

Basically it's using a groupmask. But the NxActor in the character to a group say 16. And when you come to the intersection mask out group 16.

Caphalor

20-02-2007 20:47:02

Thanks for the help, it works now fine. :)

betajaen

20-02-2007 20:54:53

Seriously? I'd love some code to put it in. :D

Caphalor

20-02-2007 21:29:15

Hm, I only did what you said.

In intersection::onEvent:

while (nbShapes--) {
if (shapes[nbShapes]->getGroupsMask().bits3 == 11)
{
std::cout << "Player in explosion range!" << std::endl;
continue;
}


And in the start function of my application (at the moment, I have only one shape for the player, a yellow box just like in the tutorial 606):

NxGroupsMask TempMask;
TempMask.bits3 = 11;
mPlayer->mController->getActor()->getShapes()[0]->setGroupsMask(TempMask);


That's all, or do you mean the whole code for the explosion?

betajaen

20-02-2007 21:40:35

Nope, that's exactly how I envisioned it ;)