main.cpp ///////////// #include #include #include "cgrassnode.h" using namespace irr; int main() { IrrlichtDevice *device = createDevice(video::EDT_OPENGL, core::dimension2d(640, 480), 16, false); device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo"); video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0,100.0f,1200.0f); scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( "../../media/terrain-heightmap.bmp"); terrain->setScale(core::vector3df(10, 4.4f, 10)); CGrassNode * node= new CGrassNode(terrain,smgr,0); terrain->setMaterialFlag(video::EMF_LIGHTING, false); terrain->setMaterialTexture(0, driver->getTexture( "../../media/terrain-texture.jpg")); terrain->setMaterialTexture(1, driver->getTexture( "../../media/detailmap3.jpg")); terrain->setMaterialType(video::EMT_DETAIL_MAP); terrain->scaleTexture(1.0f, 20.0f); int lastFPS = -1; while(device->run()) if (device->isWindowActive()) { driver->beginScene(true, true, 0 ); smgr->drawAll(); driver->endScene(); // display frames per second in window title int fps = driver->getFPS(); if (lastFPS != fps) { core::stringw str = L"Terrain Renderer - Irrlicht Engine ["; str += driver->getName(); str += "] FPS:"; str += fps; device->setWindowCaption(str.c_str()); lastFPS = fps; } } return 0; } /////////////////////// #ifndef CGRASSNODE_H #define CGRASSNODE_H #include using namespace irr; class CGrassNode : public scene::ISceneNode { public: CGrassNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id); ~CGrassNode(); virtual void OnRegisterSceneNode(); virtual void render(); virtual const core::aabbox3d& getBoundingBox() const; virtual u32 getMaterialCount(); virtual video::SMaterial& getMaterial(u32 i); private: static const int grass=10; u32 totalGrass; core::aabbox3d Box; video::S3DVertex GrassModel[4*grass*grass]; video::SMaterial Material; u16 indices[grass*grass*6]; core::vector3df Positions[grass*grass]; u8 Sizes[grass*grass]; }; #endif // CGRASSNODE_H //////////////////// #include "cgrassnode.h" CGrassNode::CGrassNode(scene::ISceneNode* parent, scene::ISceneManager* smgr, s32 id): scene::ISceneNode(parent, smgr, id) { Material.Wireframe = false; Material.Lighting = false; Material.BackfaceCulling= false; core::vector3d*BBPoints=new core::vector3d[8]; core::aabbox3d terrainBB=parent->getBoundingBox(); terrainBB.getEdges(BBPoints); f32 MaxX=BBPoints[4].X; f32 MaxZ=BBPoints[0].Z; f32 MinX=BBPoints[0].X; f32 MinZ=BBPoints[2].Z; f32 lenX=MaxX-MinX; f32 lenZ=MaxZ-MinZ; f32 MaxY=BBPoints[1].Y; f32 MinY=BBPoints[4].Y; f32 lenY=MaxY-MinY; int counter=0; scene::ITriangleSelector* selector; selector= smgr->createTerrainTriangleSelector((scene::ITerrainSceneNode*)parent); parent ->setTriangleSelector(selector); selector->drop(); scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( selector, smgr->getActiveCamera(), core::vector3df(6,10,6), core::vector3df(0,0,0), core::vector3df(0,50,0)); smgr->getActiveCamera()->addAnimator(anim); anim->drop(); for(s32 x=0;x line; smgr->getActiveCamera()->setPosition(core::vector3df(xpos,MaxY,zpos)); smgr->getActiveCamera()->setRotation(core::vector3df(-90,0,0)); line.start = smgr->getActiveCamera()->getPosition(); line.end = line.start + (smgr->getActiveCamera()->getTarget() - line.start).normalize() * 1000000; core::vector3df intersection; core::triangle3df tri; if (smgr->getSceneCollisionManager()->getCollisionPoint( line, selector, intersection, tri)) { Positions[counter]=intersection; f32 nr = tri.getNormal().Y; GrassModel[counter*4] = video::S3DVertex(0+intersection.X,0+intersection.Y,100+intersection.Z, 1,1,0, video::SColor(255,0,255,255), 0, 1); GrassModel[(counter*4)+1] = video::S3DVertex(100+intersection.X,0+intersection.Y,-10+intersection.Z, 1,0,0, video::SColor(255,255,0,255), 1, 1); GrassModel[(counter*4)+2] = video::S3DVertex(0+intersection.X,20+intersection.Y,0+intersection.Z, 0,1,1, video::SColor(255,255,255,0), 1, 0); GrassModel[(counter*4)+3] = video::S3DVertex(-100+intersection.X,0+intersection.Y,-10+intersection.Z, 0,0,1, video::SColor(255,0,255,0), 0, 0); counter+=1; } else { intersection= (core::vector3df(0,0,0)); GrassModel[counter*4] = video::S3DVertex(0+intersection.X,0+intersection.Y,100+intersection.Z, 1,1,0, video::SColor(255,0,255,255), 0, 1); GrassModel[(counter*4)+1] = video::S3DVertex(100+intersection.X,0+intersection.Y,-10+intersection.Z, 1,0,0, video::SColor(255,255,0,255), 1, 1); GrassModel[(counter*4)+2] = video::S3DVertex(00+intersection.X,20+intersection.Y,0+intersection.Z, 0,1,1, video::SColor(255,255,255,0), 1, 0); GrassModel[(counter*4)+3] = video::S3DVertex(-100+intersection.X,0+intersection.Y,-10+intersection.Z, 0,0,1, video::SColor(255,0,255,0), 0, 0); counter+=1; } } } totalGrass=counter; for(int index=0;index<(totalGrass);index++) { indices[index*6]=index*6; indices[(index*6)+1]=(index*6)+1; indices[(index*6)+2]=(index*6)+2; indices[(index*6)+3]=(index*6)+2; indices[(index*6)+4]=index*6; indices[(index*6)+5]=(index*6)+3; printf("%d",counter); } for(int index=0;index<(counter*6);index++) { printf("%d",indices[index]); } Box.reset(GrassModel[0].Pos); for (s32 i=0; iregisterNodeForRendering(this); ISceneNode::OnRegisterSceneNode(); } void CGrassNode::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); driver->setMaterial(Material); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->drawIndexedTriangleList(&GrassModel[0], (totalGrass*6), &indices[0],(totalGrass*2)); } const core::aabbox3d& CGrassNode::getBoundingBox() const { return Box; } u32 CGrassNode::getMaterialCount() { return 1; } video::SMaterial& CGrassNode::getMaterial(u32 i) { return Material; }