Beispiel #1
0
std::string TextureSource::getTextureName(u32 id)
{
	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	if(id >= m_atlaspointer_cache.size())
	{
		errorstream<<"TextureSource::getTextureName(): id="<<id
				<<" >= m_atlaspointer_cache.size()="
				<<m_atlaspointer_cache.size()<<std::endl;
		return "";
	}
	
	return m_atlaspointer_cache[id].name;
}
	void Mesh::clear()
	{
		flags = 0;
		groupId = 0;
		visgroupId = 0;
		props = "";
		color.clear();
		position.set(0,0,0);

		for(u32 s = 0; s < surfaces.size(); s++)
		{
			delete surfaces[s];
		}
		surfaces.clear();
	}
Beispiel #3
0
void CSoftwareRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
	if (Texture != texture)
	{
		if (Texture[0])
			Texture[0]->drop();

		bool textureDetected = false;

		for (u32 i = 0; i < texture.size(); ++i)
		{
			if (texture[i] && texture[i]->getDriverType() == EDT_SOFTWARE)
			{
				Texture[0] = texture[i];
				Texture[0]->grab();
				textureDetected = true;

				break;
			}
		}

		if (!textureDetected)
			Texture[0] = 0;
	}
}
Beispiel #4
0
	void Surface::clear()
	{
		flags = 0;
		lightMapId = 0;
		textureName = "";
		uvOffset.set(0.0f,0.0f);
		uvScale.set(0.0f,0.0f);
		uvRotation = 0.0f;
		triangles.clear();
		lines.clear();

		for(u32 v = 0; v < vertices.size(); v++)
			delete vertices[v];

		vertices.clear();
	}
Beispiel #5
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 #6
0
AtlasPointer TextureSource::getTexture(u32 id)
{
	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	if(id >= m_atlaspointer_cache.size())
		return AtlasPointer(0, NULL);
	
	return m_atlaspointer_cache[id].a;
}
Beispiel #7
0
//! Adds the slots in the array to the usable slots
void CGUIIcon::addUsableSlotArray(const core::array<IGUIElement*>& slotArray)
{
    s32 arraySize = slotArray.size();
    for(s32 i = 0; i < arraySize; i++)
    {
        UsableSlots->push_back(slotArray[i]);
    }

}
Beispiel #8
0
	virtual void OnRenderPassPostRender(scene::E_SCENE_NODE_RENDER_PASS renderPass)
	{
		// I only want solid nodes to be lit, so after the solid pass, turn all lights off.
		if(scene::ESNRP_SOLID == renderPass)
		{
			for(u32 i = 0; i < SceneLightList->size(); ++i)
				(*SceneLightList)[i]->setVisible(false);
		}
	}
Beispiel #9
0
	// Called after the last scene node is rendered.
	virtual void OnPostRender()
	{
		// Since light management might be switched off in the event handler, we'll turn all
		// lights on to ensure that they are in a consistent state. You wouldn't normally have
		// to do this when using a light manager, since you'd continue to do light management
		// yourself.
		for(u32 i = 0; i < SceneLightList->size(); i++)
			(*SceneLightList)[i]->setVisible(true);
	}
Beispiel #10
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);
	}
}
Beispiel #11
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 #12
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--;
    }

}
Beispiel #13
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 #15
0
void CFontTextTag::create( IExtendedText* text, const core::stringw& tag, const core::array<core::stringw>& params )
{
    if ( params.size() == 0 )
    {
        text->setCurrentFont( text->getDefaultFont() );
    }
    else
    {
        core::map<core::stringw,IGUIFont*>::Node* node = FontMap.find( params[0] );
        
        if ( node != NULL )
        {
            text->setCurrentFont( node->getValue() );
        }
    }
}
void CSceneNodeAnimatorTexture::setFramesDirectionSet(
	u32 direction_idx, const core::array<SAnimationFrame> &frames)
{
	if (direction_idx >= m_DirectionSets.size())
		for (u32 d = m_DirectionSets.size(); d <= direction_idx; d++)
			m_DirectionSets.push_back(core::array<SAnimationFrame>());
	u32 i=0;
	for (i=0; i < m_DirectionSets[direction_idx].size(); ++i)
        SAFE_DROP(m_DirectionSets[direction_idx][i].Texture);
	m_DirectionSets[direction_idx].set_used(0);
	for (i = 0; i < frames.size(); ++i)
    {
        m_DirectionSets[direction_idx].push_back(frames[i]);
		SAFE_GRAB(frames[i].Texture);
    }
}
//! constructor
CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array<video::ITexture*>& textures,
                                                     s32 timePerFrame, bool loop, u32 now)
	: Loop(loop), StartTime(now), TimePerFrame(timePerFrame)
{
	#ifdef _DEBUG
	setDebugName("CSceneNodeAnimatorTexture");
	#endif

	for (u32 i=0; i<textures.size(); ++i)
	{
		if (textures[i])
			textures[i]->grab();

		Textures.push_back(textures[i]);
	}

	EndTime = now + (timePerFrame * Textures.size());
}
Beispiel #18
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);
	}
}
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 #20
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--;
    }

}
Beispiel #21
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 #22
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 #23
0
void TextureSource::rebuildImagesAndTextures()
{
	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	/*// Oh well... just clear everything, they'll load sometime.
	m_atlaspointer_cache.clear();
	m_name_to_id.clear();*/

	video::IVideoDriver* driver = m_device->getVideoDriver();
	
	// Remove source images from textures to disable inheriting textures
	// from existing textures
	/*for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
		SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
		sap->atlas_img->drop();
		sap->atlas_img = NULL;
	}*/
	
	// Recreate textures
	for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
		SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
		video::IImage *img =
			generate_image_from_scratch(sap->name, m_device, &m_sourcecache);
		// Create texture from resulting image
		video::ITexture *t = NULL;
		if(img)
			t = driver->addTexture(sap->name.c_str(), img);
		
		// Replace texture
		sap->a.atlas = t;
		sap->a.pos = v2f(0,0);
		sap->a.size = v2f(1,1);
		sap->a.tiled = 0;
		sap->atlas_img = img;
		sap->intpos = v2s32(0,0);
		sap->intsize = img->getDimension();
	}
}
void HWSkinningCallback::OnSetConstants(video::IMaterialRendererServices *services, s32 userData)
{
/*    static const float colors[] = {
        1.0, 0.0, 0.0, 1.0,
        0.0, 1.0, 0.0, 1.0,
        0.0, 0.0, 1.0, 1.0,
        1.0, 1.0, 0.0, 1.0,
        0.0, 1.0, 1.0, 1.0,
        1.0, 0.0, 1.0, 1.0,
        0.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
    };
    static const int nb_colors = 8;
    //int index = m_used_material

    int index = 4;
    //int index = *reinterpret_cast<const int*>(&m_used_material->MaterialTypeParam);
    //printf("OnSetConstants: index: %d\n", index);
    //index = 4 * (index % nb_colors);

    services->setPixelShaderConstant("debug_color", &colors[index], 4);
*/
    //! Sets a constant for the pixel shader based on a name.
 /** This can be used if you used a high level shader language like GLSL
 or HLSL to create a shader. See setVertexShaderConstant() for an
 example on how to use this.
 \param name Name of the variable
 \param floats Pointer to array of floats
 \param count Amount of floats in array.
 \return True if successful. */
 /*virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count) = 0;*/

    // TODO: cleanup
    // - joints
    scene::ISkinnedMesh* mesh = (scene::ISkinnedMesh*)m_node->getMesh();
    f32 joints_data[55 * 16];
    int copyIncrement = 0;

    const core::array<scene::ISkinnedMesh::SJoint*> joints = mesh->getAllJoints();
    for(u32 i = 0;i < joints.size();++i)
    {
        core::matrix4 joint_vertex_pull(core::matrix4::EM4CONST_NOTHING);
        joint_vertex_pull.setbyproduct(joints[i]->GlobalAnimatedMatrix, joints[i]->GlobalInversedMatrix);

        f32* pointer = joints_data + copyIncrement;
        for(int i = 0;i < 16;++i)
            *pointer++ = joint_vertex_pull[i];

        copyIncrement += 16;
    }

    services->setVertexShaderConstant("JointTransform", joints_data, mesh->getAllJoints().size() * 16);

    // - mWorldViewProj
    // set clip matrix at register 4
/*    core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
    worldViewProj *= driver->getTransform(video::ETS_VIEW);
    worldViewProj *= driver->getTransform(video::ETS_WORLD);
    services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);
*/    // for high level shading languages, this would be another solution:
    //services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);

    // -
}
Beispiel #25
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 CGUISpriteBank::draw2DSpriteBatch(	const core::array<u32>& indices,
										const core::array<core::position2di>& pos,
										const core::rect<s32>* clip,
										const video::SColor& color,
										u32 starttime, u32 currenttime,
										bool loop, bool center)
{
	const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());

	if (!getTextureCount())
		return;
	core::array<SDrawBatch> drawBatches(getTextureCount());
	for (u32 i=0; i < Textures.size(); ++i)
	{
		drawBatches.push_back(SDrawBatch());
		drawBatches[i].positions.reallocate(drawCount);
		drawBatches[i].sourceRects.reallocate(drawCount);
	}

	for (u32 i = 0; i < drawCount; ++i)
	{
		const u32 index = indices[i];

		if (index >= Sprites.size() || Sprites[index].Frames.empty() )
			continue;

		// work out frame number
		u32 frame = 0;
		if (Sprites[index].frameTime)
		{
			u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
			if (loop)
				frame = f % Sprites[index].Frames.size();
			else
				frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
		}

		const u32 texNum = Sprites[index].Frames[frame].textureNumber;
		SDrawBatch& currentBatch = drawBatches[texNum];

		const u32 rn = Sprites[index].Frames[frame].rectNumber;
		if (rn >= Rectangles.size())
			return;

		const core::rect<s32>& r = Rectangles[rn];

		if (center)
		{
			core::position2di p = pos[i];
			p -= r.getSize() / 2;

			currentBatch.positions.push_back(p);
			currentBatch.sourceRects.push_back(r);
		}
		else
		{
			currentBatch.positions.push_back(pos[i]);
			currentBatch.sourceRects.push_back(r);
		}
	}

	for(u32 i = 0;i < drawBatches.size();i++)
	{
		if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
			Driver->draw2DImageBatch(getTexture(i), drawBatches[i].positions,
				drawBatches[i].sourceRects, clip, color, true);
	}
}
Beispiel #30
0
	HeightMap(u16 _w, u16 _h) : Width(_w), Height(_h), s(0.f), data(0)
	{
		s = sqrtf((f32)(Width * Width + Height * Height));
		data.set_used(Width * Height);
	}