CWayPoint::CWayPoint() { m_objectType = CGameObject::WaypointObject; m_next = NULL; m_back = NULL; m_timeWait = 0; ISceneManager *smgr = getIView()->getSceneMgr(); // init waypoint mesh //CColladaMeshComponent *comp = new CColladaMeshComponent( this ); //comp->loadFromFile( getIView()->getPath("data/editor/waypoint.dae") ); //addComponent( comp ); //setLighting( false ); m_node = new CGameBoxSceneNode(this, 5, smgr->getRootSceneNode(), smgr, (s32)m_objectID); m_node->getMaterial(0).Lighting = true; #ifdef GSEDITOR setVisible ( true ); // add collision ITriangleSelector *selector = smgr->createTriangleSelectorFromBoundingBox( m_node ); m_node->setTriangleSelector(selector); selector->drop(); #else setVisible ( false ); #endif }
CGameCamera::CGameCamera() { m_targetObject = NULL; m_objectType = CGameObject::CameraObject; #ifdef GSEDITOR m_cameraMesh = NULL; #endif ISceneManager *smgr = getIView()->getSceneMgr(); // save old camera ICameraSceneNode *oldCam = smgr->getActiveCamera(); // create new camera m_camera = smgr->addCameraSceneNode(); m_camera->setFOV( core::degToRad(60.0f) ); m_camera->setFarValue( 8000.0f ); m_camera->grab(); core::vector3df pos(0,0,0); setPosition( pos ); core::vector3df target(1,0,0); setTarget( target ); #ifdef GSEDITOR CColladaMeshComponent *comp = new CColladaMeshComponent( this ); comp->loadFromFile( getIView()->getPath("data/editor/camera.dae") ); addComponent( comp ); setLighting( false ); m_cameraMesh = m_node; m_cameraMesh->setVisible( true ); ITriangleSelector *selector = smgr->createTriangleSelectorFromBoundingBox( m_cameraMesh ); m_cameraMesh->setTriangleSelector(selector); selector->drop(); #endif // set camera node m_node = m_camera; // restore camera smgr->setActiveCamera( oldCam ); m_animator = NULL; #ifndef GSGAMEPLAY setEditorCamera(); #else setFreeCamera(); #endif }
bool RenderComponent::createTriangleSelector( SelectorInfo info ) { ITriangleSelector* sel = nullptr; if (info.type == BoundingBox) { ISceneNode* node = getNode(); ISceneManager* smgr = node->getSceneManager(); if (sel = smgr->createTriangleSelectorFromBoundingBox(node)) node->setTriangleSelector(sel); } return sel != nullptr; }
// init // run when init object void CPlayerComponent::initComponent() { m_collada = (CColladaMeshComponent*)m_gameObject->getComponent( IObjectComponent::ColladaMesh ); // load model by character id CGameConfig::SCharacterInfo *charInfo = CGameConfig::getInstance()->getCharacterInfo(m_charID); // load model m_collada->loadScene(charInfo->model.c_str() ); // load animation CColladaAnimationFactory* animFactory = CColladaAnimationFactory::getInstance(); m_animationPackage = animFactory->getAnimation( charInfo->name.c_str() ); if ( m_animationPackage == NULL ) m_animationPackage = animFactory->loadAnimation( charInfo->name.c_str(), getIView()->getPath(charInfo->anim)); m_collada->setAnimationPackage( m_animationPackage ); // apply lod for (int i = 0, n = (int)charInfo->lods.size(); i < n; i++) m_collada->addLodData( charInfo->lods[i].distance, charInfo->lods[i].node.c_str() ); init(m_gameObject); // register event getIView()->registerEvent("CPlayerComponent", this); // init lua player component char luaObjName[64]; sprintf(luaObjName, "CPlayerComp_%ld", m_gameObject->getID()); m_luaObjName = luaObjName; // init collision ISceneManager *smgr = getIView()->getSceneMgr(); ITriangleSelector *selector = smgr->createTriangleSelectorFromBoundingBox(m_gameObject->getSceneNode()); m_gameObject->getSceneNode()->setTriangleSelector(selector); selector->drop(); CGameObject *zone = (CGameObject*)m_gameObject->getParent(); if ( zone && zone->getObjectType() == CGameObject::ZoneObject ) ((CZone*)zone)->registerCollideObj( m_gameObject); }
// init // run when init object void CObjectCollisionComponent::initComponent() { #ifdef GSGAMEPLAY IMesh *pMesh = NULL; ISceneNode *node = m_gameObject->getSceneNode(); ISceneManager *smgr = getIView()->getSceneMgr(); if ( node == NULL ) return; std::vector<SObjectCollisionParam> listMesh; SObjectCollisionParam temp; if ( m_gameObject->getComponent( IObjectComponent::StaticMesh ) != NULL ) { pMesh = ((IMeshSceneNode*) node)->getMesh(); temp.mesh = pMesh; temp.node = node; listMesh.push_back( temp ); } else if ( m_gameObject->getComponent( IObjectComponent::AnimMesh ) != NULL ) { pMesh = ((IAnimatedMeshSceneNode*) node)->getMesh(); temp.mesh = pMesh; temp.node = node; listMesh.push_back( temp ); } else if ( m_gameObject->getComponent( IObjectComponent::ColladaMesh ) != NULL ) { CColladaMeshComponent *comp = (CColladaMeshComponent*)m_gameObject->getComponent( IObjectComponent::ColladaMesh ); ISceneNode* colladaNode = comp->getColladaNode(); std::queue<ISceneNode*> listSceneNode; const core::list<ISceneNode*>* listChild = &colladaNode->getChildren(); core::list<ISceneNode*>::ConstIterator it = listChild->begin(), end = listChild->end(); while ( it != end ) { listSceneNode.push( (*it) ); it++; } while ( listSceneNode.size() ) { CGameColladaSceneNode* sceneNode = (CGameColladaSceneNode*)listSceneNode.front(); listSceneNode.pop(); if ( sceneNode->getMesh() ) { temp.mesh = sceneNode->getMesh(); temp.node = sceneNode; listMesh.push_back( temp ); } const core::list<ISceneNode*>* listChild = &sceneNode->getChildren(); it = listChild->begin(); end = listChild->end(); while ( it != end ) { listSceneNode.push( (*it) ); it++; } } } for ( int i = 0; i < (int)listMesh.size(); i++ ) { node = listMesh[i].node; pMesh = listMesh[i].mesh; switch ( m_collisionType ) { case CObjectCollisionComponent::BoudingBox: { ITriangleSelector *selector = smgr->createTriangleSelectorFromBoundingBox(node); node->setTriangleSelector( selector ); selector->drop(); } break; case CObjectCollisionComponent::Triangle: { ITriangleSelector* selector = smgr->createTriangleSelector( pMesh, node ); node->setTriangleSelector(selector); selector->drop(); } break; case CObjectCollisionComponent::OctreeTriange: { ITriangleSelector* selector = smgr->createOctreeTriangleSelector( pMesh, node ); node->setTriangleSelector(selector); selector->drop(); } break; } } #endif }
/** Test that collision response animator will reset itself when removed from a scene node, so that the scene node can then be moved without the animator jumping it back again. */ bool collisionResponseAnimator(void) { IrrlichtDevice * device = irr::createDevice(video::EDT_NULL); assert(device); if(!device) return false; ISceneManager * smgr = device->getSceneManager(); // Create 2 nodes to the left of a "wall" ISceneNode * testNode1 = smgr->addEmptySceneNode(); ISceneNode * testNode2 = smgr->addEmptySceneNode(); testNode1->setPosition(vector3df(-50, 0,0)); testNode2->setPosition(vector3df(-50, 0,0)); // Create a "wall" node, and collision response animators for each test node. IMeshSceneNode * wallNode = smgr->addCubeSceneNode(10.f); ITriangleSelector * wallSelector = smgr->createTriangleSelectorFromBoundingBox(wallNode); ISceneNodeAnimatorCollisionResponse * collisionAnimator1 = smgr->createCollisionResponseAnimator(wallSelector, testNode1, vector3df(10,10,10), vector3df(0, 0, 0)); testNode1->addAnimator(collisionAnimator1); CMyCollisionCallback collisionCallback; collisionAnimator1->setCollisionCallback(&collisionCallback); collisionAnimator1->drop(); collisionAnimator1 = 0; ISceneNodeAnimatorCollisionResponse * collisionAnimator2 = smgr->createCollisionResponseAnimator(wallSelector, testNode2, vector3df(10,10,10), vector3df(0, 0, 0)); testNode2->addAnimator(collisionAnimator2); collisionAnimator2->setCollisionCallback(&collisionCallback); wallSelector->drop(); // Don't drop() collisionAnimator2 since we're going to use it. // Get the system in a good state device->run(); smgr->drawAll(); // Try to move both nodes to the right of the wall. // This one should be stopped by its animator. testNode1->setPosition(vector3df(50, 0,0)); collisionCallback.setNextExpectedCollision(testNode1, vector3df(-5.005f, 0, 0), vector3df(-15.005f, 0, 0), false); // Whereas this one, by forcing the animator to update its target node, should be // able to pass through the wall. (In <=1.6 it was stopped by the wall even if // the animator was removed and later re-added); testNode2->setPosition(vector3df(50, 0,0)); collisionAnimator2->setTargetNode(testNode2); collisionAnimator2->drop(); // We're done using this now. device->run(); smgr->drawAll(); bool result = true; if(testNode1->getAbsolutePosition().X > -15.f) { logTestString("collisionResponseAnimator test node 1 wasn't stopped from moving.\n"); assert(false); result = false; } if(testNode2->getAbsolutePosition().X < 50.f) { logTestString("collisionResponseAnimator test node 2 was stopped from moving.\n"); assert(false); result = false; } // Now try to move the second node back through the wall again. Now it should be // stopped by the wall. testNode2->setPosition(vector3df(-50, 0, 0)); // We'll consume this collision, so the node will actually move all the way through. collisionCallback.setNextExpectedCollision(testNode2, vector3df(5.005f, 0, 0), vector3df(15.005f, 0, 0), true); device->run(); smgr->drawAll(); if(testNode2->getAbsolutePosition().X != -50.f) { logTestString("collisionResponseAnimator test node 2 was stopped from moving.\n"); assert(false); result = false; } // Now we'll try to move it back to the right and allow it to be stopped. collisionCallback.setNextExpectedCollision(testNode2, vector3df(-5.005f, 0, 0), vector3df(-15.005f, 0, 0), false); testNode2->setPosition(vector3df(50, 0, 0)); device->run(); smgr->drawAll(); if(testNode2->getAbsolutePosition().X > -15.f) { logTestString("collisionResponseAnimator test node 2 moved too far.\n"); assert(false); result = false; } device->drop(); result &= expectedCollisionCallbackPositions; return result; }
int main() { const int nRobots = 2; //given robot numbers will be controlled by humans vector<int> humanBrainIds; //humanBrainIds.push_back(1); //humanBrainIds.push_back(0); //-- device ------------------------------------------------------------// IrrlichtDevice* device; device = createDevice( EDT_OPENGL, //driverType windowSize, 16, //bits false, false, //stencilbuffer false, //vsync NULL //receiver ); //advanced device params //SIrrlichtCreationParameters params; //params.DeviceType = EIDT_CONSOLE; //params.DriverType = EDT_OPENGL; //params.WindowSize = windowSize; //device = createDeviceEx(params); if (device == 0) return EXIT_FAILURE; // could not create selected driver. IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); //-- lights ------------------------------------------------------------// //ambient light //smgr->setAmbientLight( SColorf(1.0f,1.0f,1.0f,1.0f) ); //smgr->setAmbientLight( SColorf(.3f,.3f,.3f,1.0f) ); //diffusive light SLight light_data; light_data.AmbientColor = SColorf(.3,.3,.3); //light_data.Attenuation = vector3df(.3,.3,.3); //Attenuation cte, linear quadratic TODO ?? light_data.DiffuseColor = SColorf(.0,.0,.0); light_data.SpecularColor = SColorf(.0,.0,.0); light_data.CastShadows = true; light_data.Radius = 100.0f; light_data.Type = ELT_DIRECTIONAL; //ELT_POINT point light, it has a position in space and radiates light in all directions //ELT_SPOT spot light, it has a position in space, a direction, and a limited cone of influence //ELT_DIRECTIONAL directional light, coming from a direction from an infinite distance ILightSceneNode* light = smgr->addLightSceneNode(0, core::vector3df(.5f,.0f,.5f)); light->setLightData(light_data); //-- objects ------------------------------------------------------------// IMesh* mesh; ISceneNode * node; float HEIGHT=1000.f, WIDTH=1.f; //height between center/sky == height bottom/center //large so that scene looks 2d on interactive test mode. //on automatic mode, only middle pixel row is taken, so this does not matter //outter boundary //square node = smgr->addCubeSceneNode( 2.f*WIDTH, // width 0, // parent -1, // id vector3df(0, 0, 0), // center vector3df(0, 0, 0), // rotation vector3df(1.0f, HEIGHT, 1.0f)*-1.f // scale. *-1 turns it inside out. to use both faces make two cubes. ); //circle //mesh = smgr->getGeometryCreator()->createCylinderMesh( //1.f, //radius //1., //length //50, //tesselation //SColor(0,0,0,255), //color //false, //closeTop //0.f //oblique //); //node = smgr->addMeshSceneNode( //mesh, //0, //ISceneNode * parent //-1, //s32 id //vector3df(0, -HEIGHT, 0), //const core::vector3df & position //vector3df(0, 0, 0), //const core::vector3df & rotation //vector3df(1.0f, 2.f*HEIGHT, 1.0f) //const core::vector3df & scale //); node->getMaterial(0).AmbientColor.set(0,0,0,0); node->getMaterial(0).DiffuseColor.set(0,0,0,0); //node->getMaterial(0).SpecularColor.set(255,255,255,255); //node->getMaterial(0).Shininess = 20.0f; //node->getMaterial(0).EmissiveColor.set(0,0,0,0); //node->setMaterialFlag(EMF_WIREFRAME,true); //wireframe only //left cube node = smgr->addCubeSceneNode( 0.2, // width 0, // parent -1, // id vector3df(-.3, 0, 0), // center vector3df(0, 0, 0), // rotation vector3df(1.0f, HEIGHT, 1.0f) // scale ); node->getMaterial(0).AmbientColor.set(0,255,0,0); node->getMaterial(0).DiffuseColor.set(0,255,0,0); //right cube node = smgr->addCubeSceneNode( .2f, // width 0, // parent -1, // id vector3df(.3, 0, 0), // center vector3df(0, 0, 0), // rotation vector3df(1.0f, HEIGHT, 1.0f) // scale ); node->getMaterial(0).AmbientColor.set(0,0,255,0); node->getMaterial(0).DiffuseColor.set(0,0,255,0); //cylinder //mesh = smgr->getGeometryCreator()->createCylinderMesh( //.1f, //radius //1., //length //50, //tesselation //SColor(), //color //false, //closeTop //0.f //oblique //); //node = smgr->addMeshSceneNode( //mesh, //0, //ISceneNode * parent //-1, //s32 id //vector3df(0, -HEIGHT, 0), //const core::vector3df & position //vector3df(0, 0, 0), //const core::vector3df & rotation //vector3df(1.0f, 2.*HEIGHT, 1.0f) //const core::vector3df & scale //); //node->getMaterial(0).AmbientColor.set(0,0,0,255); //node->getMaterial(0).DiffuseColor.set(0,0,0,255); //sphere //node = smgr->addSphereSceneNode( //0.1, // radius //50, // poly count //0, // parent //FruitID, // id //vector3df(0, 0, 0), // center //vector3df(0, 0, 0), // rotation //vector3df(1.0f, 1.0f, 1.0f) // scale //); //node->getMaterial(0).AmbientColor.set(0,0,0,255); //node->getMaterial(0).DiffuseColor.set(0,0,0,255); //node->getMaterial(0).Lighting = true; //-- collision ------------------------------------------------------------// /* Put everything we want to do collision checking with inside the meta selector. */ IMetaTriangleSelector * meta = smgr->createMetaTriangleSelector(); array<ISceneNode *> nodes; smgr->getSceneNodesFromType(ESNT_ANY, nodes); // Find all nodes for (u32 i=0; i < nodes.size(); ++i) { ISceneNode * node = nodes[i]; ITriangleSelector * selector = 0; switch(node->getType()) { case ESNT_CUBE: case ESNT_ANIMATED_MESH: // Because the selector won't animate with the mesh, // and is only being used for camera collision, we'll just use an approximate // bounding box instead of ((IAnimatedMeshSceneNode*)node)->getMesh(0) selector = smgr->createTriangleSelectorFromBoundingBox(node); break; case ESNT_MESH: case ESNT_SPHERE: // Derived from IMeshSceneNode selector = smgr->createTriangleSelector(((IMeshSceneNode*)node)->getMesh(), node); break; case ESNT_TERRAIN: selector = smgr->createTerrainTriangleSelector((ITerrainSceneNode*)node); break; case ESNT_OCTREE: selector = smgr->createOctreeTriangleSelector(((IMeshSceneNode*)node)->getMesh(), node); break; default: // Don't create a selector for this node type break; } if(selector) { // Add it to the meta selector, which will take a reference to it meta->addTriangleSelector(selector); // And drop my reference to it, so that the meta selector owns it. selector->drop(); } } //-- robots ------------------------------------------------------------// //create robots Fly2D::Brain* brains[nRobots]; //all to a default type //for ( int i=0; i<nRobots; i++ ) //{ //brains[i] = new Fly2D::BrainForward; ////brains[i] = new Fly2D::BrainCircle(); //} brains[0] = new Fly2D::BrainForward; brains[1] = new Fly2D::BrainForward; //decide human control vector<Fly2D::BrainHuman*> hBrains; for ( vector<int>::iterator i = humanBrainIds.begin(); i != humanBrainIds.end(); ++i ) { if ( *i > nRobots ) { cerr << "no such robot: " << *i << endl; exit(EXIT_FAILURE); } delete brains[*i]; Fly2D::BrainHuman* hBrain = new Fly2D::BrainHuman; brains[*i] = hBrain; hBrains.push_back(hBrain); } Fly2D::ReceiverHuman hReceiver = Fly2D::ReceiverHuman( hBrains ); device->setEventReceiver( &hReceiver ); Robot* robots[nRobots]; robots[0] = new Fly2D::Robot( *device, *meta, *brains[0], vector3df(0,0,-0.5f), vector3df(0,0, 0.5f), 0.01 ); robots[1] = new Fly2D::Robot( *device, *meta, *brains[1], vector3df(0,0,0.5f), vector3df(0,0, -0.5f), 0.01 ); meta->drop(); // As soon as we're done with the selector, drop it. //-- run ------------------------------------------------------------// //TEST vector3df oldpos, oldtarget; //END TEST int nFrames = 0; ITimer* timer = device->getTimer(); int t0 = timer->getTime(); int w = driver->getScreenSize().Width; int h = driver->getScreenSize().Height; int dh = h/nRobots; int observeRobot = 0; while(device->run()) { //if (device->isWindowActive()) //only work if window has focus. //draw driver->setViewPort(rect<s32>(0,0,w,h)); driver->beginScene(true,true,0); for(int i=0; i<nRobots; i++) { driver->setViewPort(rect<s32>(0,dh*i,w,dh*(i+1))); //only part of window gets drawn into smgr->setActiveCamera(robots[i]->camera); smgr->drawAll(); //draws on window scene of active camera robots[i]->update(); } driver->endScene(); //TEST //if //( //robots[observeRobot].getPosition() != oldpos //|| robots[observeRobot].getTarget() != oldtarget //) //oldpos = robots[observeRobot].getPosition(); //oldtarget = robots[observeRobot].getTarget(); cout << robots[observeRobot]->str(); //FPS info //cout << "frame no:" << endl << nFrames << endl;; //cout << "average fps:" << endl << 1000*nFrames/(float)(timer->getTime()-t0) << endl; //nFrames++; cout << "fps:" << endl << driver->getFPS() << endl; //END TEST } device->drop(); return 0; }
int main(int argc, char** argv) { CustomEventReceiver receiver; IrrlichtDevice *device = createDevice( video::EDT_OPENGL, dimension2d<u32>(800, 600), 16, false, false, false, &receiver); if (!device) { return EXIT_FAILURE; } device->setWindowCaption(L"Solar System Simulator"); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* sceneManager = device->getSceneManager(); scene::ISceneCollisionManager* collisionManager= sceneManager->getSceneCollisionManager(); IGUIEnvironment* guiEnv = device->getGUIEnvironment(); guiEnv->addStaticText(L"Click on a planet to attach the camera to it", rect<s32>(10,10,260,22), false); sf::SoundBuffer buffer; if (buffer.loadFromFile(currentPath() + "/sounds/burning.aif")) { sf::Listener::setPosition(0, 0,0); sf::Sound sound; sound.setBuffer(buffer); sound.setPosition(0, 0, 0); sound.setLoop(true); sound.play(); } const char* spaceTexturePath = ( currentPath() + "/textures/space.jpg" ).c_str(); video::ITexture* space = driver->getTexture(spaceTexturePath); scene::ISceneNode* skybox = sceneManager->addSkyBoxSceneNode(space, space, space, space, space, space); sceneManager->addLightSceneNode(0, vector3df(0, 0, -50), video::SColorf(1.0f, 1.0f, 1.0f), 50.0f, 1001); PlanetFactory planetFactory(sceneManager, driver); Planet sun = planetFactory.create(PlanetId::Sun); Planet earth = planetFactory.create(PlanetId::Earth); Planet pluto = planetFactory.create(PlanetId::Pluto); Planet jupiter = planetFactory.create(PlanetId::Jupiter); Planet uranus = planetFactory.create(PlanetId::Uranus); Planet neptune = planetFactory.create(PlanetId::Neptune); vector<Planet> planets = { sun, planetFactory.create(PlanetId::Mercury) }; planets.push_back(planetFactory.create(PlanetId::Venus)); planets.push_back(earth); planets.push_back(planetFactory.create(PlanetId::Mars)); planets.push_back(jupiter); planets.push_back(planetFactory.create(PlanetId::Saturn)); planets.push_back(uranus); planets.push_back(neptune); planets.push_back(pluto); ICameraSceneNode* camera = sceneManager->addCameraSceneNode(0, vector3df(0,0,40), vector3df(0,0,0)); rect<s32> mainCameraViewPortRect(0, 0, 800, 600); ICameraSceneNode* topViewCamera = sceneManager->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0)); sceneManager->setAmbientLight(video::SColorf(255.0,255.0,255.0)); ISceneNode* selectedNode = sun.node; while(device->run()) { if(receiver.GetMouseState().LeftButtonDown) { position2di mousepos = receiver.GetMouseState().Position; line3df ray = sceneManager->getSceneCollisionManager()->getRayFromScreenCoordinates( mousepos, camera); vector3df intersection; triangle3df tri; for(Planet& planet : planets) { ITriangleSelector* wselector = sceneManager->createTriangleSelectorFromBoundingBox(planet.node); if (collisionManager->getCollisionPoint(ray, wselector, intersection, tri, planet.node)) { selectedNode = planet.node; } wselector->drop(); } } camera->setTarget(selectedNode->getAbsolutePosition()); skybox->setVisible(true); driver->setViewPort(mainCameraViewPortRect); driver->beginScene(true, true, SColor(255,100,101,140)); sceneManager->setActiveCamera(camera); sceneManager->drawAll(); guiEnv->drawAll(); driver->setViewPort(rect<s32>(0, 380, 200, 600)); driver->draw2DRectangle(SColor(100,0,0,190), mainCameraViewPortRect); skybox->setVisible(false); sceneManager->setActiveCamera(topViewCamera); sceneManager->drawAll(); driver->endScene(); } device->drop(); return EXIT_SUCCESS; }