| 116 | | osg::Vec3 pos = origin + delta*(float)i; |
| | 144 | osg::Vec3 pos = origin + delta*(float)i + osg::Vec3(0.0f,0.0f,0.0f); |
| | 145 | osg::Vec3 width(characterSize*((float)image->s())/(float)(image->t()),0.0f,0.0); |
| | 146 | osg::Vec3 height(0.0f,0.0f,characterSize); |
| | 147 | |
| | 148 | osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height); |
| | 149 | |
| | 150 | osg::Geode* geode = new osg::Geode; |
| | 151 | geode->addDrawable(geometry); |
| | 152 | |
| | 153 | _livesSwitch->addChild(geode,true); |
| | 154 | |
| | 155 | } |
| | 156 | } |
| | 157 | |
| | 158 | } |
| | 159 | |
| | 160 | void Character::setCatches(const std::string& filename, const osg::Vec3& origin, const osg::Vec3& delta, unsigned int numCatches) |
| | 161 | { |
| | 162 | float characterSize = delta.length(); |
| | 163 | |
| | 164 | _numCatches = 0; |
| | 165 | _catchSwitch = new osg::Switch; |
| | 166 | |
| | 167 | osg::Image* image = osgDB::readImageFile(filename); |
| | 168 | if (image) |
| | 169 | { |
| | 170 | osg::StateSet* stateset = _catchSwitch->getOrCreateStateSet(); |
| | 171 | stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON); |
| | 172 | stateset->setMode(GL_BLEND,osg::StateAttribute::ON); |
| | 173 | stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); |
| | 174 | |
| | 175 | for(unsigned int i=0; i<numCatches; ++i) |
| | 176 | { |
| | 177 | osg::Vec3 pos = origin + delta*(float)i + osg::Vec3(0.0f,0.0f,0.0f); |
| 125 | | _livesSwitch->addChild(geode,true); |
| 126 | | |
| 127 | | } |
| 128 | | } |
| 129 | | |
| 130 | | } |
| 131 | | |
| 132 | | void Character::setCatches(const std::string& filename, const osg::Vec3& origin, const osg::Vec3& delta, unsigned int numCatches) |
| 133 | | { |
| 134 | | float characterSize = delta.length(); |
| 135 | | |
| | 186 | _catchSwitch->addChild(geode,false); |
| | 187 | |
| | 188 | } |
| | 189 | } |
| | 190 | |
| | 191 | } |
| | 192 | |
| | 193 | void Character::moveLeft() |
| | 194 | { |
| | 195 | moveTo(_positionRatio - 0.01f); |
| | 196 | } |
| | 197 | |
| | 198 | void Character::moveRight() |
| | 199 | { |
| | 200 | moveTo(_positionRatio + 0.01f); |
| | 201 | } |
| | 202 | |
| | 203 | void Character::moveTo(float positionRatio) |
| | 204 | { |
| | 205 | if (positionRatio<0.0f) positionRatio = 0.0f; |
| | 206 | if (positionRatio>1.0f) positionRatio = 1.0f; |
| | 207 | |
| | 208 | _positionRatio = positionRatio; |
| | 209 | _character->setPosition(_origin+_width*+positionRatio); |
| | 210 | } |
| | 211 | |
| | 212 | void Character::reset() |
| | 213 | { |
| 137 | | _catchSwitch = new osg::Switch; |
| | 215 | _numLives = _livesSwitch->getNumChildren(); |
| | 216 | |
| | 217 | _livesSwitch->setAllChildrenOn(); |
| | 218 | _catchSwitch->setAllChildrenOff(); |
| | 219 | } |
| | 220 | |
| | 221 | bool Character::addCatch() |
| | 222 | { |
| | 223 | if (!_catchSwitch || _numCatches>=_catchSwitch->getNumChildren()) return false; |
| | 224 | |
| | 225 | _catchSwitch->setValue(_numCatches,true); |
| | 226 | ++_numCatches; |
| | 227 | |
| | 228 | return true; |
| | 229 | } |
| | 230 | |
| | 231 | bool Character::looseLife() |
| | 232 | { |
| | 233 | if (!_livesSwitch || _numLives==0) return true; |
| | 234 | |
| | 235 | --_numLives; |
| | 236 | _livesSwitch->setValue(_numLives,false); |
| | 237 | |
| | 238 | return (_numLives==0); |
| | 239 | } |
| | 240 | |
| | 241 | |
| | 242 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| | 243 | // |
| | 244 | class CatchableObject : public osg::Referenced |
| | 245 | { |
| | 246 | public: |
| | 247 | CatchableObject(); |
| | 248 | |
| | 249 | void setObject(const std::string& filename, const std::string& name, const osg::Vec3& center, float size, const osg::Vec3& direction); |
| | 250 | |
| | 251 | bool anyInside(const osg::Vec3& lower_left, const osg::Vec3& top_right); |
| | 252 | |
| | 253 | bool centerInside(const osg::Vec3& center, float radius); |
| | 254 | |
| | 255 | void explode(); |
| | 256 | |
| | 257 | bool dangerous() { return _dangerous; } |
| | 258 | |
| | 259 | void stop() { _stopped = true; } |
| | 260 | |
| | 261 | bool stopped() { return _stopped; } |
| | 262 | |
| | 263 | void setTimeToRemove(double time) { _timeToRemove=time; } |
| | 264 | |
| | 265 | double getTimeToRemove() { return _timeToRemove; } |
| | 266 | |
| | 267 | bool needToRemove(double time) { return _timeToRemove>=0.0 && time>_timeToRemove; } |
| | 268 | |
| | 269 | osg::ref_ptr<osg::PositionAttitudeTransform> _object; |
| | 270 | osg::Vec3 _velocity; |
| | 271 | float _mass; |
| | 272 | float _radius; |
| | 273 | |
| | 274 | bool _stopped; |
| | 275 | bool _dangerous; |
| | 276 | |
| | 277 | double _timeToRemove; |
| | 278 | |
| | 279 | |
| | 280 | public: |
| | 281 | |
| | 282 | // update position and velocity |
| | 283 | void update(double dt); |
| | 284 | |
| | 285 | /// Set the viscosity of the fluid. |
| | 286 | inline void setFluidViscosity(float v) |
| | 287 | { |
| | 288 | _viscosity = v; |
| | 289 | _viscosityCoefficient = 6 * osg::PI * _viscosity; |
| | 290 | } |
| | 291 | |
| | 292 | /// Get the viscosity of the fluid. |
| | 293 | inline float getFluidViscosity() const { return _viscosity; } |
| | 294 | |
| | 295 | /// Set the density of the fluid. |
| | 296 | inline void setFluidDensity(float d) |
| | 297 | { |
| | 298 | _density = d; |
| | 299 | _densityCoefficeint = 0.2f * osg::PI * _density; |
| | 300 | } |
| | 301 | |
| | 302 | /// Get the density of the fluid. |
| | 303 | inline float getFluidDensity() const { return _density; } |
| | 304 | |
| | 305 | |
| | 306 | /// Set the wind vector. |
| | 307 | inline void setWind(const osg::Vec3& wind) { _wind = wind; } |
| | 308 | |
| | 309 | /// Get the wind vector. |
| | 310 | inline const osg::Vec3& getWind() const { return _wind; } |
| | 311 | |
| | 312 | /// Set the acceleration vector. |
| | 313 | inline void setAcceleration(const osg::Vec3& v) { _acceleration = v; } |
| | 314 | |
| | 315 | /// Get the acceleration vector. |
| | 316 | inline const osg::Vec3& getAcceleration() const { return _acceleration; } |
| | 317 | |
| | 318 | /** Set the acceleration vector to the gravity on earth (0, 0, -9.81). |
| | 319 | The acceleration will be multiplied by the <CODE>scale</CODE> parameter. |
| | 320 | */ |
| | 321 | inline void setToGravity(float scale = 1.0f) { _acceleration.set(0, 0, -9.81f*scale); } |
| | 322 | |
| | 323 | /// Set the fluid parameters as for air (20°C temperature). |
| | 324 | inline void setFluidToAir() |
| | 325 | { |
| | 326 | setToGravity(1.0f); |
| | 327 | setFluidDensity(1.2929f); |
| | 328 | setFluidViscosity(1.8e-5f); |
| | 329 | } |
| | 330 | |
| | 331 | /// Set the fluid parameters as for pure water (20°C temperature). |
| | 332 | inline void setFluidToWater() |
| | 333 | { |
| | 334 | setToGravity(1.0f); |
| | 335 | setFluidDensity(1.0f); |
| | 336 | setFluidViscosity(1.002e-3f); |
| | 337 | } |
| | 338 | |
| | 339 | |
| | 340 | protected: |
| | 341 | |
| | 342 | osg::Vec3 _acceleration; |
| | 343 | float _viscosity; |
| | 344 | float _density; |
| | 345 | osg::Vec3 _wind; |
| | 346 | |
| | 347 | float _viscosityCoefficient; |
| | 348 | float _densityCoefficeint; |
| | 349 | |
| | 350 | }; |
| | 351 | |
| | 352 | CatchableObject::CatchableObject() |
| | 353 | { |
| | 354 | _stopped = false; |
| | 355 | _dangerous = false; |
| | 356 | |
| | 357 | _timeToRemove = -1.0; // do not remove. |
| | 358 | setFluidToAir(); |
| | 359 | } |
| | 360 | |
| | 361 | void CatchableObject::setObject(const std::string& filename, const std::string& name, const osg::Vec3& center, float characterSize, const osg::Vec3& velocity) |
| | 362 | { |
| | 363 | _radius = 0.5f*characterSize; |
| | 364 | float Area = osg::PI*_radius*_radius; |
| | 365 | float Volume = Area*_radius*4.0f/3.0f; |
| | 366 | |
| | 367 | _velocity = velocity; |
| | 368 | _mass = 1000.0*Volume; |
| 144 | | |
| 145 | | for(unsigned int i=0; i<numCatches; ++i) |
| 146 | | { |
| 147 | | osg::Vec3 pos = origin + delta*(float)i; |
| 148 | | osg::Vec3 width(characterSize,0.0f,0.0); |
| 149 | | osg::Vec3 height(0.0f,0.0f,characterSize*((float)image->t())/(float)(image->s())); |
| 150 | | |
| 151 | | osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height); |
| 152 | | |
| 153 | | osg::Geode* geode = new osg::Geode; |
| 154 | | geode->addDrawable(geometry); |
| 155 | | |
| 156 | | _catchSwitch->addChild(geode,false); |
| 157 | | |
| 158 | | } |
| 159 | | } |
| 160 | | |
| 161 | | } |
| 162 | | |
| 163 | | void Character::moveLeft() |
| 164 | | { |
| 165 | | moveTo(_positionRatio - 0.01f); |
| 166 | | } |
| 167 | | |
| 168 | | void Character::moveRight() |
| 169 | | { |
| 170 | | moveTo(_positionRatio + 0.01f); |
| 171 | | } |
| 172 | | |
| 173 | | void Character::moveTo(float positionRatio) |
| 174 | | { |
| 175 | | if (positionRatio<0.0f) positionRatio = 0.0f; |
| 176 | | if (positionRatio>1.0f) positionRatio = 1.0f; |
| 177 | | |
| 178 | | _positionRatio = positionRatio; |
| 179 | | _character->setPosition(_origin+_width*+positionRatio); |
| 180 | | } |
| 181 | | |
| 182 | | void Character::reset() |
| 183 | | { |
| 184 | | _numCatches = 0; |
| 185 | | _numLives = _livesSwitch->getNumChildren(); |
| 186 | | |
| 187 | | _livesSwitch->setAllChildrenOn(); |
| 188 | | _catchSwitch->setAllChildrenOff(); |
| 189 | | } |
| 190 | | |
| 191 | | bool Character::addCatch() |
| 192 | | { |
| 193 | | if (!_catchSwitch || _numCatches>=_catchSwitch->getNumChildren()) return false; |
| 194 | | |
| 195 | | _catchSwitch->setValue(_numCatches,true); |
| 196 | | ++_numCatches; |
| 197 | | |
| | 380 | stateset->setMode(GL_BLEND,osg::StateAttribute::ON); |
| | 381 | stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); |
| | 382 | |
| | 383 | osg::Geode* geode = new osg::Geode; |
| | 384 | geode->addDrawable(geometry); |
| | 385 | |
| | 386 | _object = new osg::PositionAttitudeTransform; |
| | 387 | _object->setName(name); |
| | 388 | _object->addChild(geode); |
| | 389 | _object->setPosition(center); |
| | 390 | } |
| | 391 | |
| | 392 | } |
| | 393 | |
| | 394 | void CatchableObject::update(double dt) |
| | 395 | { |
| | 396 | if (_stopped) return; |
| | 397 | |
| | 398 | float Area = osg::PI*_radius*_radius; |
| | 399 | float Volume = Area*_radius*4.0f/3.0f; |
| | 400 | |
| | 401 | // compute force due to gravity + boyancy of displacing the fluid that the particle is emersed in. |
| | 402 | osg::Vec3 force = _acceleration * (_mass - _density*Volume); |
| | 403 | |
| | 404 | // compute force due to friction |
| | 405 | osg::Vec3 relative_wind = _velocity-_wind; |
| | 406 | force -= relative_wind * Area * (_viscosityCoefficient + _densityCoefficeint*relative_wind.length()); |
| | 407 | |
| | 408 | // divide force by mass to get acceleration. |
| | 409 | _velocity += force*(dt/_mass); |
| | 410 | _object->setPosition(_object->getPosition()+_velocity*dt); |
| | 411 | } |
| | 412 | |
| | 413 | bool CatchableObject::anyInside(const osg::Vec3& lower_left, const osg::Vec3& upper_right) |
| | 414 | { |
| | 415 | osg::Vec3 pos = _object->getPosition(); |
| | 416 | |
| | 417 | if (pos.x()+_radius < lower_left.x()) return false; |
| | 418 | if (pos.x()-_radius > upper_right.x()) return false; |
| | 419 | if (pos.z()+_radius < lower_left.z()) return false; |
| | 420 | if (pos.z()-_radius > upper_right.z()) return false; |
| | 421 | |
| 201 | | bool Character::looseLife() |
| 202 | | { |
| 203 | | if (!_livesSwitch || _numLives==0) return true; |
| 204 | | |
| 205 | | --_numLives; |
| 206 | | _livesSwitch->setValue(_numLives,false); |
| 207 | | |
| 208 | | return (_numLives==0); |
| 209 | | } |
| 210 | | |
| 211 | | |
| 212 | | class SlideEventHandler : public osgGA::GUIEventHandler |
| | 425 | bool CatchableObject::centerInside(const osg::Vec3& center, float radius) |
| | 426 | { |
| | 427 | osg::Vec3 delta = _object->getPosition() - center; |
| | 428 | return (delta.length()<radius); |
| | 429 | } |
| | 430 | |
| | 431 | |
| | 432 | void CatchableObject::explode() |
| | 433 | { |
| | 434 | osg::Vec3 position(0.0f,0.0f,0.0f); |
| | 435 | osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, _radius); |
| | 436 | osgParticle::ExplosionDebriEffect* explosionDebri = new osgParticle::ExplosionDebriEffect(position, _radius); |
| | 437 | osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, _radius); |
| | 438 | osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, _radius); |
| | 439 | |
| | 440 | explosion->setWind(_wind); |
| | 441 | explosionDebri->setWind(_wind); |
| | 442 | smoke->setWind(_wind); |
| | 443 | fire->setWind(_wind); |
| | 444 | |
| | 445 | _object->addChild(explosion); |
| | 446 | _object->addChild(explosionDebri); |
| | 447 | _object->addChild(smoke); |
| | 448 | _object->addChild(fire); |
| | 449 | |
| | 450 | _dangerous = true; |
| | 451 | |
| | 452 | } |
| | 453 | |
| | 454 | |
| | 455 | |
| | 456 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| | 457 | // |
| | 458 | class GameEventHandler : public osgGA::GUIEventHandler |
| | 551 | // move objects |
| | 552 | for(CatchableObjectList::iterator itr=_catchableObjects.begin(); |
| | 553 | itr!=_catchableObjects.end(); |
| | 554 | ++itr) |
| | 555 | { |
| | 556 | (*itr)->update(dt); |
| | 557 | |
| | 558 | bool removeEntry = false; |
| | 559 | |
| | 560 | if ((*itr)->dangerous()) |
| | 561 | { |
| | 562 | if ((*itr)->anyInside(_player1.getLowerLeft(),_player1.getUpperRight())) |
| | 563 | { |
| | 564 | _player1.looseLife(); |
| | 565 | removeEntry = true; |
| | 566 | } |
| | 567 | |
| | 568 | if ((*itr)->anyInside(_player1.getLowerLeft(),_player1.getUpperRight())) |
| | 569 | { |
| | 570 | _player2.looseLife(); |
| | 571 | removeEntry = true; |
| | 572 | } |
| | 573 | } |
| | 574 | else |
| | 575 | { |
| | 576 | if ((*itr)->centerInside(_player1.getCurrentCenterOfBasket(),_player1.getCurrentRadiusOfBasket())) |
| | 577 | { |
| | 578 | _player1.addCatch(); |
| | 579 | removeEntry = true; |
| | 580 | } |
| | 581 | |
| | 582 | if ((*itr)->centerInside(_player2.getCurrentCenterOfBasket(),_player2.getCurrentRadiusOfBasket())) |
| | 583 | { |
| | 584 | _player2.addCatch(); |
| | 585 | removeEntry = true; |
| | 586 | } |
| | 587 | } |
| | 588 | |
| | 589 | |
| | 590 | if (!(*itr)->anyInside(_origin, _origin+_width+_height) || |
| | 591 | (*itr)->needToRemove(ea.time()) || |
| | 592 | removeEntry) |
| | 593 | { |
| | 594 | // need to remove |
| | 595 | // remove child from parents. |
| | 596 | osg::ref_ptr<osg::PositionAttitudeTransform> child = (*itr)->_object; |
| | 597 | osg::Node::ParentList parents = child->getParents(); |
| | 598 | for(osg::Node::ParentList::iterator pitr=parents.begin(); |
| | 599 | pitr!=parents.end(); |
| | 600 | ++pitr) |
| | 601 | { |
| | 602 | (*pitr)->removeChild(child.get()); |
| | 603 | } |
| | 604 | |
| | 605 | // remove child from catchable list |
| | 606 | itr = _catchableObjects.erase(itr); |
| | 607 | |
| | 608 | createNewCatchable(); |
| | 609 | |
| | 610 | } |
| | 611 | else if ((*itr)->anyInside(_origin, _origin+_width) && !(*itr)->stopped()) |
| | 612 | { |
| | 613 | // hit base line |
| | 614 | (*itr)->explode(); |
| | 615 | (*itr)->stop(); |
| | 616 | (*itr)->setTimeToRemove(ea.time()+3.0); |
| | 617 | } |
| | 618 | |
| | 619 | } |
| | 620 | |
| 371 | | osg::Node* SlideEventHandler::createScene() |
| 372 | | { |
| 373 | | |
| 374 | | |
| 375 | | osg::Group* group = new osg::Group; |
| 376 | | |
| 377 | | _player1.setCharacter("Catch/girl.png","girl", _originBaseLine, _widthBaseLine, 0.4f); |
| 378 | | _player1.setLives("Catch/girl.png",_originBaseLine, osg::Vec3(0.0f,0.0f,100.0f),3); |
| 379 | | _player1.setCatches("Catch/a.JPG",_originBaseLine+osg::Vec3(200.0f,0.0f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10); |
| 380 | | group->addChild(_player1._character.get()); |
| 381 | | group->addChild(_player1._livesSwitch.get()); |
| 382 | | group->addChild(_player1._catchSwitch.get()); |
| 383 | | |
| 384 | | _player2.setCharacter("Catch/boy.png","boy", _originBaseLine, _widthBaseLine, 0.4f); |
| 385 | | _player2.setLives("Catch/boy.png",_originBaseLine+osg::Vec3(900.0f,0.0f,000.0f), osg::Vec3(0.0f,0.0f,100.0f),3); |
| 386 | | _player2.setCatches("Catch/b.JPG",_originBaseLine+osg::Vec3(1100.0f,0.0f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10); |
| 387 | | group->addChild(_player2._character.get()); |
| 388 | | group->addChild(_player2._livesSwitch.get()); |
| 389 | | group->addChild(_player2._catchSwitch.get()); |
| 390 | | |
| 391 | | |
| | 696 | osg::Node* GameEventHandler::createScene() |
| | 697 | { |
| | 698 | _group = new osg::Group; |
| | 699 | |
| | 700 | // _player1.setCharacter("Catch/girl.png","girl", _originBaseLine, _widthBaseLine, 0.4f); |
| | 701 | _player1.setCharacter("Catch/gwen.png","girl", _originBaseLine + osg::Vec3(0.0f,-1.0f,0.0f), _widthBaseLine, 0.4f); |
| | 702 | _player1.setLives("Catch/gwen.png",_originBaseLine+osg::Vec3(0.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),3); |
| | 703 | _player1.setCatches("Catch/broach.png",_originBaseLine+osg::Vec3(200.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10); |
| | 704 | _group->addChild(_player1._character.get()); |
| | 705 | _group->addChild(_player1._livesSwitch.get()); |
| | 706 | _group->addChild(_player1._catchSwitch.get()); |
| | 707 | |
| | 708 | // _player2.setCharacter("Catch/boy.png","boy", _originBaseLine, _widthBaseLine, 0.4f); |
| | 709 | // _player2.setLives("Catch/boy.png",_originBaseLine+osg::Vec3(900.0f,0.0f,000.0f), osg::Vec3(0.0f,0.0f,100.0f),3); |
| | 710 | _player2.setCharacter("Catch/caitlin.png","boy", _originBaseLine + osg::Vec3(0.0f,-2.0f,0.0f), _widthBaseLine, 0.4f); |
| | 711 | _player2.setLives("Catch/caitlin.png",_originBaseLine+osg::Vec3(900.0f,-0.5f,000.0f), osg::Vec3(0.0f,0.0f,100.0f),3); |
| | 712 | _player2.setCatches("Catch/broach.png",_originBaseLine+osg::Vec3(1100.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10); |
| | 713 | _group->addChild(_player2._character.get()); |
| | 714 | _group->addChild(_player2._livesSwitch.get()); |
| | 715 | _group->addChild(_player2._catchSwitch.get()); |
| | 716 | |
| | 717 | |
| | 718 | createNewCatchable(); |
| | 719 | createNewCatchable(); |
| | 720 | createNewCatchable(); |
| | 721 | createNewCatchable(); |
| | 722 | |
| 409 | | |
| 410 | | return group; |
| 411 | | } |
| 412 | | |
| | 740 | return _group.get(); |
| | 741 | } |
| | 742 | |
| | 743 | void GameEventHandler::createNewCatchable() |
| | 744 | { |
| | 745 | float ratio = ((float)rand() / (float)RAND_MAX); |
| | 746 | float size = 100.0f*((float)rand() / (float)RAND_MAX); |
| | 747 | float angle = osg::PI*0.25f + 0.5f*osg::PI*((float)rand() / (float)RAND_MAX); |
| | 748 | float speed = 200.0f*((float)rand() / (float)RAND_MAX); |
| | 749 | |
| | 750 | CatchableObject* catchableObject = new CatchableObject; |
| | 751 | osg::Vec3 position = _origin+_height+_width*ratio + osg::Vec3(0.0f,-0.7f,0.0f); |
| | 752 | osg::Vec3 velocity(-cosf(angle)*speed,0.0f,-sinf(angle)*speed); |
| | 753 | //std::cout<<"angle = "<<angle<<" velocity="<<velocity<<std::endl; |
| | 754 | catchableObject->setObject("Catch/a.png","boy",position,size,velocity); |
| | 755 | _catchableObjects.push_back(catchableObject); |
| | 756 | |
| | 757 | // catchableObject->explode(); |
| | 758 | |
| | 759 | _group->addChild(catchableObject->_object.get()); |
| | 760 | } |