I've got a pirate ship mesh moving according to a straightlineanimator, and I'm shooting a cannonball at it (I'm doing some physics on the cannonball so it drops, so that's in an animation loop with a frametimer). I'm doing hit detection this way, which basically draws a line between the current frame's movement of the cannonball and checks for an object hit (the pirate ship is the only thing out there) in that line with getCollisionPoint.
Here's my problem: I want to know where the ball hit, so I can place a child particle emitter there. If I leave constants in the core::aabbox3d part of the createBoxEmitter, it always shows up right in the middle of the ship and then follows the ship. Very cool, but I want to displace it to where the cannonball actually hit and have it follow there. Any of my attempts to put a variable in there really throw off the location of my emitter.
Code: Select all
if (activecannonballs > 0) {
core::vector3df nodePosition = cannonball->getPosition();
core::vector3df shipPosition = shipnode->getPosition();
line.start=nodePosition;
nodePosition.X += cannonballgravity[0] * frameDeltaTime;
nodePosition.Y += cannonballgravity[1] * frameDeltaTime;
nodePosition.Z += cannonballgravity[2] * frameDeltaTime;
cannonballgravity[1] -= gravity * frameDeltaTime;
cannonball->setPosition(nodePosition);
line.end=nodePosition;
if (smgr->getSceneCollisionManager()->getCollisionPoint(line, selector, intersection, tri)){ //there was a hit!
movetheboat = smgr->createFlyStraightAnimator((shipPosition),core::vector3df(shipPosition.X,shipPosition.Y-900,shipPosition.Z), 7000, false);
if (movetheboat)
{
shipnode->addAnimator(movetheboat);
movetheboat->drop();
}
scene::IParticleSystemSceneNode* ps =
smgr->addParticleSystemSceneNode(false,shipnode);
// put smoke on the boat
scene::IParticleEmitter* em = ps->createBoxEmitter(
core::aabbox3d<f32>(-14 , 0, -14, 14, 1, 14), // emitter size
core::vector3df(0.0f,0.3f,0.0f), // initial direction
150,200, // emit rate
video::SColor(0,50,50,50), // darkest color
video::SColor(0,200,200,200), // brightest color
800,2000,0, // min and max age, angle
core::dimension2df(30.f,30.f), // min size
core::dimension2df(80.f,80.f)); // max size
ps->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* paf = ps->createFadeOutParticleAffector(video::SColor(0,255,255,255));
ps->addAffector(paf); // same goes for the affector
paf->drop();
ps->setScale(core::vector3df(4,4,4));
ps->setMaterialFlag(video::EMF_LIGHTING, false);
ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, true);
ps->setMaterialTexture(0, driver->getTexture("./cloud3.png"));
ps->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
}
// dump the cannonball if its gone far enough
float distance=sqrtf(nodePosition.X * nodePosition.X + nodePosition.Y * nodePosition.Y + nodePosition.Z * nodePosition.Z);
if ((nodePosition.Y < -30) || distance > MaxDistance) {
cannonball->remove();
activecannonballs=0;
}
}