Beispiel #1
0
void CCullingSystem::initializeOccluders()
{
	static core::array<SOccluderEntry> occluders_tmp;
	occluders_tmp.set_used(0);

	m_Occluders.sort();

	for (u32 i=0; i<m_Occluders.size(); i++)
	{
		bool occluded = false;

		for (u32 j=i+1; j<m_Occluders.size(); j++)
		{
			if (m_Occluders[j].isOccludeByPlanes(m_Occluders[i].tbbox))
			{
				occluded = true;
				break;
			}
		}

		if (!occluded)
		{
			occluders_tmp.push_back(m_Occluders[i]);	
		}
	}

	m_Occluders.set_used(0);
	m_Occluders = occluders_tmp;
}
Beispiel #2
0
static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3,
                         v3f p, v3s16 dir, v3f scale, u8 light_source, core::array<FastFace> &dest)
{
    FastFace face;

    // Position is at the center of the cube.
    v3f pos = p * BS;

    v3f vertex_pos[4];
    v3s16 vertex_dirs[4];
    getNodeVertexDirs(dir, vertex_dirs);
    for(u16 i=0; i<4; i++)
    {
        vertex_pos[i] = v3f(
                            BS/2*vertex_dirs[i].X,
                            BS/2*vertex_dirs[i].Y,
                            BS/2*vertex_dirs[i].Z
                        );
    }

    for(u16 i=0; i<4; i++)
    {
        vertex_pos[i].X *= scale.X;
        vertex_pos[i].Y *= scale.Y;
        vertex_pos[i].Z *= scale.Z;
        vertex_pos[i] += pos;
    }

    f32 abs_scale = 1.;
    if     (scale.X < 0.999 || scale.X > 1.001) abs_scale = scale.X;
    else if(scale.Y < 0.999 || scale.Y > 1.001) abs_scale = scale.Y;
    else if(scale.Z < 0.999 || scale.Z > 1.001) abs_scale = scale.Z;

    v3f normal(dir.X, dir.Y, dir.Z);

    u8 alpha = tile.alpha;

    float x0 = tile.texture.pos.X;
    float y0 = tile.texture.pos.Y;
    float w = tile.texture.size.X;
    float h = tile.texture.size.Y;

    face.vertices[0] = video::S3DVertex(vertex_pos[0], normal,
                                        MapBlock_LightColor(alpha, li0, light_source),
                                        core::vector2d<f32>(x0+w*abs_scale, y0+h));
    face.vertices[1] = video::S3DVertex(vertex_pos[1], normal,
                                        MapBlock_LightColor(alpha, li1, light_source),
                                        core::vector2d<f32>(x0, y0+h));
    face.vertices[2] = video::S3DVertex(vertex_pos[2], normal,
                                        MapBlock_LightColor(alpha, li2, light_source),
                                        core::vector2d<f32>(x0, y0));
    face.vertices[3] = video::S3DVertex(vertex_pos[3], normal,
                                        MapBlock_LightColor(alpha, li3, light_source),
                                        core::vector2d<f32>(x0+w*abs_scale, y0));

    face.tile = tile;

    dest.push_back(face);
}
Beispiel #3
0
void MapSector::getBlocks(core::array<MapBlock*> &dest)
{
	core::map<s16, MapBlock*>::Iterator bi;

	bi = m_blocks.getIterator();
	for(; bi.atEnd() == false; bi++)
	{
		MapBlock *b = bi.getNode()->getValue();
		dest.push_back(b);
	}
}
bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
	joystickInfo.clear();
	ActiveJoysticks.clear();

	const u32 numberOfJoysticks = ::joyGetNumDevs();
	JOYINFOEX info;
	info.dwSize = sizeof(info);
	info.dwFlags = JOY_RETURNALL;

	JoystickInfo activeJoystick;
	SJoystickInfo returnInfo;

	joystickInfo.reallocate(numberOfJoysticks);
	ActiveJoysticks.reallocate(numberOfJoysticks);

	u32 joystick = 0;
	for(; joystick < numberOfJoysticks; ++joystick)
	{
		if(JOYERR_NOERROR == joyGetPosEx(joystick, &info)
			&&
			JOYERR_NOERROR == joyGetDevCaps(joystick, 
											&activeJoystick.Caps,
											sizeof(activeJoystick.Caps)))
		{
			activeJoystick.Index = joystick;
			ActiveJoysticks.push_back(activeJoystick);

			returnInfo.Joystick = (u8)joystick;
			returnInfo.Axes = activeJoystick.Caps.wNumAxes;
			returnInfo.Buttons = activeJoystick.Caps.wNumButtons;
			returnInfo.Name = activeJoystick.Caps.szPname;
			returnInfo.PovHat = ((activeJoystick.Caps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV)
								? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT;

			joystickInfo.push_back(returnInfo);
		}
	}

	for(joystick = 0; joystick < joystickInfo.size(); ++joystick)
	{
		char logString[256];
		(void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'",
			joystick, joystickInfo[joystick].Axes, 
			joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str());
		os::Printer::log(logString, ELL_INFORMATION);
	}

	return true;
#else
	return false;
#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
}
Beispiel #5
0
// Create a tower of the specified number of boxes
void createBoxTower(IPhysxManager* physxManager, scene::ISceneManager* smgr, video::IVideoDriver* driver, core::array<SPhysxAndNodePair*>& objects, f32 towerSize, f32 density, const core::vector3df& position) {

    const core::vector3df scale(4,4,4);
    const f32 spacing = -2.0f*physxManager->getSkinWidth();
    core::vector3df pos = position + core::vector3df(0.0f, scale.Y/2.0f, 0.0f);

    while (towerSize > 0) {
        objects.push_back(createBox(physxManager, smgr, driver, pos, scale, density));
        pos.Y += (scale.Y + spacing);
        towerSize--;
    }

}
//! read indices
void CIrrMeshFileLoader::readIndices(io::IXMLReader* reader, int indexCount, core::array<u16>& indices)
{
	indices.reallocate(indexCount);

	core::stringc data = reader->getNodeData();
	const c8* p = &data[0];

	for (int i=0; i<indexCount && *p; ++i)
	{
		findNextNoneWhiteSpace(&p);
		indices.push_back((u16)readInt(&p));
	}
}
Beispiel #7
0
	void Surface::load(BinaryFileReader* pReader)
	{
		flags = pReader->readLong();
		textureName = pReader->readString();

		lightMapId = pReader->readLong();
		pReader->readVec2f(&uvOffset);
		pReader->readVec2f(&uvScale);
		uvRotation = pReader->readFloat();
		s32 vtxCount = pReader->readLong();
		s32 triCount = pReader->readLong();
		s32 lineCount = pReader->readLong();

		for(s32 v = 0; v < vtxCount; v++)
		{
			Vertex *vtx = new Vertex();
			vtx->load(pReader);
			vertices.push_back(vtx);
		}

		for(s32 t = 0; t < triCount; t++)
		{
			Triangle tri;
			pReader->readBuffer(&tri, sizeof(tri));
			triangles.push_back(tri);
		}

		for(s32 l = 0; l < lineCount; l++)
		{
			Line line;
			pReader->readBuffer(&line,sizeof(line));
			lines.push_back(line);

		}

	}
/*
	Here is an example traditional set-up sequence for a DrawSpec list:

	std::string furnace_inv_id = "nodemetadata:0,1,2";
	core::array<GUIInventoryMenu::DrawSpec> draw_spec;
	draw_spec.push_back(GUIInventoryMenu::DrawSpec(
			"list", furnace_inv_id, "fuel",
			v2s32(2, 3), v2s32(1, 1)));
	draw_spec.push_back(GUIInventoryMenu::DrawSpec(
			"list", furnace_inv_id, "src",
			v2s32(2, 1), v2s32(1, 1)));
	draw_spec.push_back(GUIInventoryMenu::DrawSpec(
			"list", furnace_inv_id, "dst",
			v2s32(5, 1), v2s32(2, 2)));
	draw_spec.push_back(GUIInventoryMenu::DrawSpec(
			"list", "current_player", "main",
			v2s32(0, 5), v2s32(8, 4)));
	setDrawSpec(draw_spec);

	Here is the string for creating the same DrawSpec list (a single line,
	spread to multiple lines here):

	GUIInventoryMenu::makeDrawSpecArrayFromString(
			draw_spec,
			"nodemetadata:0,1,2",
			"invsize[8,9;]"
			"list[current_name;fuel;2,3;1,1;]"
			"list[current_name;src;2,1;1,1;]"
			"list[current_name;dst;5,1;2,2;]"
			"list[current_player;main;0,5;8,4;]");

	Returns inventory menu size defined by invsize[].
*/
v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString(
		core::array<GUIInventoryMenu::DrawSpec> &draw_spec,
		const std::string &data,
		const std::string &current_name)
{
	v2s16 invsize(8,9);
	Strfnd f(data);
	while(f.atend() == false)
	{
		std::string type = trim(f.next("["));
		//infostream<<"type="<<type<<std::endl;
		if(type == "list")
		{
			std::string name = f.next(";");
			if(name == "current_name")
				name = current_name;
			std::string subname = f.next(";");
			s32 pos_x = stoi(f.next(","));
			s32 pos_y = stoi(f.next(";"));
			s32 geom_x = stoi(f.next(","));
			s32 geom_y = stoi(f.next(";"));
			infostream<<"list name="<<name<<", subname="<<subname
					<<", pos=("<<pos_x<<","<<pos_y<<")"
					<<", geom=("<<geom_x<<","<<geom_y<<")"
					<<std::endl;
			draw_spec.push_back(GUIInventoryMenu::DrawSpec(
					type, name, subname,
					v2s32(pos_x,pos_y),v2s32(geom_x,geom_y)));
			f.next("]");
		}
		else if(type == "invsize")
		{
			invsize.X = stoi(f.next(","));
			invsize.Y = stoi(f.next(";"));
			infostream<<"invsize ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
			f.next("]");
		}
		else
		{
			// Ignore others
			std::string ts = f.next("]");
			infostream<<"Unknown DrawSpec: type="<<type<<", data=\""<<ts<<"\""
					<<std::endl;
		}
	}

	return invsize;
}
Beispiel #9
0
void MapBlockObjectList::getObjects(v3f origin, f32 max_d,
		core::array<DistanceSortedObject> &dest)
{
	for(core::map<s16, MapBlockObject*>::Iterator
			i = m_objects.getIterator();
			i.atEnd() == false; i++)
	{
		MapBlockObject *obj = i.getNode()->getValue();

		f32 d = (obj->getRelativeShowPos() - origin).getLength();

		if(d > max_d)
			continue;

		DistanceSortedObject dso(obj, d);

		dest.push_back(dso);
	}
}
Beispiel #10
0
// Create a stack of meshes, with the bottom row having the specified number of cubes
void createMeshStack(IPhysxManager* physxManager, scene::ISceneManager* smgr, video::IVideoDriver* driver, core::array<SPhysxAndNodePair*>& objects, scene::IMesh* mesh, f32 stackSize, f32 density) {

    const core::vector3df meshSize = mesh->getBoundingBox().getExtent();
    const f32 spacing = -2.0f*physxManager->getSkinWidth();
    core::vector3df pos(0.0f, meshSize.Y/2.0f, 0.0f);
    f32 offset = -stackSize * (meshSize.X + spacing) * 0.5f;

    while (stackSize > 0) {
        for (s32 i = 0 ; i < stackSize ; ++i) {
            pos.X = offset + (f32)i * (meshSize.X + spacing);
            objects.push_back(createMeshBoundingBox(physxManager, smgr, driver, mesh, pos, core::vector3df(1,1,1), density));
        }

        offset += meshSize.X / 2.0f;
        pos.Y += (meshSize.Y + spacing);
        stackSize--;
    }

}
Beispiel #11
0
// Create a stack of boxes, with the bottom row having the specified number of boxes
void createBoxStack(IPhysxManager* physxManager, scene::ISceneManager* smgr, video::IVideoDriver* driver, core::array<SPhysxAndNodePair*>& objects, f32 stackSize, f32 density, const core::vector3df& position) {

    const core::vector3df scale(4,4,4);
    const f32 spacing = -2.0f*physxManager->getSkinWidth();
    core::vector3df pos = position + core::vector3df(0.0f, scale.Y/2.0f, 0.0f);
    f32 offset = -stackSize * (scale.X + spacing) * 0.5f;

    while (stackSize > 0) {
        for (s32 i = 0 ; i < stackSize ; ++i) {
            pos.X = offset + (f32)i * (scale.X + spacing);
            objects.push_back(createBox(physxManager, smgr, driver, pos, scale, density));
        }

        offset += scale.X / 2.0f;
        pos.Y += (scale.Y + spacing);
        stackSize--;
    }

}
void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
		core::array<DistanceSortedActiveObject> &dest)
{
	for(core::map<u16, ClientActiveObject*>::Iterator
			i = m_active_objects.getIterator();
			i.atEnd()==false; i++)
	{
		ClientActiveObject* obj = i.getNode()->getValue();

		f32 d = (obj->getPosition() - origin).getLength();

		if(d > max_d)
			continue;

		DistanceSortedActiveObject dso(obj, d);

		dest.push_back(dso);
	}
}
Beispiel #13
0
//! Activate any joysticks, and generate events for them.
bool CIrrDeviceSDL::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
	joystickInfo.clear();

	// we can name up to 256 different joysticks
	const int numJoysticks = core::min_(SDL_NumJoysticks(), 256);
	Joysticks.reallocate(numJoysticks);
	joystickInfo.reallocate(numJoysticks);

	int joystick = 0;
	for (; joystick<numJoysticks; ++joystick)
	{
		Joysticks.push_back(SDL_JoystickOpen(joystick));
		SJoystickInfo info;

		info.Joystick = joystick;
		info.Axes = SDL_JoystickNumAxes(Joysticks[joystick]);
		info.Buttons = SDL_JoystickNumButtons(Joysticks[joystick]);
		info.Name = SDL_JoystickName(joystick);
		info.PovHat = (SDL_JoystickNumHats(Joysticks[joystick]) > 0)
						? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT;

		joystickInfo.push_back(info);
	}

	for(joystick = 0; joystick < (int)joystickInfo.size(); ++joystick)
	{
		char logString[256];
		(void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'",
		 joystick, joystickInfo[joystick].Axes,
   joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str());
		os::Printer::log(logString, ELL_INFORMATION);
	}

	return true;

#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_

	return false;
}
Beispiel #14
0
	void Mesh::load(BinaryFileReader* pReader, bool bReadVisGroups)
	{
		flags = pReader->readLong();
		groupId = pReader->readLong();
		props = pReader->readString();
		pReader->readColorRGB(&color);
		pReader->readVec3f(&position);
		if(bReadVisGroups)
			visgroupId = pReader->readLong();
		else
			visgroupId = 0;

		s32 count = pReader->readLong();

		for(s32 i = 0; i < count; i++)
		{
			Surface* surf = new Surface();
			surf->load(pReader);
			surfaces.push_back(surf);
		}
	}
Beispiel #15
0
/*
	This method generates all the textures
*/
u32 TextureSource::getTextureIdDirect(const std::string &name)
{
	//infostream<<"getTextureIdDirect(): name=\""<<name<<"\""<<std::endl;

	// Empty name means texture 0
	if(name == "")
	{
		infostream<<"getTextureIdDirect(): name is empty"<<std::endl;
		return 0;
	}
	
	/*
		Calling only allowed from main thread
	*/
	if(get_current_thread_id() != m_main_thread)
	{
		errorstream<<"TextureSource::getTextureIdDirect() "
				"called not from main thread"<<std::endl;
		return 0;
	}

	/*
		See if texture already exists
	*/
	{
		JMutexAutoLock lock(m_atlaspointer_cache_mutex);

		core::map<std::string, u32>::Node *n;
		n = m_name_to_id.find(name);
		if(n != NULL)
		{
			/*infostream<<"getTextureIdDirect(): \""<<name
					<<"\" found in cache"<<std::endl;*/
			return n->getValue();
		}
	}

	/*infostream<<"getTextureIdDirect(): \""<<name
			<<"\" NOT found in cache. Creating it."<<std::endl;*/
	
	/*
		Get the base image
	*/

	char separator = '^';

	/*
		This is set to the id of the base image.
		If left 0, there is no base image and a completely new image
		is made.
	*/
	u32 base_image_id = 0;
	
	// Find last meta separator in name
	s32 last_separator_position = -1;
	for(s32 i=name.size()-1; i>=0; i--)
	{
		if(name[i] == separator)
		{
			last_separator_position = i;
			break;
		}
	}
	/*
		If separator was found, construct the base name and make the
		base image using a recursive call
	*/
	std::string base_image_name;
	if(last_separator_position != -1)
	{
		// Construct base name
		base_image_name = name.substr(0, last_separator_position);
		/*infostream<<"getTextureIdDirect(): Calling itself recursively"
				" to get base image of \""<<name<<"\" = \""
                <<base_image_name<<"\""<<std::endl;*/
		base_image_id = getTextureIdDirect(base_image_name);
	}
	
	//infostream<<"base_image_id="<<base_image_id<<std::endl;
	
	video::IVideoDriver* driver = m_device->getVideoDriver();
	assert(driver);

	video::ITexture *t = NULL;

	/*
		An image will be built from files and then converted into a texture.
	*/
	video::IImage *baseimg = NULL;
	
	// If a base image was found, copy it to baseimg
	if(base_image_id != 0)
	{
		JMutexAutoLock lock(m_atlaspointer_cache_mutex);

		SourceAtlasPointer ap = m_atlaspointer_cache[base_image_id];

		video::IImage *image = ap.atlas_img;
		
		if(image == NULL)
		{
			infostream<<"getTextureIdDirect(): WARNING: NULL image in "
					<<"cache: \""<<base_image_name<<"\""
					<<std::endl;
		}
		else
		{
			core::dimension2d<u32> dim = ap.intsize;

			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);

			core::position2d<s32> pos_to(0,0);
			core::position2d<s32> pos_from = ap.intpos;
			
			image->copyTo(
					baseimg, // target
					v2s32(0,0), // position in target
					core::rect<s32>(pos_from, dim) // from
			);

			/*infostream<<"getTextureIdDirect(): Loaded \""
					<<base_image_name<<"\" from image cache"
					<<std::endl;*/
		}
	}
	
	/*
		Parse out the last part of the name of the image and act
		according to it
	*/

	std::string last_part_of_name = name.substr(last_separator_position+1);
	//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;

	// Generate image according to part of name
	if(!generate_image(last_part_of_name, baseimg, m_device, &m_sourcecache))
	{
		errorstream<<"getTextureIdDirect(): "
				"failed to generate \""<<last_part_of_name<<"\""
				<<std::endl;
	}

	// If no resulting image, print a warning
	if(baseimg == NULL)
	{
		errorstream<<"getTextureIdDirect(): baseimg is NULL (attempted to"
				" create texture \""<<name<<"\""<<std::endl;
	}
	
	if(baseimg != NULL)
	{
		// Create texture from resulting image
		t = driver->addTexture(name.c_str(), baseimg);
	}
	
	/*
		Add texture to caches (add NULL textures too)
	*/

	JMutexAutoLock lock(m_atlaspointer_cache_mutex);
	
	u32 id = m_atlaspointer_cache.size();
	AtlasPointer ap(id);
	ap.atlas = t;
	ap.pos = v2f(0,0);
	ap.size = v2f(1,1);
	ap.tiled = 0;
	core::dimension2d<u32> baseimg_dim(0,0);
	if(baseimg)
		baseimg_dim = baseimg->getDimension();
	SourceAtlasPointer nap(name, ap, baseimg, v2s32(0,0), baseimg_dim);
	m_atlaspointer_cache.push_back(nap);
	m_name_to_id.insert(name, id);

	/*infostream<<"getTextureIdDirect(): "
			<<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl;*/
	
	return id;
}
Beispiel #16
0
void CCombatNPC::writeOutXMLDescription(core::array<core::stringw>& names, core::array<core::stringw>& values) const {
    
	IAIEntity::writeOutXMLDescription(names, values);
  
	core::stringw strw;
	names.push_back(core::stringw(L"waypointGroupName"));
	values.push_back(core::stringw(WaypointGroup->getName()).c_str());
	names.push_back(core::stringw(L"startWaypointID"));
	strw = (CurrentWaypoint ? core::stringw(CurrentWaypoint->getID()) : core::stringw(0));
	values.push_back(strw);
	names.push_back(core::stringw(L"fovDimensions"));
	core::vector3df dim = (FieldOfView ? FieldOfView->getDimensions() : core::vector3df(0,0,0));
	strw = core::stringw(dim.X);
	strw += ",";
	strw += dim.Y;
	strw += ",";
	strw += dim.Z;
	values.push_back(strw);
	names.push_back(core::stringw(L"range"));
	strw = core::stringw(Range);    
	values.push_back(strw);
	names.push_back(core::stringw(L"moveSpeed"));
	strw = core::stringw(MoveSpeed);
	values.push_back(strw);
	names.push_back(core::stringw(L"atDestinationThreshold"));
	strw = core::stringw(AtDestinationThreshold);
	values.push_back(strw);
	names.push_back(core::stringw(L"fovOcclusionCheck"));
	strw = core::stringw(FovOcclusionCheck);
	values.push_back(strw);
	names.push_back(core::stringw(L"checkFovForEnemies"));
	strw = core::stringw(CheckFovForEnemies);
	values.push_back(strw);
	names.push_back(core::stringw(L"checkFovForAllies"));
	strw = core::stringw(CheckFovForAllies);
	values.push_back(strw);
         
}
void CTreeGenerator::appendBranch( const core::matrix4& transform, SBranch* branch, f32 lengthScale, f32 radiusScale, s32 level, SMeshBuffer* buffer, core::array<STreeLeaf>& leaves )
{
    if ( level <= 0 )
        return; // Do nothing, this branch is invisible.
    
    // Add this branch
    f32 length = lengthScale * getFloatFromValueRange( branch->Length, Seed++ );
    
    f32 radius = getFloatFromValueRange( branch->Radius, Seed++ );
    
    f32 radiusEndScale = radiusScale * getFloatFromValueRange( branch->RadiusEnd, Seed++ );
    
    f32 radiusEnd = radius * radiusEndScale;
    
    radius = radiusScale * radius;
    
    if ( level == 1 )
        radiusEnd = 0;
    
    s32 radialSegments = (level*(RadialSegments-3))/Levels + 3;
    
    if ( level > CutoffLevel )
    {
        BuildCylinder(
            buffer->Vertices,
            buffer->Indices,
            buffer->BoundingBox,
            
            length,
            radius,
            radiusEnd,
            radialSegments,
            
            transform );
    }
    
    // Add children
    if ( level > 1 )
    {
        core::list<SBranchChild>::Iterator it = branch->Children.begin();
        while ( it != branch->Children.end() )
        {
            SBranchChild* child = &(*it);
            
            it++;
            
            SBranch* childBranch = getBranchWithId( child->IdRef );
            
            if ( childBranch == 0 )
                continue;
            
            if ( !isValueInRange( level, child->LevelRange ) )
                continue;
            
            s32 childLevel = level + getIntFromValueRange( child->RelativeLevel, Seed++ ); // RelativeLevel is usually negative, -1 in particular.
            
            s32 numChildren = getIntFromValueRange( child->Count, Seed++ );
            
            f32 positionRange = child->Position.Max - child->Position.Min;
            
            positionRange /= (f32)numChildren;
            
            f32 orientation = getRandomFloat( Seed++, 0, 360.0f );
            
            for ( s32 i=0; i<numChildren; i++ )
            {
                f32 childLengthScale = lengthScale * getFloatFromValueRange( child->LengthScale, Seed++ );
                
                orientation += getFloatFromValueRange( child->Orientation, Seed++ );
                
                // Clamp value between 0 and 360. This is needed for gravity to work properly
                if ( orientation < 0.0f )
                    orientation += 360.0f;
                else
                if ( orientation > 360.0f )
                    orientation -= 360.0f;
                
                f32 childOrientation = orientation;
                
                f32 gravity = getFloatFromValueRange( child->GravityInfluence, Seed++ );
                
                f32 childPitch = getFloatFromValueRange( child->Pitch, Seed++ );
                
                f32 childPosition = getFloatFromValueRange( child->Position, Seed++ );
                
                f32 position;
                
                if ( child->Position.IsValue )
                    position = child->Position.Value;
                else
                    position = (child->Position.Min + positionRange * i + positionRange * getRandomFloat( Seed++, 0, 1 ));
                
                f32 childRadiusScale = (radiusScale*(1.0f-position) + radiusEndScale*position) * getFloatFromValueRange( child->RadiusScale, Seed++ );
                
                // Build transformation matrix
                core::matrix4 mat;
                
                mat.setRotationDegrees( core::vector3df(childPitch, childOrientation, 0.0f) );
                
                mat[13] = length * position;
                
                mat = transform * mat;
                
                
                if ( gravity != 0.0f )
                {
                    // Do some extra work
                    
                    core::vector3df vDown = core::vector3df( 0, -1, 0 );
                    
                    core::vector3df vBranch = core::vector3df( 0, 1, 0 );
                    mat.rotateVect(vBranch);
                    
                    core::vector3df vSide;
                    
                    if ( fabs( vBranch.Y ) >= 0.9f )
                    {
                        vSide = core::vector3df( 1, 0, 0 );
                        mat.rotateVect(vSide);
                    }
                    else
                    {
                        vSide = vBranch.crossProduct(vDown);
                        vSide.normalize();
                    }
                    
                    vDown = vSide.crossProduct(vBranch);
                    vDown.normalize();
                    
                    setMatrixVec( mat, 0, vSide );
                    setMatrixVec( mat, 2, vDown );
                    
                    f32 dot = -vBranch.Y;
                    
                    if ( gravity < 0.0f )
                        dot = -dot;
                    
                    f32 angle = acos( dot );
                    
                    angle *= gravity;
                    
                    core::matrix4 mat2;
                    mat2.setRotationRadians( core::vector3df( angle,0,0 ) );
                    
                    mat = mat * mat2;
                }
                
                // Add the branch
                appendBranch( mat, childBranch, childLengthScale, childRadiusScale, childLevel, buffer, leaves );
            }
        }
    }
    
    // Add leaves
    if ( AddLeaves )
    {
        core::list<SLeaf>::Iterator lit = branch->Leaves.begin();
        while ( lit != branch->Leaves.end() )
        {
            SLeaf* leaf = &(*lit);
            lit++;
            
            if ( !isValueInRange( level, leaf->LevelRange ) )
                continue;
            
            s32 count = getIntFromValueRange( leaf->Count, LeafSeed++ );
            
            for ( s32 i=0; i<count; i++ )
            {
            
                f32 width = getFloatFromValueRange( leaf->Width, LeafSeed++ );
                f32 height = getFloatFromValueRange( leaf->Height, LeafSeed++ );
                f32 scale = getFloatFromValueRange( leaf->Scale, LeafSeed++ );
                f32 position = getFloatFromValueRange( leaf->Position, LeafSeed++ );
                f32 roll = getFloatFromValueRange( leaf->Roll, LeafSeed++ );
                f32 anchor = getFloatFromValueRange( leaf->Anchor, LeafSeed++ );
                
                core::matrix4 mat;
                
                mat[13] = length * position;
                
                mat = transform * mat;
                
                STreeLeaf treeLeaf;
                
                treeLeaf.Position = mat.getTranslation();
                
                treeLeaf.Color.setRed( getIntFromValueRange( leaf->Red, LeafSeed++ ) );
                treeLeaf.Color.setGreen( getIntFromValueRange( leaf->Green, LeafSeed++ ) );
                treeLeaf.Color.setBlue( getIntFromValueRange( leaf->Blue, LeafSeed++ ) );
                treeLeaf.Color.setAlpha( getIntFromValueRange( leaf->Alpha, LeafSeed++ ) );
                
                treeLeaf.Size = core::dimension2df(scale*width, scale*height);
                treeLeaf.Roll = roll;
                
                if ( leaf->HasAxis )
                {
                    treeLeaf.HasAxis = true;
                    treeLeaf.Axis = leaf->Axis;
                    treeLeaf.Position += leaf->Axis * height * scale * anchor / 2.0f;
                }
                else
                {
                    treeLeaf.HasAxis = false;
                }
                
                leaves.push_back( treeLeaf );
            }
            
        }
    }
}
void BuildCylinder(   
        core::array<video::S3DVertex>& vertexArray,
        core::array<u16>& indexArray,
        core::aabbox3d<f32>& boundingBox,
        
        f32 height,
        f32 startRadius,
        f32 endRadius,
        s32 radialSegments,
        
        const core::matrix4& transform,
        
        f32 startTCoordY = 0.0f,
        f32 endTCoordY = 1.0f,
        video::SColor startColor = video::SColor(255,255,255,255),
        video::SColor endColor = video::SColor(255,255,255,255) )
{
    u16 vertexIndex = vertexArray.size();
    
    s32 radialVertices = radialSegments + 1; // We want one additional vertex to make the texture wraps correctly
    
    // Place bottom cap
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df pos;
        core::vector3df normal = dir;

        pos = dir * startRadius;
        
        // Place bottom vertex
        transform.transformVect( pos );
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = startTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            startColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint( pos );
    }
    
    // Place top cap and indices
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df normal = dir;
        core::vector3df pos = dir * endRadius;
        pos.Y = height;
        
        transform.transformVect( pos ); 
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = endTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            endColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint(pos);
        
        // Add indices
        if ( i != radialVertices-1 )
        {
            s32 i2 = (i+1)%radialVertices;
            // Place the indices
            indexArray.push_back ( vertexIndex + i );
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + i2 );
            
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + radialVertices + i2 );
            indexArray.push_back ( vertexIndex + i2 );
        }
    }
}
void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
		v3s16 dir, v3f scale, v3f posRelative_f,
		core::array<FastFace> &dest)
{
	FastFace face;
	
	// Position is at the center of the cube.
	v3f pos = p * BS;
	posRelative_f *= BS;

	v3f vertex_pos[4];
	v3s16 vertex_dirs[4];
	getNodeVertexDirs(dir, vertex_dirs);
	for(u16 i=0; i<4; i++)
	{
		vertex_pos[i] = v3f(
				BS/2*vertex_dirs[i].X,
				BS/2*vertex_dirs[i].Y,
				BS/2*vertex_dirs[i].Z
		);
	}

	for(u16 i=0; i<4; i++)
	{
		vertex_pos[i].X *= scale.X;
		vertex_pos[i].Y *= scale.Y;
		vertex_pos[i].Z *= scale.Z;
		vertex_pos[i] += pos + posRelative_f;
	}

	f32 abs_scale = 1.;
	if     (scale.X < 0.999 || scale.X > 1.001) abs_scale = scale.X;
	else if(scale.Y < 0.999 || scale.Y > 1.001) abs_scale = scale.Y;
	else if(scale.Z < 0.999 || scale.Z > 1.001) abs_scale = scale.Z;

	v3f zerovector = v3f(0,0,0);
	
	u8 alpha = tile.alpha;
	/*u8 alpha = 255;
	if(tile.id == TILE_WATER)
		alpha = WATER_ALPHA;*/

	float x0 = tile.texture.pos.X;
	float y0 = tile.texture.pos.Y;
	float w = tile.texture.size.X;
	float h = tile.texture.size.Y;

	/*video::SColor c = lightColor(alpha, li);

	face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0), c,
			core::vector2d<f32>(x0+w*abs_scale, y0+h));
	face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0), c,
			core::vector2d<f32>(x0, y0+h));
	face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0), c,
			core::vector2d<f32>(x0, y0));
	face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0), c,
			core::vector2d<f32>(x0+w*abs_scale, y0));*/

	face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0),
			lightColor(alpha, li0),
			core::vector2d<f32>(x0+w*abs_scale, y0+h));
	face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0),
			lightColor(alpha, li1),
			core::vector2d<f32>(x0, y0+h));
	face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0),
			lightColor(alpha, li2),
			core::vector2d<f32>(x0, y0));
	face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0),
			lightColor(alpha, li3),
			core::vector2d<f32>(x0+w*abs_scale, y0));

	face.tile = tile;
	//DEBUG
	//f->tile = TILE_STONE;
	
	dest.push_back(face);
}
	void CSMFile::load(BinaryFileReader* pReader)
	{
		clear();

		header.load(pReader);

		//groups
		{
			const s32 count = pReader->readLong();
#ifdef _IRR_DEBUG_CSM_LOADER_
			os::Printer::log("CSM Version", core::stringc(header.getVersion()).c_str());
			os::Printer::log("Loading groups. Count", core::stringc(count));
#endif

			groups.reallocate(count);
			for (s32 i = 0; i < count; i++)
			{
				Group* grp = new Group();
				grp->load(pReader);
				groups.push_back(grp);
			}
		}
		const bool bHasVGroups = (header.getVersion() == Header::VERSION_4_1);

		if (bHasVGroups)
		{
			//visgroups
			const s32 count = pReader->readLong();
#ifdef _IRR_DEBUG_CSM_LOADER_
			os::Printer::log("Loading visgroups. Count", core::stringc(count));
#endif

			visgroups.reallocate(count);
			for (s32 i = 0; i < count; i++)
			{
				VisGroup* grp = new VisGroup();
				grp->load(pReader);
				visgroups.push_back(grp);
			}
		}

		//lightmaps
		{
			const s32 count = pReader->readLong();
#ifdef _IRR_DEBUG_CSM_LOADER_
			os::Printer::log("Loading lightmaps. Count", core::stringc(count));
#endif

			lightmaps.reallocate(count);
			for(s32 i = 0; i < count; i++)
			{
				LightMap* lm = new LightMap();
				lm->load(pReader);
				lightmaps.push_back(lm);
			}
		}

		//meshes
		{
			const s32 count = pReader->readLong();
#ifdef _IRR_DEBUG_CSM_LOADER_
			os::Printer::log("Loading meshes. Count", core::stringc(count));
#endif

			meshes.reallocate(count);
			for(s32 i = 0; i < count; i++)
			{
				Mesh* mesh = new Mesh();
				mesh->load(pReader,bHasVGroups);
				meshes.push_back(mesh);
			}
		}

		//entities
		{
			const s32 count = pReader->readLong();
#ifdef _IRR_DEBUG_CSM_LOADER_
			os::Printer::log("Loading entitites. Count", core::stringc(count));
#endif

			entities.reallocate(count);
			for(s32 i = 0; i < count; i++)
			{
				Entity* ent = new Entity();
				ent->load(pReader);
				entities.push_back(ent);
			}
		}

		//camera data
#ifdef _IRR_DEBUG_CSM_LOADER_
		os::Printer::log("Loading camera data.");
#endif
		cameraData.load(pReader);
	}
Beispiel #21
0
	void CSMFile::load(BinaryFileReader* pReader)
	{
		clear();

		header.load(pReader);

		//groups
		{
			s32 count = pReader->readLong();

			for (s32 i = 0; i < count; i++)
			{
				Group* grp = new Group();
				grp->load(pReader);
				groups.push_back(grp);
			}
		}
		bool bHasVGroups = (header.getVersion() == Header::VERSION_4_1);

		if (bHasVGroups)
		{
			//visgroups
			s32 count = pReader->readLong();

			for (s32 i = 0; i < count; i++)
			{
				VisGroup* grp = new VisGroup();
				grp->load(pReader);
				visgroups.push_back(grp);
			}
		}

		//lightmaps
		{
			s32 count = pReader->readLong();

			for(s32 i = 0; i < count; i++)
			{
				LightMap* grp = new LightMap();
				grp->load(pReader);
				lightmaps.push_back(grp);
			}
		}

		//meshes
		{
			s32 count = pReader->readLong();

			for(s32 i = 0; i < count; i++)
			{
				Mesh* grp = new Mesh();
				grp->load(pReader,bHasVGroups);
				meshes.push_back(grp);
			}
		}

		//entities
		{
			s32 count = pReader->readLong();

			for(s32 i = 0; i < count; i++)
			{
				Entity* grp = new Entity();
				grp->load(pReader);
				entities.push_back(grp);
			}
		}

		//camera data
		cameraData.load(pReader);


	}
Beispiel #22
0
u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols,
		core::array<ChatFormattedLine>& destination) const
{
	u32 num_added = 0;
	core::array<ChatFormattedFragment> next_frags;
	ChatFormattedLine next_line;
	ChatFormattedFragment temp_frag;
	u32 out_column = 0;
	u32 in_pos = 0;
	u32 hanging_indentation = 0;

	// Format the sender name and produce fragments
	if (!line.name.empty())
	{
		temp_frag.text = L"<";
		temp_frag.column = 0;
		//temp_frag.bold = 0;
		next_frags.push_back(temp_frag);
		temp_frag.text = line.name;
		temp_frag.column = 0;
		//temp_frag.bold = 1;
		next_frags.push_back(temp_frag);
		temp_frag.text = L"> ";
		temp_frag.column = 0;
		//temp_frag.bold = 0;
		next_frags.push_back(temp_frag);
	}

	// Choose an indentation level
	if (line.name.empty())
	{
		// Server messages
		hanging_indentation = 0;
	}
	else if (line.name.size() + 3 <= cols/2)
	{
		// Names shorter than about half the console width
		hanging_indentation = line.name.size() + 3;
	}
	else
	{
		// Very long names
		hanging_indentation = 2;
	}

	next_line.first = true;
	bool text_processing = false;

	// Produce fragments and layout them into lines
	while (!next_frags.empty() || in_pos < line.text.size())
	{
		// Layout fragments into lines
		while (!next_frags.empty())
		{
			ChatFormattedFragment& frag = next_frags[0];
			if (frag.text.size() <= cols - out_column)
			{
				// Fragment fits into current line
				frag.column = out_column;
				next_line.fragments.push_back(frag);
				out_column += frag.text.size();
				next_frags.erase(0, 1);
			}
			else
			{
				// Fragment does not fit into current line
				// So split it up
				temp_frag.text = frag.text.substr(0, cols - out_column);
				temp_frag.column = out_column;
				//temp_frag.bold = frag.bold;
				next_line.fragments.push_back(temp_frag);
				frag.text = frag.text.substr(cols - out_column);
				out_column = cols;
			}
			if (out_column == cols || text_processing)
			{
				// End the current line
				destination.push_back(next_line);
				num_added++;
				next_line.fragments.clear();
				next_line.first = false;

				out_column = text_processing ? hanging_indentation : 0;
			}
		}

		// Produce fragment
		if (in_pos < line.text.size())
		{
			u32 remaining_in_input = line.text.size() - in_pos;
			u32 remaining_in_output = cols - out_column;

			// Determine a fragment length <= the minimum of
			// remaining_in_{in,out}put. Try to end the fragment
			// on a word boundary.
			u32 frag_length = 1, space_pos = 0;
			while (frag_length < remaining_in_input &&
					frag_length < remaining_in_output)
			{
				if (isspace(line.text[in_pos + frag_length]))
					space_pos = frag_length;
				++frag_length;
			}
			if (space_pos != 0 && frag_length < remaining_in_input)
				frag_length = space_pos + 1;

			temp_frag.text = line.text.substr(in_pos, frag_length);
			temp_frag.column = 0;
			//temp_frag.bold = 0;
			next_frags.push_back(temp_frag);
			in_pos += frag_length;
			text_processing = true;
		}
	}

	// End the last line
	if (num_added == 0 || !next_line.fragments.empty())
	{
		destination.push_back(next_line);
		num_added++;
	}

	return num_added;
}
Beispiel #23
0
void TextureSource::buildMainAtlas(class IGameDef *gamedef) 
{
	assert(gamedef->tsrc() == this);
	INodeDefManager *ndef = gamedef->ndef();

	infostream<<"TextureSource::buildMainAtlas()"<<std::endl;

	//return; // Disable (for testing)
	
	video::IVideoDriver* driver = m_device->getVideoDriver();
	assert(driver);

	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	// Create an image of the right size
	core::dimension2d<u32> atlas_dim(1024,1024);
	video::IImage *atlas_img =
			driver->createImage(video::ECF_A8R8G8B8, atlas_dim);
	//assert(atlas_img);
	if(atlas_img == NULL)
	{
		errorstream<<"TextureSource::buildMainAtlas(): Failed to create atlas "
				"image; not building texture atlas."<<std::endl;
		return;
	}

	/*
		Grab list of stuff to include in the texture atlas from the
		main content features
	*/

	core::map<std::string, bool> sourcelist;

	for(u16 j=0; j<MAX_CONTENT+1; j++)
	{
		if(j == CONTENT_IGNORE || j == CONTENT_AIR)
			continue;
		const ContentFeatures &f = ndef->get(j);
		for(u32 i=0; i<6; i++)
		{
			std::string name = f.tname_tiles[i];
			sourcelist[name] = true;
		}
	}
	
	infostream<<"Creating texture atlas out of textures: ";
	for(core::map<std::string, bool>::Iterator
			i = sourcelist.getIterator();
			i.atEnd() == false; i++)
	{
		std::string name = i.getNode()->getKey();
		infostream<<"\""<<name<<"\" ";
	}
	infostream<<std::endl;

	// Padding to disallow texture bleeding
	s32 padding = 16;

	s32 column_width = 256;
	s32 column_padding = 16;

	/*
		First pass: generate almost everything
	*/
	core::position2d<s32> pos_in_atlas(0,0);
	
	pos_in_atlas.Y = padding;

	for(core::map<std::string, bool>::Iterator
			i = sourcelist.getIterator();
			i.atEnd() == false; i++)
	{
		std::string name = i.getNode()->getKey();

		// Generate image by name
		video::IImage *img2 = generate_image_from_scratch(name, m_device,
				&m_sourcecache);
		if(img2 == NULL)
		{
			errorstream<<"TextureSource::buildMainAtlas(): "
					<<"Couldn't generate image \""<<name<<"\""<<std::endl;
			continue;
		}

		core::dimension2d<u32> dim = img2->getDimension();

		// Don't add to atlas if image is large
		core::dimension2d<u32> max_size_in_atlas(32,32);
		if(dim.Width > max_size_in_atlas.Width
		|| dim.Height > max_size_in_atlas.Height)
		{
			infostream<<"TextureSource::buildMainAtlas(): Not adding "
					<<"\""<<name<<"\" because image is large"<<std::endl;
			continue;
		}

		// Wrap columns and stop making atlas if atlas is full
		if(pos_in_atlas.Y + dim.Height > atlas_dim.Height)
		{
			if(pos_in_atlas.X > (s32)atlas_dim.Width - 256 - padding){
				errorstream<<"TextureSource::buildMainAtlas(): "
						<<"Atlas is full, not adding more textures."
						<<std::endl;
				break;
			}
			pos_in_atlas.Y = padding;
			pos_in_atlas.X += column_width + column_padding;
		}
		
		/*infostream<<"TextureSource::buildMainAtlas(): Adding \""<<name
				<<"\" to texture atlas"<<std::endl;*/

		// Tile it a few times in the X direction
		u16 xwise_tiling = column_width / dim.Width;
		if(xwise_tiling > 16) // Limit to 16 (more gives no benefit)
			xwise_tiling = 16;
		for(u32 j=0; j<xwise_tiling; j++)
		{
			// Copy the copy to the atlas
			/*img2->copyToWithAlpha(atlas_img,
					pos_in_atlas + v2s32(j*dim.Width,0),
					core::rect<s32>(v2s32(0,0), dim),
					video::SColor(255,255,255,255),
					NULL);*/
			img2->copyTo(atlas_img,
					pos_in_atlas + v2s32(j*dim.Width,0),
					core::rect<s32>(v2s32(0,0), dim),
					NULL);
		}

		// Copy the borders a few times to disallow texture bleeding
		for(u32 side=0; side<2; side++) // top and bottom
		for(s32 y0=0; y0<padding; y0++)
		for(s32 x0=0; x0<(s32)xwise_tiling*(s32)dim.Width; x0++)
		{
			s32 dst_y;
			s32 src_y;
			if(side==0)
			{
				dst_y = y0 + pos_in_atlas.Y + dim.Height;
				src_y = pos_in_atlas.Y + dim.Height - 1;
			}
			else
			{
				dst_y = -y0 + pos_in_atlas.Y-1;
				src_y = pos_in_atlas.Y;
			}
			s32 x = x0 + pos_in_atlas.X;
			video::SColor c = atlas_img->getPixel(x, src_y);
			atlas_img->setPixel(x,dst_y,c);
		}

		img2->drop();

		/*
			Add texture to caches
		*/
		
		bool reuse_old_id = false;
		u32 id = m_atlaspointer_cache.size();
		// Check old id without fetching a texture
		core::map<std::string, u32>::Node *n;
		n = m_name_to_id.find(name);
		// If it exists, we will replace the old definition
		if(n){
			id = n->getValue();
			reuse_old_id = true;
			/*infostream<<"TextureSource::buildMainAtlas(): "
					<<"Replacing old AtlasPointer"<<std::endl;*/
		}

		// Create AtlasPointer
		AtlasPointer ap(id);
		ap.atlas = NULL; // Set on the second pass
		ap.pos = v2f((float)pos_in_atlas.X/(float)atlas_dim.Width,
				(float)pos_in_atlas.Y/(float)atlas_dim.Height);
		ap.size = v2f((float)dim.Width/(float)atlas_dim.Width,
				(float)dim.Width/(float)atlas_dim.Height);
		ap.tiled = xwise_tiling;

		// Create SourceAtlasPointer and add to containers
		SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
		if(reuse_old_id)
			m_atlaspointer_cache[id] = nap;
		else
			m_atlaspointer_cache.push_back(nap);
		m_name_to_id[name] = id;
			
		// Increment position
		pos_in_atlas.Y += dim.Height + padding * 2;
	}

	/*
		Make texture
	*/
	video::ITexture *t = driver->addTexture("__main_atlas__", atlas_img);
	assert(t);

	/*
		Second pass: set texture pointer in generated AtlasPointers
	*/
	for(core::map<std::string, bool>::Iterator
			i = sourcelist.getIterator();
			i.atEnd() == false; i++)
	{
		std::string name = i.getNode()->getKey();
		if(m_name_to_id.find(name) == NULL)
			continue;
		u32 id = m_name_to_id[name];
		//infostream<<"id of name "<<name<<" is "<<id<<std::endl;
		m_atlaspointer_cache[id].a.atlas = t;
	}

	/*
		Write image to file so that it can be inspected
	*/
	/*std::string atlaspath = porting::path_user
			+ DIR_DELIM + "generated_texture_atlas.png";
	infostream<<"Removing and writing texture atlas for inspection to "
			<<atlaspath<<std::endl;
	fs::RecursiveDelete(atlaspath);
	driver->writeImageToFile(atlas_img, atlaspath.c_str());*/
}