//------------------------------------------------------------------------------------
// irr::scene::ISceneManager wrappers
//------------------------------------------------------------------------------------

extern "C"
{

	ISceneNodeAnimator* IrrScene_ISceneManager_createTextureAnimator(ISceneManager* scene,ITexture** textureArr,s32 textureArrSize,s32 timePerFrame, bool loop=true)
	{
		if (scene) {

			array<ITexture*> textures;
			for (int i=0; i<textureArrSize; i++) {	
				textures.push_back(textureArr[i]);
			}
		
			return scene->createTextureAnimator(textures,timePerFrame,loop);
		} else return 0;
	}
	
	ISceneNodeAnimator* IrrScene_ISceneManager_createFollowSplineAnimator(ISceneManager* scene,s32 startTime,vector3df** pointsArray,u32 pointsArraySize,f32 speed=1.0f,f32 tightness=0.5f, bool loop=true, bool pingpong=false)
	{
		if (scene) {
			array<vector3df> points;
			for (int i=0; i<pointsArraySize; i++) {	
				points.push_back(*pointsArray[i]);
			}

			return scene->createFollowSplineAnimator(startTime,points,speed,tightness,loop,pingpong);
		} else return 0;
	}
	
	void IrrScene_ISceneManager_clear(ISceneManager* scene)
	{
		if (scene>0)
			scene->clear();
	}
	
	bool IrrScene_ISceneManager_postEventFromUser(ISceneManager* scene,SEvent* usrevent)
	{
		if (scene>0)
			return scene->postEventFromUser(*usrevent);
		else return false;
	}
	
	void IrrScene_ISceneManager_addToDeletionQueue(ISceneManager* scene,ISceneNode* node)
	{
		if (scene>0)
			scene->addToDeletionQueue(node);
	}
	
	IMeshManipulator* IrrScene_ISceneManager_getMeshManipulator(ISceneManager* scene)
	{
		if (scene>0)
			return scene->getMeshManipulator();
		else return 0;
	}
	
	ISceneCollisionManager* IrrScene_ISceneManager_getSceneCollisionManager(ISceneManager* scene)
	{
		if (scene>0)
			return scene->getSceneCollisionManager();
		else return 0;
	}
	
	void IrrScene_ISceneManager_addExternalMeshLoader(ISceneManager* scene,IMeshLoader* externalLoader)
	{
		if (scene>0)
			scene->addExternalMeshLoader(externalLoader);
	}
	
	IMetaTriangleSelector* IrrScene_ISceneManager_createMetaTriangleSelector(ISceneManager* scene)
	{
		if (scene>0)
			return scene->createMetaTriangleSelector();
		else return 0;
	}
	
	ITriangleSelector* IrrScene_ISceneManager_createTerrainTriangleSelector(ISceneManager* scene,ITerrainSceneNode* node,s32 LOD=0)
	{
		if (scene>0)
			return scene->createTerrainTriangleSelector(node,LOD);
		else return 0;
	}
	
	ITriangleSelector* IrrScene_ISceneManager_createOctreeTriangleSelector(ISceneManager* scene,IMesh* mesh,ISceneNode* node,s32 minimalPolysPerNode=32)
	{
		if (scene>0)
			return scene->createOctreeTriangleSelector(mesh,node,minimalPolysPerNode);
		else return 0;
	}
	
	ITriangleSelector* IrrScene_ISceneManager_createTriangleSelectorFromBoundingBox(ISceneManager* scene,ISceneNode* node)
	{
		if (scene>0)
			return scene->createTriangleSelectorFromBoundingBox(node);
		else return 0;
	}
	
	ITriangleSelector* IrrScene_ISceneManager_createTriangleSelector(ISceneManager* scene,IMesh* mesh,ISceneNode* node)
	{
		if (scene>0)
			return scene->createTriangleSelector(mesh,node);
		else return 0;
	}

	ITriangleSelector* IrrScene_ISceneManager_createTriangleSelectorFromAnimatedNode(ISceneManager* scene, IAnimatedMeshSceneNode* node)
	{
		if (scene>0)
			return scene->createTriangleSelector(node);
		else return 0;
	}
	
	ISceneNodeAnimatorCollisionResponse* IrrScene_ISceneManager_createCollisionResponseAnimator(ISceneManager* scene,
				ITriangleSelector* world,ISceneNode* sceneNode,
				vector3df* ellipsoidRadius=0,
				vector3df* gravityPerSecond=0,
				vector3df* ellipsoidTranslation=0,
				f32 slidingValue=0.0005f)
	{
		if (scene>0)	
			return scene->createCollisionResponseAnimator(world, sceneNode, 
				(ellipsoidRadius ? *ellipsoidRadius : vector3df(30,60,30)),
				(gravityPerSecond ? *gravityPerSecond : vector3df(0,-10.0f,0)),
				(ellipsoidTranslation ? *ellipsoidTranslation : vector3df(0,0,0)), 
				slidingValue);
		else return 0;
	}
	
	ISceneNodeAnimator* IrrScene_ISceneManager_createDeleteAnimator(ISceneManager* scene,u32 timeMs)
	{
		if (scene>0)
			return scene->createDeleteAnimator(timeMs);
		else return 0;
	}
	
	ISceneNodeAnimator* IrrScene_ISceneManager_createFlyStraightAnimator(ISceneManager* scene,vector3df* startPoint,vector3df* endPoint,u32 timeForWay,bool loop=false)
	{
		if (scene>0)
			return scene->createFlyStraightAnimator(*startPoint,*endPoint,timeForWay,loop);
		else return 0;
	}
	
	ISceneNodeAnimator* IrrScene_ISceneManager_createFlyCircleAnimator(ISceneManager* scene,vector3df* center=0,f32 radius = 100.f,f32 speed=0.001f,vector3df* direction=0,f32 startPosition = 0.f,f32 radiusEllipsoid = 0.f)
	{
		if (scene>0) {
			bool bDelDir = false;
			bool bDelCenter = false;
			if (!direction) {
				direction=new vector3df(0.0f,1.0f,0.0f);
				bDelDir=true;
			}		
			if (!direction) {
				center = new vector3df(0.0f,0.0f,0.0f);
				bDelCenter = true;
			}
			
			ISceneNodeAnimator* pRetVal=scene->createFlyCircleAnimator(*center,radius,speed,*direction,startPosition,radiusEllipsoid);
			
			if (bDelDir) delete direction;
			if (bDelCenter) delete center;
			
			return pRetVal;
		} else return 0;
	}
	
	ISceneNodeAnimator* IrrScene_ISceneManager_createRotationAnimator(ISceneManager* scene,vector3df* rotationSpeed)
	{
		if (scene>0)
			return scene->createRotationAnimator(*rotationSpeed);
		else return 0;
	}
	
	void IrrScene_ISceneManager_registerNodeForRendering(ISceneManager* scene,ISceneNode* node,E_SCENE_NODE_RENDER_PASS pass=ESNRP_AUTOMATIC)
	{
		if (scene>0)
			scene->registerNodeForRendering(node,pass);
	}
	
	SColor* IrrScene_ISceneManager_getShadowColor(ISceneManager* scene)
	{
		if (scene>0)
			return new SColor(scene->getShadowColor());
		else return 0;
	}
	
	void IrrScene_ISceneManager_setShadowColor(ISceneManager* scene,SColor* color=0)
	{
		if (scene>0) {
			bool delC=false;
			if (!color) {
				color=new SColor(150,0,0,0);
				delC=true;
			}
			scene->setShadowColor(*color);
			if (delC) delete color;
		}
	}
	
	void IrrScene_ISceneManager_setActiveCamera(ISceneManager* scene,ICameraSceneNode* camera)
	{
		if (scene>0)
			scene->setActiveCamera(camera);
	}
	
	ICameraSceneNode* IrrScene_ISceneManager_getActiveCamera(ISceneManager* scene)
	{
		if (scene>0)
			return scene->getActiveCamera();
		else return 0;
	}
	
	ISceneNode* IrrScene_ISceneManager_getSceneNodeFromId(ISceneManager* scene,s32 id,ISceneNode* start=0)
	{
		if (scene>0)
			return scene->getSceneNodeFromId(id,start);
		else return 0;
	}
	
	ISceneNode* IrrScene_ISceneManager_getSceneNodeFromName(ISceneManager* scene,const char* name,ISceneNode* start=0)
	{
		if (scene)
			return scene->getSceneNodeFromName(name,start);
		else return 0;
	}
	
	ISceneNode* IrrScene_ISceneManager_getRootSceneNode(ISceneManager* scene)
	{
		if (scene>0)
			return scene->getRootSceneNode();
		else return 0;
	}
	
	IAnimatedMesh* IrrScene_ISceneManager_addTerrainMesh(ISceneManager* scene,const c8* meshname,IImage* texture,IImage* heightmap,dimension2d<f32>* stretch=0,f32 maxHeight=200.0f,dimension2d<s32>* defBlock=0)
	{
		IAnimatedMesh* pRetVal=0;
	
		if (scene>0) {
			bool delS=false;
			if (!stretch) {
				stretch=new dimension2d<f32>(10.0f,10.0f);
				delS=true;
			}
	
			bool delD=false;
			if (!defBlock) {
				defBlock=new dimension2d<s32>(64,64);
				delD=true;
			}
	
			pRetVal=scene->addTerrainMesh(path(meshname),texture,heightmap,*stretch,maxHeight, dimension2du(*defBlock));
	
			if (delS) delete stretch;
			if (delD) delete defBlock;
		}
	
		return pRetVal;
	}
	
	ISceneNode* IrrScene_ISceneManager_addSkyDomeSceneNode(ISceneManager* scene,ITexture* texture,u32 horiRes = 16, u32 vertRes = 8, f32 texturePercentage = 0.9, f32 spherePercentage = 2.0, f32 radius = 1000.f, ISceneNode* parent = 0, s32 id=-1)
	{
		if (scene)
			return scene->addSkyDomeSceneNode(texture,horiRes,vertRes,texturePercentage,spherePercentage,radius,parent,id);
		else return 0;
	}
	
	ITerrainSceneNode* IrrScene_ISceneManager_addTerrainSceneNode(ISceneManager* scene,IReadFile* heightMapFile,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0,SColor* vertexColor=0,s32 maxLOD=5,E_TERRAIN_PATCH_SIZE patchSize=ETPS_17,s32 smoothFactor=0,bool addAlsoIfHeightmapEmpty = false)
	{
		ITerrainSceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delC=false;
			if (!vertexColor) {
				vertexColor=new SColor(255,255,255,255);
				delC=true;
			}
	
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
			pRetVal=scene->addTerrainSceneNode(heightMapFile,parent,id,*pos,*rot,*scale,*vertexColor,maxLOD,patchSize,smoothFactor,addAlsoIfHeightmapEmpty);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
			if (delC) delete vertexColor;
		}
	
		return pRetVal;
	}
	
	ITerrainSceneNode* IrrScene_ISceneManager_addTerrainSceneNodeFromFile(ISceneManager* scene,const c8* heightMapFileName,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0,SColor* vertexColor=0,s32 maxLOD=5,E_TERRAIN_PATCH_SIZE patchSize=ETPS_17,s32 smoothFactor=0,bool addAlsoIfHeightmapEmpty = false)
	{
		ITerrainSceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delC=false;
			if (!vertexColor) {
				vertexColor=new SColor(255,255,255,255);
				delC=true;
			}
	
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
			pRetVal=scene->addTerrainSceneNode(heightMapFileName,parent,id,*pos,*rot,*scale,*vertexColor,maxLOD,patchSize,smoothFactor,addAlsoIfHeightmapEmpty);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
			if (delC) delete vertexColor;
		}
	
		return pRetVal;
	}
	
	// defaults: material=0, hillHeight=0.0f,countHillsLength=0.0f,countHillsWidth=0.0f,textureRepeatCountLength=1.0f,textureRepeatCountWidth=1.0f
	IAnimatedMesh* IrrScene_ISceneManager_addHillPlaneMesh(ISceneManager* scene,
				const c8* name,
				dimension2d<f32>* tileSize, dimension2d<s32>* tileCount,
				SMaterial* material=0,f32 hillHeight=0.0f, 
				dimension2d<f32>* countHills=0,
				dimension2d<f32>* textureRepeatCount=0)
	{
		IAnimatedMesh* pRetVal=0;
	
		if (scene>0) {
	
			bool delCH=false;
			if (!countHills) {
				countHills=new dimension2d<f32>(0.0f,0.0f);
				delCH=true;
			}
			bool delTR=false;
			if (!textureRepeatCount) {
				textureRepeatCount=new dimension2d<f32>(1.0f,1.0f);
				delTR=true;
			}
	
			dimension2d<u32> tileCount2;
			tileCount2.set(tileCount->Width, tileCount->Height);
	
			pRetVal=scene->addHillPlaneMesh(path(name),
				*tileSize,
				tileCount2,
				material,hillHeight,
				*countHills,
				*textureRepeatCount);
	
			if (delCH) delete countHills;
			if (delTR) delete textureRepeatCount;
		}
	
		return pRetVal;
	}
	
	ITextSceneNode* IrrScene_ISceneManager_addTextSceneNode(ISceneManager* scene,IGUIFont* font,const c8* text,SColor* color=0,ISceneNode* parent=0,vector3df* pos=0,s32 id=-1)
	{
		ITextSceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delC=false;
			if (!color) {
				color=new SColor(100,255,255,255);
				delC=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
	
			stringw w_text = text;
			pRetVal=scene->addTextSceneNode(font,w_text.c_str(),*color,parent,*pos,id);
	
			if (delC) delete color;
			if (delP) delete pos;
		}
	
		return pRetVal;
	}
	
	IDummyTransformationSceneNode* IrrScene_ISceneManager_addDummyTransformationSceneNode(ISceneManager* scene,ISceneNode* parent=0,s32 id=-1)
	{
		if (scene>0)
			return scene->addDummyTransformationSceneNode(parent,id);
		else return 0;
	}
	
	ISceneNode* IrrScene_ISceneManager_addEmptySceneNode(ISceneManager* scene,ISceneNode* parent=0,s32 id=-1)
	{
		if (scene>0)
			return scene->addEmptySceneNode(parent,id);
		else return 0;
	}
	
	IParticleSystemSceneNode* IrrScene_ISceneManager_addParticleSystemSceneNode(ISceneManager* scene,bool withDefaultEmitter=true,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0)
	{
		IParticleSystemSceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
	
			pRetVal=scene->addParticleSystemSceneNode(withDefaultEmitter,parent,id,*pos,*rot,*scale);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
		}
	
		return pRetVal;
	}
	
	ISceneNode* IrrScene_ISceneManager_addSkyBoxSceneNode(ISceneManager* scene,ITexture* top,ITexture* bottom,ITexture* left,ITexture* right,ITexture* front,ITexture* back,ISceneNode* parent=0,s32 id=-1)
	{
		if (scene>0)
			return scene->addSkyBoxSceneNode(top,bottom,left,right,front,back,parent,id);
		else return 0;
	}
	
	IBillboardSceneNode* IrrScene_ISceneManager_addBillboardSceneNode(ISceneManager* scene,ISceneNode* parent=0,dimension2d<f32>* size=0,vector3df* pos=0,s32 id=-1,SColor* colorTop = 0,SColor* colorBottom = 0)
	{
		if (scene>0) 
			return scene->addBillboardSceneNode(parent,
				(size ? *size : dimension2d<f32>(10.0f,10.0f)),
				(pos ? *pos : vector3df(0,0,0)), 
				id, 
				(colorTop ? *colorTop : SColor(0xFFFFFFFF)), 
				(colorBottom ? *colorBottom : SColor(0xFFFFFFFF)));	
		else return 0;
	}
	
	ILightSceneNode* IrrScene_ISceneManager_addLightSceneNode(ISceneManager* scene,ISceneNode* parent=0,vector3df* pos=0,SColorf* color=0,f32 radius=100.0f,s32 id=-1)
	{
		ILightSceneNode* pRetVal=0;
	
		if (scene>0) {
	
			bool delC=false;
			if (!color) {
				color=new SColorf(1.0f,1.0f,1.0f);
				delC=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
	
			pRetVal=scene->addLightSceneNode(parent,*pos,*color,radius,id);
	
			if (delC) delete color;
			if (delP) delete pos;
		}
	
		return pRetVal;
	}
	
	ICameraSceneNode* IrrScene_ISceneManager_addCameraSceneNodeFPS(ISceneManager* scene,ISceneNode* parent=0,f32 rotateSpeed=100.0f,f32 moveSpeed=.5f,s32 id=-1,SKeyMap** keyMapArray=0,s32 keyMapSize=0,bool noVerticalMovement=false,f32 jumpSpeed = 0.f, bool invertMouse=false, bool makeActive=true)
	{
		if (scene>0) {
			array<SKeyMap> keymap;
			for (int i=0; i<keyMapSize; i++) {	
				keymap.push_back(*keyMapArray[i]);
			}
		
			return scene->addCameraSceneNodeFPS(parent,rotateSpeed,moveSpeed,id,keymap.pointer(),keyMapSize,noVerticalMovement, jumpSpeed, invertMouse, makeActive);
		} else return 0;
	}
	
	ICameraSceneNode* IrrScene_ISceneManager_addCameraSceneNodeMaya(ISceneManager* scene,ISceneNode* parent=0,f32 rotateSpeed=-1500.0f,f32 zoomSpeed=200.0f,f32 translationSpeed=1500.0f,s32 id=-1, bool makeActive = true)
	{
		if (scene>0)
			return scene->addCameraSceneNodeMaya(parent,rotateSpeed,zoomSpeed,translationSpeed,id, makeActive);
		else return 0;
	}
	
	ICameraSceneNode* IrrScene_ISceneManager_addCameraSceneNode(ISceneManager* scene,ISceneNode* parent=0,vector3df* pos=0,vector3df* lookat=0,s32 id=-1, bool makeActive=true)
	{
		ICameraSceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delLk=false;
			if (!lookat) {
				lookat=new vector3df(0,0,100);
				delLk=true;
			}
	
			pRetVal=scene->addCameraSceneNode(parent,*pos,*lookat,id, makeActive);
	
			if (delP) delete pos;
			if (delLk) delete lookat;
		}
	
		return pRetVal;
	}
	
	IMeshSceneNode* IrrScene_ISceneManager_addOctreeSceneNode(ISceneManager* scene,IMesh* mesh,ISceneNode* parent=0,s32 id=-1,s32 minimalPolysPerNode=512,bool alsoAddIfMeshPointerZero=false)
	{
		if (scene>0)
			return scene->addOctreeSceneNode(mesh,parent,id,minimalPolysPerNode,alsoAddIfMeshPointerZero);
		else return 0;
	}
	
	IMeshSceneNode* IrrScene_ISceneManager_addAnimatedOctreeSceneNode(ISceneManager* scene,IAnimatedMesh* mesh,ISceneNode* parent=0,s32 id=-1,s32 minimalPolysPerNode=128)
	{
		if (scene>0)
			return scene->addOctreeSceneNode(mesh,parent,id,minimalPolysPerNode);
		else return 0;
	}
	
	ISceneNode* IrrScene_ISceneManager_addWaterSurfaceSceneNode(ISceneManager* scene,IMesh* mesh,f32 waveHeight=2.0f,f32 waveSpeed=300.0f,f32 waveLength=10.0f,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0)
	{
		ISceneNode* pRetVal=0;
	
		if (scene>0) {
			
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
					
			pRetVal=scene->addWaterSurfaceSceneNode(mesh,waveHeight,waveSpeed,waveLength,parent,id,*pos,*rot,*scale);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
		}
	
		return pRetVal;
	}
	
	ISceneNode* IrrScene_ISceneManager_addMeshSceneNode(ISceneManager* scene,IMesh* mesh,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0,bool alsoAddIfMeshPointerZero=false)
	{
		ISceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
	
			pRetVal=scene->addMeshSceneNode(mesh,parent,id,*pos,*rot,*scale,alsoAddIfMeshPointerZero);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
		}
	
		return pRetVal;
	}
	
	
	IAnimatedMeshSceneNode* IrrScene_ISceneManager_addAnimatedMeshSceneNode(ISceneManager* scene,IAnimatedMesh* mesh,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0,bool alsoAddIfMeshPointerZero=false)
	{
		IAnimatedMeshSceneNode* pRetVal=0;
	
		if (scene>0) {
	
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
	
			pRetVal=scene->addAnimatedMeshSceneNode(mesh,parent,id,*pos,*rot,*scale,alsoAddIfMeshPointerZero);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
		}
	
		return pRetVal;
	}
				
	ISceneNode* IrrScene_ISceneManager_addCubeSceneNode(ISceneManager* scene,f32 size=10.0f,ISceneNode* parent=0,s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0)
	{
		ISceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
	
			pRetVal=scene->addCubeSceneNode(size,parent,id,*pos,*rot,*scale);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
		}
	
		return pRetVal;
	}
	
	ISceneNode* IrrScene_ISceneManager_addSphereSceneNode(ISceneManager* scene,f32 radius=5.0f, s32 polyCount=16, ISceneNode* parent=0, s32 id=-1,vector3df* pos=0,vector3df* rot=0,vector3df* scale=0)
	{
		ISceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delR=false;
			if (!rot) {
				rot=new vector3df(0,0,0);
				delR=true;
			}
			bool delP=false;
			if (!pos) {
				pos=new vector3df(0,0,0);
				delP=true;
			}
			bool delS=false;
			if (!scale) {
				scale=new vector3df(1.0f,1.0f,1.0f);
				delS=true;
			}
	
			pRetVal=scene->addSphereSceneNode(radius,polyCount,parent,id,*pos,*rot,*scale);
	
			if (delR) delete rot;
			if (delP) delete pos;
			if (delS) delete scale;
		}
	
		return pRetVal;
	}
	
	IVideoDriver* IrrScene_ISceneManager_getVideoDriver(ISceneManager* scene)
	{
		if (scene>0)
			return scene->getVideoDriver();
		else return 0;
	}
	
	IAnimatedMesh* IrrScene_ISceneManager_getMesh(ISceneManager* scene,const c8* filename)
	{
		if (scene>0)
			return scene->getMesh(path(filename));
		else return 0;
	}

	IAnimatedMesh* IrrScene_ISceneManager_getMeshFromFileIO(ISceneManager* scene,io::IReadFile* file)
	{
		if (scene>0)
			return scene->getMesh(file);
		else return 0;
	}
	
	void IrrScene_ISceneManager_drawAll(ISceneManager* scene)
	{
		if (scene>0)
			scene->drawAll();
	}
	
	IMeshCache* IrrScene_ISceneManager_getMeshCache(ISceneManager* scene)
	{
		if (scene)
			return scene->getMeshCache();
		else return 0;
	}
	
	ISceneManager* IrrScene_ISceneManager_createNewSceneManager(ISceneManager* scene,bool cloneContent=false)
	{
		if (scene)
			return scene->createNewSceneManager(cloneContent);
		else return 0;
	}
	
	ISceneNodeFactory* IrrScene_ISceneManager_getDefaultSceneNodeFactory(ISceneManager* scene)
	{
		if (scene)
			return scene->getDefaultSceneNodeFactory();
		else return 0;
	}
	
	void IrrScene_ISceneManager_registerSceneNodeFactory(ISceneManager* scene,ISceneNodeFactory* factoryToAdd)
	{
		if (scene)
			scene->registerSceneNodeFactory(factoryToAdd);
	}
	
	u32 IrrScene_ISceneManager_getRegisteredSceneNodeFactoryCount(ISceneManager* scene)
	{
		if (scene)
			return scene->getRegisteredSceneNodeFactoryCount();
		else return 0;
	}
	
	ISceneNodeFactory* IrrScene_ISceneManager_getSceneNodeFactory(ISceneManager* scene,u32 index)
	{
		if (scene)
			return scene->getSceneNodeFactory(index);
		else return 0;
	}
	
	ISceneNodeAnimatorFactory* IrrScene_ISceneManager_getDefaultSceneNodeAnimatorFactory(ISceneManager* scene)
	{
		if (scene)
			return scene->getDefaultSceneNodeAnimatorFactory();
		else return 0;
	}
	
	void IrrScene_ISceneManager_registerSceneNodeAnimatorFactory(ISceneManager* scene,ISceneNodeAnimatorFactory* factoryToAdd)
	{
		if (scene)
			scene->registerSceneNodeAnimatorFactory(factoryToAdd);
	}
	
	u32 IrrScene_ISceneManager_getRegisteredSceneNodeAnimatorFactoryCount(ISceneManager* scene)
	{
		if (scene)
			return scene->getRegisteredSceneNodeAnimatorFactoryCount();
		else return -1;
	}
	
	ISceneNodeAnimatorFactory* IrrScene_ISceneManager_getSceneNodeAnimatorFactory(ISceneManager* scene,u32 index) 
	{
		if (scene)
			return scene->getSceneNodeAnimatorFactory(index);
		else return 0;
	}
	
	IAttributes* IrrScene_ISceneManager_getParameters(ISceneManager* scene)
	{
		if (scene)
			return scene->getParameters();
		else return 0;
	}
	
	const c8* IrrScene_ISceneManager_getSceneNodeTypeName(ISceneManager* scene,ESCENE_NODE_TYPE type)
	{
		if (scene)
			return scene->getSceneNodeTypeName(type);
		else return 0;
	}
	
	bool IrrScene_ISceneManager_saveSceneToFile(ISceneManager* scene,const c8* filename, ISceneUserDataSerializer* userDataSerializer=0)
	{
		if (scene)
			return scene->saveScene(path(filename),userDataSerializer);
		else return false;
	}
	
	bool IrrScene_ISceneManager_saveSceneToFileIO(ISceneManager* scene,io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0)
	{
		if (scene)
			return scene->saveScene(file,userDataSerializer);
		else return false;
	}
	
	bool IrrScene_ISceneManager_loadSceneFromFile(ISceneManager* scene,const c8* filename, ISceneUserDataSerializer* userDataSerializer=0)
	{
		if (scene)
			return scene->loadScene(path(filename),userDataSerializer);
		else return false;
	}
	
	bool IrrScene_ISceneManager_loadSceneFromFileIO(ISceneManager* scene,io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0)
	{
		if (scene)
			return scene->loadScene(file,userDataSerializer);
		else return false;
	}

	bool IrrScene_ISceneManager_drop(ISceneManager* unk)
	{
		if (unk)
			return unk->drop();
		else return 0;
	}
	
	const c8* IrrScene_ISceneManager_getDebugName(ISceneManager* unk)
	{
		if (unk)
			return unk->getDebugName();
		else return "";
	}
	
	void IrrScene_ISceneManager_grab(ISceneManager* unk)
	{
		if (unk)
			unk->grab();
	}
	
	void IrrScene_ISceneManager_setAmbientLight(ISceneManager* scene,SColorf* ambientColor)
	{
		if (scene) 
			scene->setAmbientLight(*ambientColor);
	}

	video::SColorf* IrrScene_ISceneManager_getAmbientLight(ISceneManager* scene)
	{
		if (scene) 
			return new SColorf(scene->getAmbientLight());
		else return 0;
	}
	
	IGUIEnvironment* IrrScene_ISceneManager_getGUIEnvironment(ISceneManager* scene)
	{
		if (scene)
			return scene->getGUIEnvironment();
		else return 0;
	}

	IMeshSceneNode* IrrScene_ISceneManager_addQuake3SceneNode(ISceneManager* scene,IMeshBuffer* meshBuffer, const quake3::IShader * shader,ISceneNode* parent=0, s32 id=-1)
	{
		if (scene)
			return scene->addQuake3SceneNode(meshBuffer,shader,parent,id);
		else return 0;
	}
	
	IBillboardTextSceneNode* IrrScene_ISceneManager_addBillboardTextSceneNode(ISceneManager* scene, 
		gui::IGUIFont* font, const wchar_t* text, ISceneNode* parent = 0,
		const dimension2df* size = 0,
		const vector3df* pos = 0, s32 id=-1,
		SColor* colorTop = 0, SColor* colorBottom = 0)
	{
		IBillboardTextSceneNode* pRetVal=0;
	
		if (scene>0) {
			bool delP=false;
			if (!pos) { pos=new vector3df(0,0,0); delP=true; }
			bool delS=false;
			if (!size) { size=new dimension2d<f32>(10.0f,10.0f); delS=true; }

			bool delShadeTop=false;
			bool delShadeDown=false;
			if (!colorTop){ colorTop=new SColor(0xFFFFFFFF); delShadeTop=true;}
			if (!colorBottom){ colorBottom=new SColor(0xFFFFFFFF); delShadeDown=true;}
						
			pRetVal=scene->addBillboardTextSceneNode(font, text, parent, *size, *pos, id, *colorTop, *colorBottom);
	
			if (delP) delete pos;
			if (delS) delete size;
			if (delShadeTop) delete colorTop;
			if (delShadeDown) delete colorBottom;
		}
	
		return pRetVal;
	}
	
	IAnimatedMesh* IrrScene_ISceneManager_addArrowMesh(ISceneManager* scene,const c8* name,
			SColor* vtxColor0 = 0, SColor* vtxColor1 = 0,
			u32 tesselationCylinder = 4, u32 tesselationCone = 8, f32 height = 1.0f,
			f32 cylinderHeight=  0.6f, f32 width0 = 0.05f, f32 width1 = 0.3f
			) 
	{
		IAnimatedMesh* pRetVal=0;

		bool delvtxColor0=false;
		bool delvtxColor1=false;
		if (!vtxColor0){ vtxColor0=new SColor(0xFFFFFFFF); delvtxColor0=true;}
		if (!vtxColor1){ vtxColor1=new SColor(0xFFFFFFFF); delvtxColor1=true;}

		if (scene) {
			pRetVal = scene->addArrowMesh(path(name),*vtxColor0,*vtxColor1,tesselationCylinder,tesselationCone,height,cylinderHeight,width0,width1);
		}

		if (delvtxColor0) delete vtxColor0;
		if (delvtxColor1) delete vtxColor1;

		return pRetVal;
	}

	IAnimatedMesh* IrrScene_ISceneManager_addSphereMesh(ISceneManager* scene,const c8* name, f32 radius=5.f, u32 polyCountX = 16, u32 polyCountY = 16)
	{
		if (scene) {
			return scene->addSphereMesh(path(name), radius, polyCountX, polyCountY);
		} else return 0;
	}
	
	ISceneNode* IrrScene_ISceneManager_getSceneNodeFromType(ISceneManager* scene,ESCENE_NODE_TYPE type,ISceneNode* start=0)
	{
		if (scene)
			return scene->getSceneNodeFromType(type,start);
		else return 0;
	}

	ISceneNode* IrrScene_ISceneManager_addSceneNode(ISceneManager* scene,const char* sceneNodeTypeName, ISceneNode* parent = 0)
	{
		if (scene)
			return scene->addSceneNode(sceneNodeTypeName,parent);
		else return 0;
	}

	s32 IrrScene_ISceneManager_getSceneNodesFromType(ISceneManager* scene,ESCENE_NODE_TYPE type, u32** outNodePtrs, ISceneNode* start=0)
	{
		if (scene)	{			

			core::array<scene::ISceneNode*> outNodes;
			scene->getSceneNodesFromType(type,outNodes,start);

			s32 size = outNodes.size();
			
			Irr_ptrarray_allocate(outNodePtrs,size);
			

			for (int i=0; i<size; i++) {	
				((u32*)*outNodePtrs)[i]=(u32)(outNodes[i]);
			}

			return size;
		} else return 0;
	}

	IVolumeLightSceneNode* IrrScene_ISceneManager_addVolumeLightSceneNode(ISceneManager* scene, 
		ISceneNode* parent=0, s32 id=-1,
		const u32 subdivU = 32, const u32 subdivV = 32,
		const video::SColor* foot = 0,
		const video::SColor* tail = 0,
		const core::vector3df* position = 0,
		const core::vector3df* rotation = 0,
		const core::vector3df* scale = 0)
	{
		if (scene)
			return scene->addVolumeLightSceneNode(parent, id, subdivU, subdivV, 
				(foot ? *foot : SColor(51, 0, 230, 180)),
				(tail ? *tail : SColor(0, 0, 0, 0)), 
				(position ? *position : vector3df(0,0,0)), 
				(rotation ? *rotation : vector3df(0,0,0)), 
				(scale ? *scale : vector3df(1.0f, 1.0f, 1.0f))
			);
		else return 0;
	}

	void IrrScene_ISceneManager_setLightManager(ISceneManager* scene, ILightManager* lightManager)
	{	
		if (scene)
			scene->setLightManager(lightManager);
	}

	IFileSystem* IrrScene_ISceneManager_getFileSystem(ISceneManager* scene)
	{
		if (scene)
			return scene->getFileSystem();
		else return 0;
	}
	
	IAnimatedMesh* IrrScene_ISceneManager_addVolumeLightMesh(
		ISceneManager* scene,
		const c8* name,
		const u32 SubdivideU = 32, const u32 SubdivideV = 32,
		SColor* FootColor = 0,
		SColor* TailColor = 0) 
	{
		if (scene)
			return scene->addVolumeLightMesh(path(name), SubdivideU, SubdivideV, (FootColor ? *FootColor : SColor(51, 0, 230, 180)), (TailColor ? *TailColor : SColor(0, 0, 0, 0)));
		else return 0;
	}
	
	const c8* IrrScene_ISceneManager_getAnimatorTypeName(ISceneManager* scene, ESCENE_NODE_ANIMATOR_TYPE type)
	{
		if (scene)
			return scene->getAnimatorTypeName(type);
		else return "";
	}
	
	ISkinnedMesh* IrrScene_ISceneManager_createSkinnedMesh(ISceneManager* scene)
	{
		if (scene)
			return scene->createSkinnedMesh();
		else return 0;
	}
	
	const IGeometryCreator* IrrScene_ISceneManager_getGeometryCreator(ISceneManager* scene)
	{
		if (scene)
			return scene->getGeometryCreator();
		else return 0;
	}
	
	bool IrrScene_ISceneManager_isCulled(ISceneManager* scene, const ISceneNode* node) 
	{
		if (scene)
			return scene->isCulled(node);
		else return false;
	}
}

