Пример #1
0
  void Entity::loadMesh(char *filename, bool planar, bool hwSkin, int skinSpeed)
  {
	if(type == MESH_TYPE || type == MAP_TYPE)
	{
      IAnimatedMesh *mesh;
      mesh = Scene->getMesh(filename);
      if(planar == true)
      {
        Scene->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.003f);
      }

      tmesh = Scene->getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0));

      sceneNode = Scene->addMeshSceneNode(tmesh);
      sceneNode->setMaterialFlag(EMF_LIGHTING, lit);
	}
	else if(type == ANIM_TYPE)
	{
	  mesh = Scene->getMesh(filename);
      if(planar == true)
      {
        Scene->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.003f);
      }
      Scene->getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0));

	  animNode = Scene->addAnimatedMeshSceneNode(mesh);
	  animNode->setMaterialFlag(EMF_LIGHTING, lit);

	  if(hwSkin)
		  //hwSkinInstance.getInstance->setupNode(irrlicht, animNode);
		  HWSkinCB::getInstance()->setupNode(irrlicht, animNode, 60);
	}
  }
Пример #2
0
/*----------------------------------------------------------------------------*/
void OcclusionCulling::loadLeaf(s16 n)
{
  //printf(" >> loading leaf %d %d mdls\n", n, world[n].mdl.size());
  // load and models of this leaf
  for (u16 i=0; i < world[n].mdl.size(); i++)
  {
     u16 id = world[n].mdl[i]->id;
     //printf(" >> load mdl %d [%s]\n", id, listMDL[id]);
     IAnimatedMesh* mesh = smgr->getMesh(listMDL[id]);
     world[n].mdl[i]->node = smgr->addAnimatedMeshSceneNode(mesh);
     if (world[n].mdl[i]->node)
     {
       world[n].mdl[i]->node->setPosition(world[n].mdl[i]->pos);
       world[n].mdl[i]->node->setRotation(vector3df(0,world[n].mdl[i]->angle,world[n].mdl[i]->upvector));
     }
     mesh->drop();
  }

  // create light

  // apply shaders

  // set collision

}
Пример #3
0
IAnimatedMesh* CPingPangMeshLoader::createMesh(
    IReadFile* file
    )
{
	IAnimatedMesh* msh = 0;

	if( strstr( file->getFileName(), ".md2" ) )
	{
		msh = new CPingPangMD2XMesh();
		if( ((CPingPangMD2XMesh*)msh)->loadFile( file ) )
			return msh;

		msh->drop();
	}
	else if( strstr( file->getFileName(), ".sam" ) )
	{
		msh = new CPingPangSAMMesh();
		if( ((CPingPangSAMMesh*)msh)->loadFile( file ) )
			return msh;

		msh->drop();
	}
	// Modified by Huang Liang
	else if ( strstr( file->getFileName(), ".ms3d" ) )
	{
		msh = new irr::scene::sklani::CSkeletonAni(m_driver);
//		if ( ((irr::scene::sklani::CSkeletonAni*)msh)->LoadOldMs3Mesh(file) )
		if ( ((irr::scene::sklani::CSkeletonAni*)msh)->Import(file) )
			return msh;
	}
	// Modified end

	return 0;
}
Пример #4
0
//! Reads attributes of the scene node.
void COctTreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	const s32 oldMinimal = MinimalPolysPerNode;

	MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode");
	core::stringc newMeshStr = in->getAttributeAsString("Mesh");

	IMesh* newMesh = 0;

	if (newMeshStr == "")
		newMeshStr = MeshName;

	IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());

	if (newAnimatedMesh)
		newMesh = newAnimatedMesh->getMesh(0);

	if (newMesh && ((MeshName != newMeshStr) || (MinimalPolysPerNode != oldMinimal)))
	{
		// recalculate tree
		createTree(newMesh);
	}

	ISceneNode::deserializeAttributes(in, options);
}
Пример #5
0
int main()
{
    // we'll use the OGL driver
	IrrlichtDevice *device =
		createDevice(EDT_OPENGL, dimension2du(640, 480), 16,
			false, false, false, 0);

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();

    // load sydney
	IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
    // squash her!
	CSquashingMeshSceneNode* node = new CSquashingMeshSceneNode( mesh->getMesh(0), 0, smgr, 0 );


	if (node)
	{
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setPosition( vector3df(0,0,50));
		node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
	}

	smgr->addCameraSceneNodeFPS();

    int lastFPS = -1;

	while(device->run())
	{
		driver->beginScene(true, true, SColor(255,100,101,140));

        node->render();
        node->OnPostRender(device->getTimer()->getTime());

		smgr->drawAll();
		guienv->drawAll();

		driver->endScene();

		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			core::stringw str = L"Irrlicht Mesh Deformation Contest [";
			str += driver->getName();
			str += "] FPS:";
			str += fps;

			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}


	}

	device->drop();

	return 0;
}
Пример #6
0
Scenario::Scenario(IrrlichtDevice* dev, stringc file, stringc mapName)
{
    device = dev;

    device->getFileSystem()->addZipFileArchive(file.c_str());

    IAnimatedMesh* mesh = device->getSceneManager()->getMesh(mapName.c_str());

    ISceneNode* node = device->getSceneManager()->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);

}
Пример #7
0
  void Entity::loadBsp(char *filename)
  {
    if(type == MESH_TYPE || type == MAP_TYPE)
    {
      IAnimatedMesh *mesh = Scene->getMesh(filename);

      sceneNode = Scene->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
      sceneNode->setMaterialFlag(EMF_LIGHTING, true);

      bmesh = mesh;
    }
  }
Пример #8
0
//------------------------------------------------------------------------------
//! GetMeshFromGeom
//! Helper function to extract mesh data from object geometry
IMesh* CBulletObjectAnimator::GetMeshFromGeom(ISceneManager* pSceneManager,
  CBulletObjectAnimatorGeometry* pGeom)
{
  IMesh* mesh = pGeom->mesh.irrMesh;
  if (mesh == NULL)
  {
    IAnimatedMesh* animMesh = pSceneManager->getMesh(pGeom->meshFile.c_str());
    if (animMesh != NULL)
      mesh = animMesh->getMesh(0);
  }

  return mesh;
}
Пример #9
0
//! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information.
IAnimatedMesh* CMD2MeshFileLoader::createMesh(io::IReadFile* file)
{
	IAnimatedMesh* msh = new CAnimatedMeshMD2();
	if (msh)
	{
		if (loadFile(file, (CAnimatedMeshMD2*)msh) )
			return msh;

		msh->drop();
	}

	return 0;
}
Пример #10
0
void viewprt::createGround()
{
   // Try to add a ground plane grid
   scene::ISceneManager* smgr = device->getSceneManager();
   video::IVideoDriver* driver = device->getVideoDriver();
   IAnimatedMesh *plane = smgr->addHillPlaneMesh("test",core::dimension2d<f32>(20,20),core::dimension2d<u32>(60,60));
   ground = smgr->addWaterSurfaceSceneNode(plane->getMesh(0), 0.0f, 1000, 10);
   ground->setPosition(core::vector3df(0,-1,0));
   ground->setMaterialFlag(EMF_LIGHTING,false);
   ground->setMaterialFlag(EMF_BACK_FACE_CULLING,false);
   ground->setMaterialType(EMT_SOLID);
   ground->setMaterialTexture(0, driver->getTexture("media/ui/terrain-texture.jpg"));
}
//! Reads attributes of the scene node.
void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	io::path oldMeshStr = SceneManager->getMeshCache()->getMeshName(Mesh);
	io::path newMeshStr = in->getAttributeAsString("Mesh");
	ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials");

	if (newMeshStr != "" && oldMeshStr != newMeshStr)
	{
		IMesh* newMesh = 0;
		IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());

		if (newAnimatedMesh)
			newMesh = newAnimatedMesh->getMesh(0);

		if (newMesh)
			setMesh(newMesh);
	}

	// optional attribute to assign the hint to the whole mesh
	if (in->existsAttribute("HardwareMappingHint") &&
		in->existsAttribute("HardwareMappingBufferType"))
	{
		scene::E_HARDWARE_MAPPING mapping = scene::EHM_NEVER;
		scene::E_BUFFER_TYPE bufferType = scene::EBT_NONE;

		core::stringc smapping = in->getAttributeAsString("HardwareMappingHint");
		if (smapping.equals_ignore_case("static"))
			mapping = scene::EHM_STATIC;
		else if (smapping.equals_ignore_case("dynamic"))
			mapping = scene::EHM_DYNAMIC;
		else if (smapping.equals_ignore_case("stream"))
			mapping = scene::EHM_STREAM;

		core::stringc sbufferType = in->getAttributeAsString("HardwareMappingBufferType");
		if (sbufferType.equals_ignore_case("vertex"))
			bufferType = scene::EBT_VERTEX;
		else if (sbufferType.equals_ignore_case("index"))
			bufferType = scene::EBT_INDEX;
		else if (sbufferType.equals_ignore_case("vertexindex"))
			bufferType = scene::EBT_VERTEX_AND_INDEX;

		IMesh* mesh = getMesh();
		if (mesh)
			mesh->setHardwareMappingHint(mapping, bufferType);
	}

	IMeshSceneNode::deserializeAttributes(in, options);
}
Пример #12
0
/*----------------------------------------------------------------------------*/
Smodel* OcclusionCulling::loadModel(u16 id, vector3df pos, u16 angle, u16 upvector)
{
 Smodel* x = createSmodel(id, pos, angle, upvector);

 IAnimatedMesh* mesh = smgr->getMesh(listMDL[id]);
                  //mesh->setHardwareMappingHint(EHM_STATIC);
 //printf("loading model [%s]\n", listMDL[id]); getchar();
 x->node = smgr->addAnimatedMeshSceneNode(mesh);
 if (x->node)
 {
   x->node->setPosition(pos);
   x->node->setRotation(vector3df(0,angle,upvector));
 }
 mesh->drop();
 return x;
}
Пример #13
0
CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
: SceneNode(reinterpret_cast<ISceneNode*>(node)), AnimatedNode(node)
{
	#ifdef _DEBUG
	setDebugName("CTriangleSelector");
	#endif

	if (!AnimatedNode)
		return;

	IAnimatedMesh * animatedMesh = AnimatedNode->getMesh();
	if (!animatedMesh)
		return;

	IMesh * mesh = animatedMesh->getMesh((s32)AnimatedNode->getFrameNr());

	if (mesh)
		createFromMesh(mesh);
}
Пример #14
0
//! Reads attributes of the scene node.
void COctTreeSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	int oldMinimal = MinimalPolysPerNode;
	//core::stringc oldMeshStr = SceneManager->getMeshCache()->getMeshFilename(Mesh);
	core::stringc oldMeshStr = MeshName;

	MinimalPolysPerNode = in->getAttributeAsInt("MinimalPolysPerNode");
	core::stringc newMeshStr = in->getAttributeAsString("Mesh");

	bool loadedNewMesh = false;

	IMesh* newMesh = 0;

	if (newMeshStr != "" && oldMeshStr != newMeshStr)
	{
		IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());

		if (newAnimatedMesh)
			newMesh = newAnimatedMesh->getMesh(0);

		if (newMesh)
		{
		//	if (Mesh)
		//		Mesh->drop();

		//	Mesh = newMesh;
		//	Mesh->grab();

			loadedNewMesh = true;
		}
	}

	if (loadedNewMesh || MinimalPolysPerNode != oldMinimal)
	{
		// recalculate tree
		//createTree(Mesh);
		createTree ( newMesh );
		// newMesh->drop ();
	}

	ISceneNode::deserializeAttributes(in, options);
}
Пример #15
0
//! Reads attributes of the scene node.
void CMeshSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	core::stringc oldMeshStr = SceneManager->getMeshCache()->getMeshFilename(Mesh);
	core::stringc newMeshStr = in->getAttributeAsString("Mesh");
	ReadOnlyMaterials = in->getAttributeAsBool("ReadOnlyMaterials");

	if (newMeshStr != "" && oldMeshStr != newMeshStr)
	{
		IMesh* newMesh = 0;
		IAnimatedMesh* newAnimatedMesh = SceneManager->getMesh(newMeshStr.c_str());

		if (newAnimatedMesh)
			newMesh = newAnimatedMesh->getMesh(0);

		if (newMesh)
			setMesh(newMesh);
	}

	IMeshSceneNode::deserializeAttributes(in, options);
}
Пример #16
0
CTriangleSelector::CTriangleSelector(IAnimatedMeshSceneNode* node)
: SceneNode(node), AnimatedNode(node), LastMeshFrame(0)
{
	#ifdef _DEBUG
	setDebugName("CTriangleSelector");
	#endif

	if (!AnimatedNode)
		return;

	IAnimatedMesh* animatedMesh = AnimatedNode->getMesh();
	if (!animatedMesh)
		return;

	LastMeshFrame = (u32)AnimatedNode->getFrameNr();
	IMesh* mesh = animatedMesh->getMesh(LastMeshFrame);

	if (mesh)
		createFromMesh(mesh);
}
Пример #17
0
void CTriangleSelector::update(void) const
{
	if (!AnimatedNode)
		return; //< harmless no-op

	const u32 currentFrame = (u32)AnimatedNode->getFrameNr();
	if (currentFrame == LastMeshFrame)
		return; //< Nothing to do

	LastMeshFrame = currentFrame;
	IAnimatedMesh * animatedMesh = AnimatedNode->getMesh();

	if (animatedMesh)
	{
		IMesh * mesh = animatedMesh->getMesh(LastMeshFrame);

		if (mesh)
			updateFromMesh(mesh);
	}
}
Пример #18
0
void load_map() {
	IAnimatedMesh* mesh = smgr->getMesh("resources/nodes/maps/room.3ds");

	smgr->getMeshManipulator()->makePlanarTextureMapping(mesh->getMesh(0), 0.008f);
	ISceneNode* node = 0;

	node = smgr->addAnimatedMeshSceneNode(mesh);
	node->setMaterialTexture(0,	driver->getTexture("resources/textures/maps/wall.jpg"));
	node->getMaterial(0).SpecularColor.set(0,0,0,0);

	mesh = smgr->addHillPlaneMesh("myHill",
			dimension2d<f32>(20,20),
			dimension2d<u32>(40,40),
			0,
			0,
			dimension2d<f32>(0,0),
			dimension2d<f32>(10,10)
		);

	node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), 3.0f, 300.0f, 30.0f);
	node->setPosition(vector3df(0,7,0));

	node->setMaterialTexture(0,	driver->getTexture("resources/textures/maps/stones.jpg"));
	node->setMaterialTexture(1,	driver->getTexture("resources/textures/maps/water.jpg"));

	node->setMaterialType(video::EMT_REFLECTION_2_LAYER);

	// create light
	node = smgr->addLightSceneNode(0, vector3df(0,0,0), SColorf(1.0f, 0.6f, 0.7f, 1.0f), 600.0f);
	ISceneNodeAnimator* anim = 0;
	anim = smgr->createFlyCircleAnimator (vector3df(0,150,0),250.0f);
	node->addAnimator(anim);
	anim->drop();

	// attach billboard to light
	node = smgr->addBillboardSceneNode(node, dimension2d<f32>(50, 50));
	node->setMaterialFlag(EMF_LIGHTING, false);
	node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
	node->setMaterialTexture(0,	driver->getTexture("resources/textures/particles/particlewhite.bmp"));
}
Пример #19
0
void CLiquidbodyExample::runExample()
{
    debugDraw = true;
    drawProperties = true;
    drawWireFrame = false;

    int rows=2, columns=2;

    device =
        createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16,
            false, false, false, this);

    printf("Please enter the number of rows and columns of floating objects to create: \n");

    cin >> rows;
    cin >> columns;


    device->setWindowCaption(L"irrBullet Liquidbody Example - Josiah Hartzell");

    device->getFileSystem()->addFolderFileArchive("../../media/");


    ILightSceneNode* light = device->getSceneManager()->addLightSceneNode(0, vector3df(20, 40, -50), SColorf(1.0f, 1.0f, 1.0f), 4000.0f);
    light->setLightType(ELT_DIRECTIONAL);
    light->setRotation(vector3df(0,200,30));

    device->getSceneManager()->setAmbientLight(SColor(100,100,100,100));

    camera = device->getSceneManager()->addCameraSceneNodeFPS();
	camera->setPosition(vector3df(50,15,4));
	camera->setTarget(vector3df(0,0,0));


    ////////////////////////////
    // Create irrBullet World //
    ////////////////////////////
    world = createIrrBulletWorld(device, true, debugDraw);

    world->setDebugMode(EPDM_DrawAabb |
            EPDM_DrawContactPoints);

    world->setGravity(vector3df(0,-10,0));

    ILiquidBody* water = world->addLiquidBody(vector3df(-5000,0,5000),irr::core::aabbox3df(0, -10000, 0, 10000, 0, 10000), 500.0f, 200.0f);
    water->setCurrentDirection(vector3df(0,0,0));
    water->setGlobalWaveChangeIncrement(0.01f);
    water->setGlobalWaveUpdateFrequency(1.0f);
    water->setMaxGlobalWaveHeight(4.0f);
    water->setMinGlobalWaveHeight(-1.0f);
    water->setLocalWaveValues(10,1,0.5f);
    water->setInfinite(true);
    water->setInfiniteDepth(true);
    water->setLiquidDensity(0.1f);
    //water->setDebugDrawEnabled(false);


    IAnimatedMesh* mesh = device->getSceneManager()->addHillPlaneMesh( "myHill",
		core::dimension2d<f32>(20,20),
		core::dimension2d<u32>(40,40), 0, 0,
		core::dimension2d<f32>(0,0),
		core::dimension2d<f32>(1000,1000));

	ISceneNode* node = device->getSceneManager()->addWaterSurfaceSceneNode(mesh->getMesh(0), 0.0f, 300.0f, 30.0f);
	node->setPosition(core::vector3df(0,5,0));

	node->setMaterialTexture(0, device->getVideoDriver()->getTexture("water.jpg"));
	node->setScale(vector3df(1000,1,1000));

	node->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
	node->setMaterialFlag(EMF_BACK_FACE_CULLING, false);


	for(u32 i=0; i < rows; i++)
	{
	    for(u32 j=0; j < columns; j++)
        {
            IRigidBody* body = addCube(vector3df(i*15,0,j*15), vector3df(10,10,10), 1, "crate.jpg");

            irr::f32 t = 0.5f;
            irr::f32 buoyancy = 0.2f;

            irr::core::array<SBuoyancyPoint> points;
            //points.push_back(SBuoyancyPoint(irr::core::vector3df(0,0,0), 180.0f));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(t,t,t), buoyancy));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(-t,t,t), buoyancy));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(-t,t,-t), buoyancy));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(t,t,-t), buoyancy));

            points.push_back(SBuoyancyPoint(irr::core::vector3df(-t,-t,t), buoyancy));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(t,-t,t), buoyancy));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(-t,-t,-t), buoyancy));
            points.push_back(SBuoyancyPoint(irr::core::vector3df(t,-t,-t), buoyancy));


            /*ICollisionObjectAffectorBuoyancy* affector = new ICollisionObjectAffectorBuoyancy(points,
                irr::core::aabbox3df(0, -100, 0, 10000, 0, 10000), 1);
            affector->setDebugDrawing(true);
            body->addAffector(affector);*/
            body->setBuoyancyPoints(points);

            //body->setActivationState(EAS_DISABLE_DEACTIVATION);
        }
	}

    // Set our delta time and time stamp
    u32 TimeStamp = device->getTimer()->getTime();
    u32 DeltaTime = 0;
    while(device->run())
    {
        device->getVideoDriver()->beginScene(true, true, SColor(255,100,101,140));

        DeltaTime = device->getTimer()->getTime() - TimeStamp;
		TimeStamp = device->getTimer()->getTime();

		// Step the simulation with our delta time
        world->stepSimulation(DeltaTime*0.001f, 120);
        //static_cast<ISoftBody*>(world->getCollisionObjectByName("SOFTBODY1"))->addForce(vector3df(-2,0,0));


        //world->debugDrawWorld(debugDraw);
        // This call will draw the technical properties of the physics simulation
        // to the GUI environment.
        world->debugDrawProperties(drawProperties);


        device->getSceneManager()->drawAll();
        device->getGUIEnvironment()->drawAll();

        device->getVideoDriver()->endScene();
    }
    //delete Liquid;

    // We're done with the IrrBullet world, so we free the memory that it takes up.
    if(world)
        delete world;

    if(device)
        device->drop();
}
Пример #20
0
//! renders the node.
void CSkyDomeSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();
	scene::ICameraSceneNode* camera = SceneManager->getActiveCamera();

	if (!camera || !driver)
		return;

	if ( !camera->isOrthogonal() )
	{
		core::matrix4 mat(AbsoluteTransformation);
		mat.setTranslation(camera->getAbsolutePosition());

		driver->setTransform(video::ETS_WORLD, mat);

		driver->setMaterial(Buffer->Material);
		driver->drawMeshBuffer(Buffer);
	}

	// for debug purposes only:
	if ( DebugDataVisible )
	{
		video::SMaterial m;
		m.Lighting = false;
		driver->setMaterial(m);

		if ( DebugDataVisible & scene::EDS_NORMALS )
		{
			IAnimatedMesh * arrow = SceneManager->addArrowMesh (
					"__debugnormal2", 0xFFECEC00,
					0xFF999900, 4, 8, 1.f * 40.f, 0.6f * 40.f, 0.05f * 40.f, 0.3f * 40.f);
			if ( 0 == arrow )
			{
				arrow = SceneManager->getMesh ( "__debugnormal2" );
			}
			IMesh *mesh = arrow->getMesh(0);

			// find a good scaling factor
			core::matrix4 m2;

			// draw normals
			const scene::IMeshBuffer* mb = Buffer;
			const u32 vSize = video::getVertexPitchFromType(mb->getVertexType());
			const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices();
			for ( u32 i=0; i != mb->getVertexCount(); ++i )
			{
				// align to v->Normal
				core::quaternion quatRot(v->Normal.X, 0.f, -v->Normal.X, 1+v->Normal.Y);
				quatRot.normalize();
				quatRot.getMatrix(m2, v->Pos);

				m2 = AbsoluteTransformation * m2;

				driver->setTransform(video::ETS_WORLD, m2);
				for (u32 a = 0; a != mesh->getMeshBufferCount(); ++a)
					driver->drawMeshBuffer(mesh->getMeshBuffer(a));

				v = (const video::S3DVertex*) ( (u8*) v + vSize );
			}
			driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		}

		// show mesh
		if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY )
		{
			m.Wireframe = true;
			driver->setMaterial(m);

			driver->drawMeshBuffer(Buffer);
		}
	}
}
Пример #21
0
void Mesh3DInitScene()
{
	IAnimatedMesh*				mesh;
	IAnimatedMeshSceneNode*     node;
	scene::ISceneNodeAnimator*  anim;
	scene::ISceneManager*		smgr   = IrrlichtManager::GetIrrlichtManager()->GetScene();
	IrrlichtDevice*				device = IrrlichtManager::GetIrrlichtManager()->GetDevice();
	video::IVideoDriver*		driver = IrrlichtManager::GetIrrlichtManager()->GetDriver();
	
	std::string					load_zip;
	std::string					load_data;
	std::string					reload_path;
	FileSystemZip*				pfilesystem			= NULL;
	io::IReadFile*				memfile				= NULL;
	byte*						apk_buffer			= NULL;
	byte*						buff_extract		= NULL;
	int							size				= 0;
	int							apk_size			= 0;

	if (!IrrlichtManager::GetIrrlichtManager()->GetDevice())
	{
		LogError("Error initializing Irrlicht");
		return;
	}
	
	IrrlichtManager::GetIrrlichtManager()->GetDevice()->getTimer()->setTime(0);
		
    smgr->addLightSceneNode(0, core::vector3df(-100,10,0), video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 200.0f);
    smgr->addLightSceneNode(0, core::vector3df(+100,10,0), video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 200.0f);
	
		
//////////////////////////////mesh/////////////////////////////////////////////////
	load_zip	= (GetBaseAppPath() + "game/ninja.zip").c_str();
	load_data	= "ninja.b3d";
	reload_path	= (GetBaseAppPath() + "game/ninja.b3d").c_str();
	
#ifdef ANDROID_NDK
	apk_buffer	= FileManager::GetFileManager()->Get(load_zip.c_str(), &apk_size, false, false);
	
	if( apk_buffer )
	{
		pfilesystem	= new FileSystemZip();
		pfilesystem->Init_unzMemory(apk_buffer, apk_size);
		buff_extract = pfilesystem->Get_unz(load_data, &size);

		delete apk_buffer;
		apk_buffer = NULL;
	}
#else
	pfilesystem = new FileSystemZip();
	pfilesystem->Init_unz(load_zip.c_str());
	buff_extract = pfilesystem->Get_unz(load_data.c_str(), &size);
#endif
	
	memfile = device->getFileSystem()->createMemoryReadFile(buff_extract, size, reload_path.c_str(), true);
	//new buffer copy on file->read(Buffer, size) of CXMeshFileLoader::readFileIntoMemory
	mesh	= smgr->getMesh( memfile );
	node	= smgr->addAnimatedMeshSceneNode( mesh );

	//delete buff_extract in drop() then goto ~CMemoryReadFile
	memfile->drop();
						
	if( pfilesystem )
	{
		delete pfilesystem;
		pfilesystem = NULL;
	}

//////////////////////////////texture/////////////////////////////////////////////////
	node->setMaterialTexture( 0, driver->getTexture((GetBaseAppPath()+"game/nskinbl.jpg").c_str()) );
    node->setMaterialFlag(EMF_LIGHTING, true);
    node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
    anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0));
    node->addAnimator(anim);
    anim->drop();

	u32 alpha_val		= 90;
	u32 MaterialCount	= node->getMaterialCount();
	
	for(u32 i=0; i<MaterialCount; i++)
	{
		video::SMaterial& tex_mat	= node->getMaterial(i);
		tex_mat.MaterialType		= video::EMT_TRANSPARENT_VERTEX_ALPHA;
		//tex_mat.MaterialTypeParam	= 0.1;
		//tex_mat.MaterialTypeParam2= 0.1;
		tex_mat.AmbientColor.setAlpha(alpha_val);
		tex_mat.DiffuseColor.setAlpha(alpha_val);
		tex_mat.SpecularColor.setAlpha(alpha_val);
		tex_mat.EmissiveColor.setAlpha(alpha_val);
	}

#if	defined(_IRR_COMPILE_WITH_OGLES2_)
	for(u32 i=0; i<mesh->getMeshBufferCount(); i++)
	{
		scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i);
		video::S3DVertex* vertex = (video::S3DVertex*)buffer->getVertices();
		
		for(u32 j=0; j<buffer->getVertexCount(); j++)
		{
			vertex[j].Color.setAlpha(alpha_val);
		}
	}
#endif
	
	smgr->addSkyBoxSceneNode(IrrlichtManager::GetIrrlichtManager()->GetTexture("game/irrlicht2_up.jpg"),
                             IrrlichtManager::GetIrrlichtManager()->GetTexture("game/irrlicht2_dn.jpg"),
                             IrrlichtManager::GetIrrlichtManager()->GetTexture("game/irrlicht2_lf.jpg"),
                             IrrlichtManager::GetIrrlichtManager()->GetTexture("game/irrlicht2_rt.jpg"),
                             IrrlichtManager::GetIrrlichtManager()->GetTexture("game/irrlicht2_ft.jpg"),
                             IrrlichtManager::GetIrrlichtManager()->GetTexture("game/irrlicht2_bk.jpg"));
//////////////////////////////////cam/////////////////////////////////////////////    
   	ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .02f, 0, 0, 0, true, 1.0f);
	//camera->addCameraSceneNode(0, vector3df(0,2,-10));
	camera->setPosition(core::vector3df(0,5,-20));
	float fov = float(GetPrimaryGLX())/ float(GetPrimaryGLY());
	camera->setAspectRatio(fov);
	camera->setFOV((120 * (float)M_PI / 360.0f));

#ifdef _IRR_COMPILE_WITH_GUI_
	EventControlComponent* receiver = new EventControlComponent();
    receiver->AddGuiButton();
	device->setEventReceiver(receiver);
#endif
}
Пример #22
0
/*
Ok, now the main-function:
First, we initialize the device, get the SourceManager and
VideoDriver, load an animated mesh from .md2 and a map from
.pk3. Because that's old stuff, I won't explain every step.
Just take care of the maps position.
*/
int main()
{
	// ask user for driver
	video::E_DRIVER_TYPE driverType=driverChoiceConsole();
	if (driverType==video::EDT_COUNT)
		return 1;

	//Instance of the EventReceiver
	MyEventReceiver receiver;

	//Initialise the engine
	IrrlichtDevice *device = createDevice(driverType,
			dimension2du(ResX,ResY), 32, fullScreen,
			false, false, &receiver);
	if (!device)
		return 1;

	ISceneManager *smgr = device->getSceneManager();
	IVideoDriver *driver = device->getVideoDriver();

	//Load model
	IAnimatedMesh *model = smgr->getMesh("../../media/sydney.md2");
	if (!model)
		return 1;
	IAnimatedMeshSceneNode *model_node = smgr->addAnimatedMeshSceneNode(model);
	//Load texture
	if (model_node)
	{
		ITexture *texture = driver->getTexture("../../media/sydney.bmp");
		model_node->setMaterialTexture(0,texture);
		model_node->setMD2Animation(scene::EMAT_RUN);
		//Disable lighting (we've got no light)
		model_node->setMaterialFlag(EMF_LIGHTING,false);
	}

	//Load map
	device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
	IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp");
	if (map)
	{
		ISceneNode *map_node = smgr->addOctreeSceneNode(map->getMesh(0));
		//Set position
		map_node->setPosition(vector3df(-850,-220,-850));
	}

/*
Now we create our four cameras. One is looking at the model
from the front, one from the top and one from the side. In
addition there's a FPS-camera which can be controlled by the
user.
*/
	// Create 3 fixed and one user-controlled cameras
	//Front
	camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0));
	//Top
	camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0));
	//Left
	camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0));
	//User-controlled
	camera[3] = smgr->addCameraSceneNodeFPS();
	// don't start at sydney's position
	if (camera[3])
		camera[3]->setPosition(core::vector3df(-50,0,-50));

/*
Create a variable for counting the fps and hide the mouse:
*/
	//Hide mouse
	device->getCursorControl()->setVisible(false);
	//We want to count the fps
	int lastFPS = -1;

/*
There wasn't much new stuff - till now!
Only by defining four cameras, the game won't be splitscreen.
To do this you need several steps:
  - Set the viewport to the whole screen
  - Begin a new scene (Clear screen)

  - The following 3 steps are repeated for every viewport in the splitscreen
    - Set the viewport to the area you wish
    - Activate the camera which should be "linked" with the viewport
    - Render all objects

  - If you have a GUI:
    - Set the viewport the whole screen
    - Display the GUI
  - End scene

Sounds a little complicated, but you'll see it isn't:
*/

	while(device->run())
	{
		//Set the viewpoint to the whole screen and begin scene
		driver->setViewPort(rect<s32>(0,0,ResX,ResY));
		driver->beginScene(true,true,SColor(255,100,100,100));
		//If SplitScreen is used
		if (SplitScreen)
		{
			//Activate camera1
			smgr->setActiveCamera(camera[0]);
			//Set viewpoint to the first quarter (left top)
			driver->setViewPort(rect<s32>(0,0,ResX/2,ResY/2));
			//Draw scene
			smgr->drawAll();
			//Activate camera2
			smgr->setActiveCamera(camera[1]);
			//Set viewpoint to the second quarter (right top)
			driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY/2));
			//Draw scene
			smgr->drawAll();
			//Activate camera3
			smgr->setActiveCamera(camera[2]);
			//Set viewpoint to the third quarter (left bottom)
			driver->setViewPort(rect<s32>(0,ResY/2,ResX/2,ResY));
			//Draw scene
			smgr->drawAll();
			//Set viewport the last quarter (right bottom)
			driver->setViewPort(rect<s32>(ResX/2,ResY/2,ResX,ResY));
		}
		//Activate camera4
		smgr->setActiveCamera(camera[3]);
		//Draw scene
		smgr->drawAll();
		driver->endScene();

		/*
		As you can probably see, the image is rendered for every
		viewport seperately. That means, that you'll loose much performance.
		Ok, if you're aksing "How do I have to set the viewport
		to get this or that screen?", don't panic. It's really
		easy: In the rect-function you define 4 coordinates:
		- X-coordinate of the corner left top
		- Y-coordinate of the corner left top
		- X-coordinate of the corner right bottom
		- Y-coordinate of the corner right bottom

		That means, if you want to split the screen into 2 viewports
		you would give the following coordinates:
		- 1st viewport: 0,0,ResX/2,ResY
		- 2nd viewport: ResX/2,0,ResX,ResY

		If you didn't fully understand, just play arround with the example
		to check out what happens.

		Now we just view the current fps and shut down the engine,
		when the user wants to:
		*/
		//Get and show fps
		if (driver->getFPS() != lastFPS)
		{
			lastFPS = driver->getFPS();
			core::stringw tmp = L"Irrlicht SplitScreen-Example (FPS: ";
			tmp += lastFPS;
			tmp += ")";
			device->setWindowCaption(tmp.c_str());
		}
	}
	//Delete device
	device->drop();
	return 0;
}
//! renders the node.
void CAnimatedMeshSceneNode::render()
{
    video::IVideoDriver* driver = SceneManager->getVideoDriver();

    if (!Mesh || !driver)
        return;

    bool isTransparentPass =
        SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;

    ++PassCount;

    s32 frame = getFrameNr();
    scene::IMesh* m = Mesh->getMesh(frame, 255, StartFrame, EndFrame);

    if ( 0 == m )
    {
#ifdef _DEBUG
        os::Printer::log("Animated Mesh returned no mesh to render.", Mesh->getDebugName(), ELL_WARNING);
#endif
    }

    driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);


    u32 i,g;

    // update all dummy transformation nodes
    if (!JointChildSceneNodes.empty() && Mesh &&
            (Mesh->getMeshType() == EAMT_MS3D || Mesh->getMeshType() == EAMT_X  || Mesh->getMeshType() == EAMT_B3D ))
    {
        IAnimatedMeshMS3D* amm = (IAnimatedMeshMS3D*)Mesh;
        core::matrix4* m;

        for ( i=0; i< JointChildSceneNodes.size(); ++i)
            if (JointChildSceneNodes[i])
            {
                m = amm->getMatrixOfJoint(i, frame);
                if (m)
                    JointChildSceneNodes[i]->getRelativeTransformationMatrix() = *m;
            }
    }

    if (Shadow && PassCount==1)
        Shadow->setMeshToRenderFrom(m);

    // for debug purposes only:

    u32 renderMeshes = 1;
    video::SMaterial mat;
    if (DebugDataVisible && PassCount==1)
    {
        // overwrite half transparency
        if ( DebugDataVisible & scene::EDS_HALF_TRANSPARENCY )
        {
            for ( g=0; g<m->getMeshBufferCount(); ++g)
            {
                mat = Materials[g];
                mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
                driver->setMaterial(mat);
                driver->drawMeshBuffer ( m->getMeshBuffer ( g ) );
            }
            renderMeshes = 0;
        }
    }

    // render original meshes
    if ( renderMeshes )
    {
        for ( i=0; i<m->getMeshBufferCount(); ++i)
        {
            video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType);
            bool transparent = (rnd && rnd->isTransparent());

            // only render transparent buffer if this is the transparent render pass
            // and solid only in solid pass
            if (transparent == isTransparentPass)
            {
                scene::IMeshBuffer* mb = m->getMeshBuffer(i);
                driver->setMaterial(Materials[i]);
                driver->drawMeshBuffer(mb);
            }
        }
    }

    // for debug purposes only:
    if (DebugDataVisible && PassCount==1)
    {
        mat.Lighting = false;
        driver->setMaterial(mat);

        // show bounding box
        if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
        {
            for ( g=0; g< m->getMeshBufferCount(); ++g)
            {
                driver->draw3DBox( m->getMeshBuffer(g)->getBoundingBox(),
                                   video::SColor(0,190,128,128)
                                 );
            }
        }

        if ( DebugDataVisible & scene::EDS_BBOX )
            driver->draw3DBox(Box, video::SColor(0,255,255,255));

        // show skeleton
        if ( DebugDataVisible & scene::EDS_SKELETON )
        {
            if (Mesh->getMeshType() == EAMT_X)
            {
                // draw skeleton
                const core::array<core::vector3df>* ds =
                    ((IAnimatedMeshX*)Mesh)->getDrawableSkeleton(frame);

                for ( g=0; g < ds->size(); g +=2 )
                    driver->draw3DLine((*ds)[g], (*ds)[g+1],  video::SColor(0,51,66,255));
            }

            // show tag for quake3 models
            if (Mesh->getMeshType() == EAMT_MD3 )
            {
                IAnimatedMesh * arrow = SceneManager->addArrowMesh ( "__tag_show",
                                        4, 8, 5.f, 4.f, 0.5f, 1.f, 0xFF0000FF, 0xFF000088
                                                                   );
                if ( 0 == arrow )
                {
                    arrow = SceneManager->getMesh ( "__tag_show" );
                }
                IMesh *arrowMesh = arrow->getMesh ( 0 );

                video::SMaterial material;
                material.Lighting = false;
                driver->setMaterial(material);

                core::matrix4 m;

                SMD3QuaterionTagList *taglist = ((IAnimatedMeshMD3*)Mesh)->getTagList (	getFrameNr(),
                                                255,
                                                getStartFrame (),
                                                getEndFrame ()
                                                                                      );
                if ( taglist )
                {
                    for ( u32 g = 0; g != taglist->size(); ++g )
                    {
                        (*taglist)[g].setto ( m );

                        driver->setTransform(video::ETS_WORLD, m );

                        for ( u32 a = 0; a != arrowMesh->getMeshBufferCount(); ++a )
                            driver->drawMeshBuffer ( arrowMesh->getMeshBuffer ( a ) );
                    }
                }
            }
        }

        // show normals
        if ( DebugDataVisible & scene::EDS_NORMALS )
        {
            IAnimatedMesh * arrow = SceneManager->addArrowMesh ( "__debugnormal",
                                    4, 8, 1.f, 0.6f, 0.05f, 0.3f, 0xFFECEC00, 0xFF999900
                                                               );
            if ( 0 == arrow )
            {
                arrow = SceneManager->getMesh ( "__debugnormal" );
            }
            IMesh *mesh = arrow->getMesh ( 0 );

            // find a good scaling factor

            core::matrix4 m2;

            // draw normals
            for ( g=0; g<m->getMeshBufferCount(); ++g)
            {
                scene::IMeshBuffer* mb = m->getMeshBuffer(g);
                const u32 vSize = mb->getVertexPitch();
                const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices();
                for ( i = 0; i != mb->getVertexCount(); ++i )
                {
                    AlignToUpVector ( m2, v->Normal );
                    AbsoluteTransformation.transformVect ( m2.pointer(), v->Pos );

                    driver->setTransform(video::ETS_WORLD, m2 );
                    for ( u32 a = 0; a != mesh->getMeshBufferCount(); ++a )
                        driver->drawMeshBuffer ( mesh->getMeshBuffer ( a ) );

                    v = (const video::S3DVertex*) ( (u8*) v + vSize );
                }
            }
            driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
        }

        // show mesh
        if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY )
        {
            mat.Lighting = false;
            mat.Wireframe = true;
            driver->setMaterial(mat);

            for ( g=0; g<m->getMeshBufferCount(); ++g)
            {
                driver->drawMeshBuffer ( m->getMeshBuffer ( g ) );
            }
        }
    }
}
Пример #24
0
// Tests mesh transformations via mesh manipulator.
bool meshTransform(void)
{
	// Use EDT_BURNINGSVIDEO since it is not dependent on (e.g.) OpenGL driver versions.
	IrrlichtDevice *device = createDevice(EDT_BURNINGSVIDEO, dimension2d<u32>(160, 120), 32);
	assert_log(device);
	if (!device)
		return false;

	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager * smgr = device->getSceneManager();

	IMeshSceneNode* node1 = smgr->addCubeSceneNode(50);
	IAnimatedMesh* amesh = smgr->getMesh("../media/sydney.md2");
	IAnimatedMesh* smesh = smgr->getMesh("../media/ninja.b3d");
	assert_log(node1 && amesh && smesh);

	bool result = false;
	if (!node1 || !amesh || !smesh)
		return false;

//	node1->setPosition(core::vector3df(-60,0,150));
	node1->setDebugDataVisible(scene::EDS_BBOX_ALL);

	IMeshSceneNode* node2 = smgr->addMeshSceneNode(amesh->getMesh(10));
	assert_log(node2);

	if (!node2)
		return false;

//	node2->setPosition(core::vector3df(30,10,150));
	node2->setDebugDataVisible(scene::EDS_BBOX_ALL);
	node2->setMaterialFlag(EMF_LIGHTING, false);

	IMeshSceneNode* node3 = smgr->addMeshSceneNode(smesh->getMesh(10));
	assert_log(node3);

	if (!node3)
		return false;

//	node3->setPosition(core::vector3df(10,0,0));
	node3->setDebugDataVisible(scene::EDS_BBOX_ALL);
	node3->setMaterialFlag(EMF_LIGHTING, false);

	smgr->addCameraSceneNode()->setPosition(core::vector3df(0,0,-20));

	// Just jump to the last frame since that's all we're interested in.
	device->run();
	driver->beginScene(true, true, SColor(255, 60, 60, 60));
	smgr->drawAll();
	driver->endScene();

	core::matrix4 mat;
	mat.setTranslation(core::vector3df(-60,0,150));
	driver->getMeshManipulator()->transform(node1->getMesh(), mat);

	mat.setTranslation(core::vector3df(30,10,150));
	driver->getMeshManipulator()->transform(node2->getMesh(), mat);

	mat.setTranslation(core::vector3df(10,0,0));
	driver->getMeshManipulator()->transform(node3->getMesh(), mat);

	// Just jump to the last frame since that's all we're interested in.
	device->run();
	driver->beginScene(true, true, SColor(255, 60, 60, 60));
	smgr->drawAll();
	driver->endScene();

	result = takeScreenshotAndCompareAgainstReference(driver, "-meshTransform.png");

	device->closeDevice();
	device->run();
	device->drop();

	return result;
}
Пример #25
0
//! renders the node.
void CMeshSceneNode::render()
{
	video::IVideoDriver* driver = SceneManager->getVideoDriver();

	if (!Mesh || !driver)
		return;

	bool isTransparentPass = 
		SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;

	++PassCount;

	driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
	Box = Mesh->getBoundingBox();

	// for debug purposes only:

	bool renderMeshes = true;
	video::SMaterial mat;
	if (DebugDataVisible && PassCount==1)
	{
		// overwrite half transparency
		if ( DebugDataVisible & scene::EDS_HALF_TRANSPARENCY )
		{
			for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
			{
				mat = Materials[g];
				mat.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
				driver->setMaterial(mat);
				driver->drawMeshBuffer(Mesh->getMeshBuffer(g));
			}
			renderMeshes = false;
		}
	}

	// render original meshes
	if ( renderMeshes )
	{
		for (u32 i=0; i<Mesh->getMeshBufferCount(); ++i)
		{
			scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
			if (mb)
			{
				const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];

				video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType);
				bool transparent = (rnd && rnd->isTransparent());

				// only render transparent buffer if this is the transparent render pass
				// and solid only in solid pass
				if (transparent == isTransparentPass) 
				{
					driver->setMaterial(material);
					driver->drawMeshBuffer(mb);
				}
			}
		}
	}

	driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

	// for debug purposes only:
	if ( DebugDataVisible && PassCount==1)
	{
		video::SMaterial m;
		m.Lighting = false;
		driver->setMaterial(m);

		if ( DebugDataVisible & scene::EDS_BBOX )
		{
			driver->draw3DBox(Box, video::SColor(255,255,255,255));
		}
		if ( DebugDataVisible & scene::EDS_BBOX_BUFFERS )
		{
			for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
			{
				driver->draw3DBox(
					Mesh->getMeshBuffer(g)->getBoundingBox(),
					video::SColor(255,190,128,128));
			}
		}

		if ( DebugDataVisible & scene::EDS_NORMALS )
		{
			IAnimatedMesh * arrow = SceneManager->addArrowMesh (
					"__debugnormal", 0xFFECEC00,
					0xFF999900, 4, 8, 1.f, 0.6f, 0.05f,
					0.3f);
			if ( 0 == arrow )
			{
				arrow = SceneManager->getMesh ( "__debugnormal" );
			}
			IMesh *mesh = arrow->getMesh(0);

			// find a good scaling factor

			core::matrix4 m2;

			// draw normals
			for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
			{
				const scene::IMeshBuffer* mb = Mesh->getMeshBuffer(g);
				const u32 vSize = video::getVertexPitchFromType(mb->getVertexType());
				const video::S3DVertex* v = ( const video::S3DVertex*)mb->getVertices();
				for ( u32 i=0; i != mb->getVertexCount(); ++i )
				{
					// align to v->Normal
					core::quaternion quatRot(v->Normal.X, 0.f, -v->Normal.X, 1+v->Normal.Y);
					quatRot.normalize();
					quatRot.getMatrix(m2);

					m2.setTranslation(v->Pos);
					m2*=AbsoluteTransformation;

					driver->setTransform(video::ETS_WORLD, m2);
					for (u32 a = 0; a != mesh->getMeshBufferCount(); ++a)
						driver->drawMeshBuffer(mesh->getMeshBuffer(a));

					v = (const video::S3DVertex*) ( (u8*) v + vSize );
				}
			}
			driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		}

		// show mesh
		if ( DebugDataVisible & scene::EDS_MESH_WIRE_OVERLAY )
		{
			m.Wireframe = true;
			driver->setMaterial(m);

			for (u32 g=0; g<Mesh->getMeshBufferCount(); ++g)
			{
				driver->drawMeshBuffer( Mesh->getMeshBuffer(g) );
			}
		}
	}
}