Exemplo n.º 1
0
	int DBTools::insertPoint(INOUT Point3D& point)
	{
		Point3D pTemp = point;
		int pointid = getIdByPoint(pTemp);
		if( pointid == 0)
		{
			std::stringstream ss_x;
			std::stringstream ss_y;
			std::stringstream ss_z; 
			ss_x.precision(9);
		    ss_y.precision(9);
		    ss_z.precision(9);
			ss_x<<floatToInt(pTemp.getLatitude());
			ss_y<<floatToInt(pTemp.getLongitude());
			
			if(pTemp.getAltitude()>0)
			    ss_z<<floatToInt(pTemp.getAltitude());
			else
				ss_z<<0;

			std::string sql="insert into point(x,y,z) values("+ss_x.str()+"," + ss_y.str() + " ," + ss_z.str()+ ");";
			mysql_query(&myCont,sql.c_str());
			 //std::cout<<ss_x.str()<<std::endl;
			pointid = mysql_insert_id(&myCont);//get last inserted id.
			pTemp.setId(pointid);
			point = pTemp;
		}
		point.setId(pointid);
		return pointid;
	}
Exemplo n.º 2
0
	int DBTools::getIdByPoint(IN Point3D& point)
	{
		int pointid = 0;
		Point3D pTemp = point;

		std::stringstream ss_x;
		std::stringstream ss_y;
		std::stringstream ss_z;
		ss_x.precision(9);
		ss_y.precision(9);
		ss_z.precision(9);
		ss_x<<floatToInt(pTemp.getLatitude());
		ss_y<<floatToInt(pTemp.getLongitude());
		if(pTemp.getAltitude()>0)
			ss_z<<floatToInt(pTemp.getAltitude());
		else
			ss_z<<0;
		std::string sql="select point_id from point where x="+ss_x.str()+" and y="+ss_y.str()+" and z="+ss_z.str()+";";
		int res=mysql_query(&myCont,sql.c_str());
		//std::cout<<ss_x.str()<<std::endl;
		if(!res)
		{
			MYSQL_RES *result = mysql_store_result(&myCont);
			if(mysql_num_rows(result))
			{
				MYSQL_ROW sql_row;
				sql_row=mysql_fetch_row(result);
				pointid = atoi(sql_row[0]);
			}
			mysql_free_result(result);
		}
		return pointid;
	}
Exemplo n.º 3
0
/**
  * @brief EXTI line detection callbacks
  * @param GPIO_Pin: Specifies the pins connected EXTI line
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == GPIO_PIN_13)
  {
	    int32_t d1, d2, d3, d4, d5, d6, d7, d8;
	    int32_t data[3];
	    int32_t gdata[6];

	    if(BSP_HUM_TEMP_isInitialized()) {
	        BSP_HUM_TEMP_GetHumidity((float *)&HUMIDITY_Value);
	        BSP_HUM_TEMP_GetTemperature((float *)&TEMPERATURE_Value);
	        floatToInt(HUMIDITY_Value, &d1, &d2, 2);
	        float tempF = celsius2fahrenheit(TEMPERATURE_Value);
	        floatToInt(tempF, &d3, &d4, 2);
            sprintf(dataOut, "HUM: %d.%02d rH     TEMP: %d.%02d (f)\n\r", (int)d1, (int)d2, (int)d3, (int)d4);
	        printf(dataOut);
	    }

	    if(BSP_PRESSURE_isInitialized())
	    {
	        BSP_PRESSURE_GetPressure((float *)&PRESSURE_Value);
	        BSP_PRESSURE_GetTemperature((float *)&TEMPERATURE2_Value);
	        floatToInt(PRESSURE_Value, &d5, &d6, 2);
	        float tempF2 = celsius2fahrenheit(TEMPERATURE2_Value);
	        floatToInt(tempF2, &d7, &d8, 2);
            sprintf(dataOut, "PRESS: %d.%02d hPa     TEMP: %d.%02d (f)\n\r", (int)d5, (int)d6, (int)d7, (int)d8);
	        printf(dataOut);
	    }

	    if(BSP_MAGNETO_isInitialized())
	    {
	        BSP_MAGNETO_M_GetAxesRaw((AxesRaw_TypeDef *)&MAG_Value);
            data[0] = MAG_Value.AXIS_X;
            data[1] = MAG_Value.AXIS_Y;
            data[2] = MAG_Value.AXIS_Z;

            sprintf(dataOut, "MAG_X: %d, MAG_Y: %d, MAG_Z: %d\n\r", (int)data[0], (int)data[1], (int)data[2]);
	        printf(dataOut);
	    }


	    if(BSP_IMU_6AXES_isInitialized()) {
	        BSP_IMU_6AXES_X_GetAxesRaw((AxesRaw_TypeDef *)&ACC_Value);
	        BSP_IMU_6AXES_G_GetAxesRaw((AxesRaw_TypeDef *)&GYR_Value);
            gdata[0] = ACC_Value.AXIS_X;
            gdata[1] = ACC_Value.AXIS_Y;
            gdata[2] = ACC_Value.AXIS_Z;
            gdata[3] = GYR_Value.AXIS_X;
            gdata[4] = GYR_Value.AXIS_Y;
            gdata[5] = GYR_Value.AXIS_Z;

            sprintf(dataOut, "ACC_X: %d, ACC_Y: %d, ACC_Z: %d\n\r", (int)gdata[0], (int)gdata[1], (int)gdata[2]);
	        printf(dataOut);
            sprintf(dataOut, "GYR_X: %d, GYR_Y: %d, GYR_Z: %d\n\r", (int)gdata[3], (int)gdata[4], (int)gdata[5]);
	        printf(dataOut);

	    }
  }
}
void TestVoxelAlgorithms::testVoxelLineIterator(INodeDefManager *ndef)
{
	// Test some lines
	// Do not test lines that start or end on the border of
	// two voxels as rounding errors can make the test fail!
	std::vector<core::line3d<f32> > lines;
	for (f32 x = -9.1; x < 9; x += 3.124) {
	for (f32 y = -9.2; y < 9; y += 3.123) {
	for (f32 z = -9.3; z < 9; z += 3.122) {
		lines.push_back(core::line3d<f32>(-x, -y, -z, x, y, z));
	}
	}
	}
	lines.push_back(core::line3d<f32>(0, 0, 0, 0, 0, 0));
	// Test every line
	std::vector<core::line3d<f32> >::iterator it = lines.begin();
	for (; it < lines.end(); it++) {
		core::line3d<f32> l = *it;

		// Initialize test
		voxalgo::VoxelLineIterator iterator(l.start, l.getVector());

		//Test the first voxel
		v3s16 start_voxel = floatToInt(l.start, 1);
		UASSERT(iterator.m_current_node_pos == start_voxel);

		// Values for testing
		v3s16 end_voxel = floatToInt(l.end, 1);
		v3s16 voxel_vector = end_voxel - start_voxel;
		int nodecount = abs(voxel_vector.X) + abs(voxel_vector.Y)
			+ abs(voxel_vector.Z);
		int actual_nodecount = 0;
		v3s16 old_voxel = iterator.m_current_node_pos;

		while (iterator.hasNext()) {
			iterator.next();
			actual_nodecount++;
			v3s16 new_voxel = iterator.m_current_node_pos;
			// This must be a neighbor of the old voxel
			UASSERTEQ(f32, (new_voxel - old_voxel).getLengthSQ(), 1);
			// The line must intersect with the voxel
			v3f voxel_center = intToFloat(iterator.m_current_node_pos, 1);
			aabb3f box(voxel_center - v3f(0.5, 0.5, 0.5),
				voxel_center + v3f(0.5, 0.5, 0.5));
			UASSERT(box.intersectsWithLine(l));
			// Update old voxel
			old_voxel = new_voxel;
		}

		// Test last node
		UASSERT(iterator.m_current_node_pos == end_voxel);
		// Test node count
		UASSERTEQ(int, actual_nodecount, nodecount);
	}
}
Exemplo n.º 5
0
v3s16 LocalPlayer::getFootstepNodePos()
{
	if (in_liquid_stable)
		// Emit swimming sound if the player is in liquid
		return floatToInt(getPosition(), BS);
	if (touching_ground)
		// BS * 0.05 below the player's feet ensures a 1/16th height
		// nodebox is detected instead of the node below it.
		return floatToInt(getPosition() - v3f(0, BS * 0.05f, 0), BS);
	// A larger distance below is necessary for a footstep sound
	// when landing after a jump or fall. BS * 0.5 ensures water
	// sounds when swimming in 1 node deep water.
	return floatToInt(getPosition() - v3f(0, BS * 0.5f, 0), BS);
}
Exemplo n.º 6
0
float LocalPlayer::getSlipFactor(Environment *env, const v3f &speedH)
{

	if (!touching_ground)
		return 1.0f;

	float slip_factor = 1.0f;
	// Slip on slippery nodes
	const INodeDefManager *nodemgr = env->getGameDef()->ndef();
	Map *map = &env->getMap();
	const ContentFeatures &f = nodemgr->get(map->getNodeNoEx(
			floatToInt(getPosition() - v3f(0, 0.05f * BS, 0), BS)));
	int slippery = 0;
	if (f.walkable) {
		slippery = itemgroup_get(f.groups, "slippery");
	} else if (is_slipping) {
		// slipping over an edge? Check surroundings for slippery nodes
		slippery = 2 << 16; // guard value, bigger than all realistic ones
		for (int z = 0; z <= 1; z++) {
			for (int x = 0; x <= 1; x++) {
				// this should cover all nodes surrounding player position
				v3f offset((x - 0.5f) * BS, 0.05f * BS, (z - 0.5f) * BS);
				const ContentFeatures &f2 = nodemgr->get(map->getNodeNoEx(
						floatToInt(getPosition() - offset, BS)));
				if (f2.walkable) {
					// find least slippery node we might be standing on
					int s = itemgroup_get(f2.groups, "slippery");
					if (s < slippery)
						slippery = s;
				}
			}
		}
		// without any hits, ignore slippery
		if (slippery >= (2 << 16))
			slippery = 0;
	}
	if (slippery >= 1) {
		if (speedH == v3f(0.0f)) {
			slippery = slippery * 2;
		}
		slip_factor = core::clamp(1.0f / (slippery + 1), 0.001f, 1.0f);
		is_slipping = true;
	} else {
		// remember this to avoid checking the edge case above too often
		is_slipping = false;
	}
	return slip_factor;
}
Exemplo n.º 7
0
void ClientMap::renderPostFx()
{
	INodeDefManager *nodemgr = m_gamedef->ndef();

	// Sadly ISceneManager has no "post effects" render pass, in that case we
	// could just register for that and handle it in renderMap().

	m_camera_mutex.Lock();
	v3f camera_position = m_camera_position;
	m_camera_mutex.Unlock();

	MapNode n = getNodeNoEx(floatToInt(camera_position, BS));

	// - If the player is in a solid node, make everything black.
	// - If the player is in liquid, draw a semi-transparent overlay.
	const ContentFeatures& features = nodemgr->get(n);
	video::SColor post_effect_color = features.post_effect_color;
	if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")))
	{
		post_effect_color = video::SColor(255, 0, 0, 0);
	}
	if (post_effect_color.getAlpha() != 0)
	{
		// Draw a full-screen rectangle
		video::IVideoDriver* driver = SceneManager->getVideoDriver();
		v2u32 ss = driver->getScreenSize();
		core::rect<s32> rect(0,0, ss.X, ss.Y);
		driver->draw2DRectangle(post_effect_color, rect);
	}
}
Exemplo n.º 8
0
void LimiterMono<N>::process(float* input, int16_t* output, int numFrames) {

    for (int n = 0; n < numFrames; n++) {

        // peak detect and convert to log2 domain
        int32_t peak = peaklog2(&input[n]);

        // compute limiter attenuation
        int32_t attn = MAX(_threshold - peak, 0);

        // apply envelope
        attn = envelope(attn);

        // convert from log2 domain
        attn = fixexp2(attn);

        // lowpass filter
        attn = _filter.process(attn);
        float gain = attn * _outGain;

        // delay audio
        float x = input[n];
        _delay.process(x);

        // apply gain
        x *= gain;

        // apply dither
        x += dither();

        // store 16-bit output
        output[n] = (int16_t)floatToInt(x);
    }
}
Exemplo n.º 9
0
	SmokePuffCSO(scene::ISceneManager *smgr,
			ClientEnvironment *env, const v3f &pos, const v2f &size)
	{
		infostream<<"SmokePuffCSO: constructing"<<std::endl;
		m_spritenode = smgr->addBillboardSceneNode(
				NULL, v2f(1,1), pos, -1);
		m_spritenode->setMaterialTexture(0,
				env->getGameDef()->tsrc()->getTextureForMesh("smoke_puff.png"));
		m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
		m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
		//m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
		m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
		m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
		m_spritenode->setColor(video::SColor(255,0,0,0));
		m_spritenode->setVisible(true);
		m_spritenode->setSize(size);
		/* Update brightness */
		u8 light;
		bool pos_ok;
		MapNode n = env->getMap().getNodeNoEx(floatToInt(pos, BS), &pos_ok);
		light = pos_ok ? decode_light(n.getLightBlend(env->getDayNightRatio(),
							env->getGameDef()->ndef()))
		               : 64;
		video::SColor color(255,light,light,light);
		m_spritenode->setColor(color);
	}
Exemplo n.º 10
0
void ClientMap::renderPostFx(CameraMode cam_mode)
{
	// Sadly ISceneManager has no "post effects" render pass, in that case we
	// could just register for that and handle it in renderMap().

	MapNode n = getNodeNoEx(floatToInt(m_camera_position, BS));

	// - If the player is in a solid node, make everything black.
	// - If the player is in liquid, draw a semi-transparent overlay.
	// - Do not if player is in third person mode
	const ContentFeatures& features = m_nodedef->get(n);
	video::SColor post_effect_color = features.post_effect_color;
	if(features.solidness == 2 && !(g_settings->getBool("noclip") &&
			m_client->checkLocalPrivilege("noclip")) &&
			cam_mode == CAMERA_MODE_FIRST)
	{
		post_effect_color = video::SColor(255, 0, 0, 0);
	}
	if (post_effect_color.getAlpha() != 0)
	{
		// Draw a full-screen rectangle
		video::IVideoDriver* driver = SceneManager->getVideoDriver();
		v2u32 ss = driver->getScreenSize();
		core::rect<s32> rect(0,0, ss.X, ss.Y);
		driver->draw2DRectangle(post_effect_color, rect);
	}
}
Exemplo n.º 11
0
static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
		float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr)
{
	float d0 = (float)BS * p0.getDistanceFrom(p1);
	v3s16 u0 = p1 - p0;
	v3f uf = v3f(u0.X, u0.Y, u0.Z) * BS;
	uf.normalize();
	v3f p0f = v3f(p0.X, p0.Y, p0.Z) * BS;
	u32 count = 0;
	for(float s=start_off; s<d0+end_off; s+=step){
		v3f pf = p0f + uf * s;
		v3s16 p = floatToInt(pf, BS);
		MapNode n = map->getNodeNoEx(p);
		bool is_transparent = false;
		const ContentFeatures &f = nodemgr->get(n);
		if(f.solidness == 0)
			is_transparent = (f.visual_solidness != 2);
		else
			is_transparent = (f.solidness != 2);
		if(!is_transparent){
			count++;
			if(count >= needed_count)
				return true;
		}
		step *= stepfac;
	}
	return false;
}
Exemplo n.º 12
0
void Mapper::updateActiveMarkers ()
{
	video::IImage *minimap_mask = data->minimap_shape_round ?
		data->minimap_mask_round : data->minimap_mask_square;

	std::list<Nametag *> *nametags = client->getCamera()->getNametags();

	m_active_markers.clear();

	for (std::list<Nametag *>::const_iterator
			i = nametags->begin();
			i != nametags->end(); ++i) {
		Nametag *nametag = *i;
		v3s16 pos = floatToInt(nametag->parent_node->getPosition() +
			intToFloat(client->getCamera()->getOffset(), BS), BS);
		pos -= data->pos - v3s16(data->map_size / 2,
				data->scan_height / 2,
				data->map_size / 2);
		if (pos.X < 0 || pos.X > data->map_size ||
				pos.Y < 0 || pos.Y > data->scan_height ||
				pos.Z < 0 || pos.Z > data->map_size) {
			continue;
		}
		pos.X = ((float)pos.X / data->map_size) * MINIMAP_MAX_SX;
		pos.Z = ((float)pos.Z / data->map_size) * MINIMAP_MAX_SY;
		video::SColor mask_col = minimap_mask->getPixel(pos.X, pos.Z);
		if (!mask_col.getAlpha()) {
			continue;
		}
		m_active_markers.push_back(v2f(((float)pos.X / (float)MINIMAP_MAX_SX) - 0.5,
			(1.0 - (float)pos.Z / (float)MINIMAP_MAX_SY) - 0.5));
	}
}
Exemplo n.º 13
0
void LimiterQuad<N>::process(float* input, int16_t* output, int numFrames) {

    for (int n = 0; n < numFrames; n++) {

        // peak detect and convert to log2 domain
        int32_t peak = peaklog2(&input[4*n+0], &input[4*n+1], &input[4*n+2], &input[4*n+3]);

        // compute limiter attenuation
        int32_t attn = MAX(_threshold - peak, 0);

        // apply envelope
        attn = envelope(attn);

        // convert from log2 domain
        attn = fixexp2(attn);

        // lowpass filter
        attn = _filter.process(attn);
        float gain = attn * _outGain;

        // delay audio
        float x0 = input[4*n+0];
        float x1 = input[4*n+1];
        float x2 = input[4*n+2];
        float x3 = input[4*n+3];
        _delay.process(x0, x1, x2, x3);

        // apply gain
        x0 *= gain;
        x1 *= gain;
        x2 *= gain;
        x3 *= gain;

        // apply dither
        float d = dither();
        x0 += d;
        x1 += d;
        x2 += d;
        x3 += d;

        // store 16-bit output
        output[4*n+0] = (int16_t)floatToInt(x0);
        output[4*n+1] = (int16_t)floatToInt(x1);
        output[4*n+2] = (int16_t)floatToInt(x2);
        output[4*n+3] = (int16_t)floatToInt(x3);
    }
}
Exemplo n.º 14
0
  JNIEXPORT jint JNICALL Java_edu_berkeley_bid_CUMACH_floatToInt
  (JNIEnv *env, jobject obj, jint n, jobject jin, jobject jout, jint nbits)
  {
    float *in = (float*)getPointer(env, jin);
    int *out = (int*)getPointer(env, jout);

    return floatToInt(n, in, out, nbits);
  }
Exemplo n.º 15
0
/**
 * Helper function for Client Side Modding
 * Flavour is applied there, this should not be used for core engine
 * @param p
 * @param is_valid_position
 * @return
 */
MapNode Client::getNode(v3s16 p, bool *is_valid_position)
{
	if (checkCSMFlavourLimit(CSMFlavourLimit::CSM_FL_LOOKUP_NODES)) {
		v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS);
		if ((u32) ppos.getDistanceFrom(p) > m_csm_noderange_limit) {
			*is_valid_position = false;
			return {};
		}
	}
	return m_env.getMap().getNodeNoEx(p, is_valid_position);
}
Exemplo n.º 16
0
int parser::parseSubExp(char *p, int &iStartParse, subexp *pSubExp, variable_scope &varScope, bool bReturnParseIndex)
{
	int iCurSub;
	raw_materials rawMat;

	iStartParse++;
	iCurSub = floatToInt(parseDigit(p, iStartParse, bReturnParseIndex));
	rawMat.getTokens(pSubExp[iCurSub].exp, pSubExp, varScope);
	pSubExp[iCurSub].result = rawMat.getResult();

	// we return index of SubExpression which was used 
	return iCurSub;
}
Exemplo n.º 17
0
void Client::addUpdateMeshTask(v3s16 p, bool urgent, int step)
{
	//ScopeProfiler sp(g_profiler, "Client: Mesh prepare");
	MapBlock *b = m_env.getMap().getBlockNoCreateNoEx(p);
	if(b == NULL)
		return;

	/*
		Create a task to update the mesh of the block
	*/
	auto & draw_control = m_env.getClientMap().getControl();
	std::shared_ptr<MeshMakeData> data(new MeshMakeData(this, m_cache_enable_shaders, m_env.getMap(), draw_control));

	{
		//TimeTaker timer("data fill");
		// Release: ~0ms
		// Debug: 1-6ms, avg=2ms
		data->fill(b);

#if ! ENABLE_THREADS
		if (!data->fill_data())
			return;
#endif

		data->setCrack(m_crack_level, m_crack_pos);
		data->setHighlighted(m_highlighted_pos, m_show_highlighted);
		data->setSmoothLighting(m_cache_smooth_lighting);
		data->step = step ? step : getFarmeshStep(data->draw_control, getNodeBlockPos(floatToInt(m_env.getLocalPlayer()->getPosition(), BS)), p);
		data->range = getNodeBlockPos(floatToInt(m_env.getLocalPlayer()->getPosition(), BS)).getDistanceFrom(p);
		if (step)
			data->no_draw = true;
	}

	// Add task to queue
	//unsigned int qsize = 
	//m_mesh_update_thread.m_queue_in.addBlock(p, data, urgent);
	m_mesh_update_thread.enqueueUpdate(p, data, urgent);
	//draw_control.block_overflow = qsize > 1000; // todo: depend on mesh make speed
}
Exemplo n.º 18
0
u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
		bool set_changed)
{
	assert(object);
	if(object->getId() == 0)
	{
		u16 new_id = getFreeServerActiveObjectId(m_active_objects);
		if(new_id == 0)
		{
			dstream<<"WARNING: ServerEnvironment::addActiveObjectRaw(): "
					<<"no free ids available"<<std::endl;
			delete object;
			return 0;
		}
		object->setId(new_id);
	}
	if(isFreeServerActiveObjectId(object->getId(), m_active_objects) == false)
	{
		dstream<<"WARNING: ServerEnvironment::addActiveObjectRaw(): "
				<<"id is not free ("<<object->getId()<<")"<<std::endl;
		delete object;
		return 0;
	}
	/*dstream<<"INGO: ServerEnvironment::addActiveObjectRaw(): "
			<<"added (id="<<object->getId()<<")"<<std::endl;*/
			
	m_active_objects.insert(object->getId(), object);

	// Add static object to active static list of the block
	v3f objectpos = object->getBasePosition();
	std::string staticdata = object->getStaticData();
	StaticObject s_obj(object->getType(), objectpos, staticdata);
	// Add to the block where the object is located in
	v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
	MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
	if(block)
	{
		block->m_static_objects.m_active.insert(object->getId(), s_obj);
		object->m_static_exists = true;
		object->m_static_block = blockpos;

		if(set_changed)
			block->setChangedFlag();
	}
	else{
		dstream<<"WARNING: ServerEnv: Could not find a block for "
				<<"storing newly added static active object"<<std::endl;
	}

	return object->getId();
}
Exemplo n.º 19
0
void MobV2SAO::punch(ServerActiveObject *puncher, float time_from_last_punch)
{
	if(!puncher)
		return;
	
	v3f dir = (getBasePosition() - puncher->getBasePosition()).normalize();

	// A quick hack; SAO description is player name for player
	std::string playername = puncher->getDescription();

	Map *map = &m_env->getMap();
	
	actionstream<<playername<<" punches mob id="<<m_id
			<<" at "<<PP(m_base_position/BS)<<std::endl;

	m_disturb_timer = 0;
	m_disturbing_player = playername;
	m_next_pos_exists = false; // Cancel moving immediately
	
	m_yaw = wrapDegrees_180(180./PI*atan2(dir.Z, dir.X) + 180.);
	v3f new_base_position = m_base_position + dir * BS;
	{
		v3s16 pos_i = floatToInt(new_base_position, BS);
		v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
		v3s16 pos_size_off(0,0,0);
		if(m_size.X >= 2.5){
			pos_size_off.X = -1;
			pos_size_off.Y = -1;
		}
		bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks);
		if(free)
			m_base_position = new_base_position;
	}
	sendPosition();
	

	// "Material" properties of the MobV2
	MaterialProperties mp;
	mp.diggability = DIGGABLE_NORMAL;
	mp.crackiness = -1.0;
	mp.cuttability = 1.0;

	ToolDiggingProperties tp;
	puncher->getWieldDiggingProperties(&tp);

	HittingProperties hitprop = getHittingProperties(&mp, &tp,
			time_from_last_punch);

	doDamage(hitprop.hp);
	puncher->damageWieldedItem(hitprop.wear);
}
Exemplo n.º 20
0
void ClientEnvironment::drawPostFx(video::IVideoDriver* driver, v3f camera_pos)
{
	/*LocalPlayer *player = getLocalPlayer();
	assert(player);
	v3f pos_f = player->getPosition() + v3f(0,BS*1.625,0);*/
	v3f pos_f = camera_pos;
	v3s16 p_nodes = floatToInt(pos_f, BS);
	MapNode n = m_map->getNodeNoEx(p_nodes);
	if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
	{
		v2u32 ss = driver->getScreenSize();
		core::rect<s32> rect(0,0, ss.X, ss.Y);
		driver->draw2DRectangle(video::SColor(64, 100, 100, 200), rect);
	}
}
Exemplo n.º 21
0
float build_in_func::power(float fNumber, int iPowerNum)
{
	int iPowerBase = floatToInt(fNumber);

	if (iPowerNum == 0) fNumber=1;
	else if (iPowerNum > 0)
	{
		for (int i = 0; i < iPowerNum-1; i++) fNumber = iPowerBase * fNumber;
	}
	else if (iPowerNum < 0)
	{
		for (int i = 0; i < abs((float)iPowerNum)-1; i++) fNumber = iPowerBase * fNumber;
		fNumber = 1 / fNumber;
	}
	return fNumber;
}
Exemplo n.º 22
0
int parser::parseFuncArgs(char *p, int &iStartParse, subexp *pSubExp, float *pArgs, int &iArgsNum, variable_scope &varScope)
{
	iStartParse++;
	int iSubIndex = floatToInt(parseDigit(p,iStartParse,true));
    // Implement unary minus here
	for (int i = 0; pSubExp[iSubIndex].exp[i]; i++)
	{
		// Parse digit
		if (isDigit(pSubExp[iSubIndex].exp[i]))
        {
			pArgs[iArgsNum] = parseDigit(pSubExp[iSubIndex].exp, i, true);
		}
		// Parse unary minus
        else if (pSubExp[iSubIndex].exp[i]=='-' && pSubExp[iSubIndex].exp[i+1] && isDigit(pSubExp[iSubIndex].exp[i+1]))
        {
            i++;
            pArgs[iArgsNum] = parseDigit(pSubExp[iSubIndex].exp, i, true, true);
        }
		// Parse next arg
		else if (pSubExp[iSubIndex].exp[i]==',')
		{
			iArgsNum += 1;
			continue;
		}
		// Parse build in func
        else if (isChar(pSubExp[iSubIndex].exp[i]) && isFunc(pSubExp[iSubIndex].exp, i))
        {
            pArgs[iArgsNum] = pSubExp[parseBuildInFunc(pSubExp[iSubIndex].exp, i, pSubExp, varScope, true)].result;
        }
		// Parse variable
		else if (isChar(pSubExp[iSubIndex].exp[i]))
		{
			pArgs[iArgsNum] = varScope.vScope[parseVariable(pSubExp[iSubIndex].exp, i, varScope, false)].getValue();
		}
		// Parse sub string
		else if (pSubExp[iSubIndex].exp[i]=='$')
		{
			pArgs[iArgsNum] = pSubExp[parseSubExp(pSubExp[iSubIndex].exp, i, pSubExp, varScope, true)].result;
		}
	}
	iArgsNum += 1;

	return iSubIndex;
}
Exemplo n.º 23
0
void Sky::sky_rotate (const scene::ICameraSceneNode* camera, SKY_ROTATE type, float wicked_time_of_day, v3f & Pos) {
	v3POS player_position = floatToInt(camera->getPosition(), BS)+camera_offset;
	double shift = (double)player_position.Z / MAP_GENERATION_LIMIT;
	double xz = 90;
	double xy = wicked_time_of_day * 360 - 90;
	double yz = 70 * -shift; // 70 - maximum angle near end of map

	if (type == SKY_ROTATE::MOON)
		xz *= -1;

	if (type == SKY_ROTATE::MOONLIGHT)
		xy -= 90;
	else if (type == SKY_ROTATE::SUNLIGHT)
		xy += 90 + 180;

	Pos.rotateXZBy(xz);
	Pos.rotateXYBy(xy);
	Pos.rotateYZBy(yz);
}
Exemplo n.º 24
0
void cNinjaProgressBar::draw(HDC hdc)
{
	// get current GDI data setup
	sNinjaGDI	*curNGDI = getActiveNGDI();
	if(!curNGDI) return;

	// draw the shaded rectangle
	if(heavy) njDeepShadedRect(hdc,&hostDim,TRUE,curNGDI->ncsBackground);
	else njShadedRect(hdc,&hostDim,TRUE,curNGDI->ncsBackground);
	
	// size of bar to draw
	sUInt32 barSize = floatToInt(((100.0f / (sFloat)(maxVal - minVal)) * curVal) * latSize);

	// draw it!
	RECT bar;
	bar.left = hostDim.left + NINJA_PROGRESSBAR_LATERAL_MARGIN;
	bar.right = bar.left + barSize;
	bar.top = hostDim.top + NINJA_PROGRESSBAR_VERTICAL_MARGIN;
	bar.bottom = hostDim.bottom - NINJA_PROGRESSBAR_VERTICAL_MARGIN;
	njColourRect(hdc,&bar,curNGDI->ncsHighlight);
}
Exemplo n.º 25
0
//VERY BAD COPYPASTE FROM clientmap.cpp!
static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
		float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr,
		unordered_map_v3POS<bool> & occlude_cache)
{
	float d0 = (float)1 * p0.getDistanceFrom(p1);
	v3s16 u0 = p1 - p0;
	v3f uf = v3f(u0.X, u0.Y, u0.Z);
	uf.normalize();
	v3f p0f = v3f(p0.X, p0.Y, p0.Z);
	u32 count = 0;
	for(float s=start_off; s<d0+end_off; s+=step){
		v3f pf = p0f + uf * s;
		v3s16 p = floatToInt(pf, 1);
		bool is_transparent = false;
		bool cache = true;
		if (occlude_cache.count(p)) {
			cache = false;
			is_transparent = occlude_cache[p];
		} else {
		MapNode n = map->getNodeTry(p);
		if (!n) {
			return true; // ONE DIFFERENCE FROM clientmap.cpp
		}
		const ContentFeatures &f = nodemgr->get(n);
		if(f.solidness == 0)
			is_transparent = (f.visual_solidness != 2);
		else
			is_transparent = (f.solidness != 2);
		}
		if (cache)
			occlude_cache[p] = is_transparent;
		if(!is_transparent){
			if(count == needed_count)
				return true;
			count++;
		}
		step *= stepfac;
	}
	return false;
}
Exemplo n.º 26
0
static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
                       float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr,
                       std::unordered_map<v3POS, bool, v3POSHash, v3POSEqual> & occlude_cache)
{
    float d0 = (float)BS * p0.getDistanceFrom(p1);
    v3s16 u0 = p1 - p0;
    v3f uf = v3f(u0.X, u0.Y, u0.Z) * BS;
    uf.normalize();
    v3f p0f = v3f(p0.X, p0.Y, p0.Z) * BS;
    u32 count = 0;
    for(float s=start_off; s<d0+end_off; s+=step) {
        v3f pf = p0f + uf * s;
        v3s16 p = floatToInt(pf, BS);
        bool is_transparent = false;
        bool cache = true;
        if (occlude_cache.count(p)) {
            cache = false;
            is_transparent = occlude_cache[p];
        } else {
            MapNode n = map->getNodeTry(p);
            if (n.getContent() == CONTENT_IGNORE) {
                cache = false;
            }
            const ContentFeatures &f = nodemgr->get(n);
            if(f.solidness == 0)
                is_transparent = (f.visual_solidness != 2);
            else
                is_transparent = (f.solidness != 2);
        }
        if (cache)
            occlude_cache[p] = is_transparent;
        if(!is_transparent) {
            if(count == needed_count)
                return true;
            count++;
        }
        step *= stepfac;
    }
    return false;
}
Exemplo n.º 27
0
float build_in_func::doFunction(char *pFuncName, float *pArgs, int iArgsNum)
{
	int iChosenIndex = chooseFunc(pFuncName);

	switch (iChosenIndex)
	{
	    case 0:
			if (iFuncArgsNum[iChosenIndex] != iArgsNum) throw ArgsNumError;
		    return abs(pArgs[0]);
	    case 1:
			if (iFuncArgsNum[iChosenIndex] != iArgsNum) throw ArgsNumError;
		    return power(pArgs[0], floatToInt(pArgs[1]));
		case 2:
			if (iFuncArgsNum[iChosenIndex] != iArgsNum) throw ArgsNumError;
			show(pArgs[0]);
			return 0;
        default:
            // Case when we not found any build in function with such name
			throw BuildInFuncExistanceError;
		    break;
	}
}
Exemplo n.º 28
0
int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
		int oldvalue, bool *sunlight_seen_result)
{
	const bool debugprint = false;
	INodeDefManager *ndef = m_gamedef->ndef();
	static v3f z_directions[50] = {
		v3f(-100, 0, 0)
	};
	static f32 z_offsets[sizeof(z_directions)/sizeof(*z_directions)] = {
		-1000,
	};
	if(z_directions[0].X < -99){
		for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
			z_directions[i] = v3f(
				0.01 * myrand_range(-100, 100),
				1.0,
				0.01 * myrand_range(-100, 100)
			);
			z_offsets[i] = 0.01 * myrand_range(0,100);
		}
	}
	if(debugprint)
		std::cerr<<"In goes "<<PP(m_camera_direction)<<", out comes ";
	int sunlight_seen_count = 0;
	float sunlight_min_d = max_d*0.8;
	if(sunlight_min_d > 35*BS)
		sunlight_min_d = 35*BS;
	std::vector<int> values;
	for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){
		v3f z_dir = z_directions[i];
		z_dir.normalize();
		core::CMatrix4<f32> a;
		a.buildRotateFromTo(v3f(0,1,0), z_dir);
		v3f dir = m_camera_direction;
		a.rotateVect(dir);
		int br = 0;
		float step = BS*1.5;
		if(max_d > 35*BS)
			step = max_d / 35 * 1.5;
		float off = step * z_offsets[i];
		bool sunlight_seen_now = false;
		bool ok = getVisibleBrightness(this, m_camera_position, dir,
				step, 1.0, max_d*0.6+off, max_d, ndef, daylight_factor,
				sunlight_min_d,
				&br, &sunlight_seen_now);
		if(sunlight_seen_now)
			sunlight_seen_count++;
		if(!ok)
			continue;
		values.push_back(br);
		// Don't try too much if being in the sun is clear
		if(sunlight_seen_count >= 20)
			break;
	}
	int brightness_sum = 0;
	int brightness_count = 0;
	std::sort(values.begin(), values.end());
	u32 num_values_to_use = values.size();
	if(num_values_to_use >= 10)
		num_values_to_use -= num_values_to_use/2;
	else if(num_values_to_use >= 7)
		num_values_to_use -= num_values_to_use/3;
	u32 first_value_i = (values.size() - num_values_to_use) / 2;
	if(debugprint){
		for(u32 i=0; i < first_value_i; i++)
			std::cerr<<values[i]<<" ";
		std::cerr<<"[";
	}
	for(u32 i=first_value_i; i < first_value_i+num_values_to_use; i++){
		if(debugprint)
			std::cerr<<values[i]<<" ";
		brightness_sum += values[i];
		brightness_count++;
	}
	if(debugprint){
		std::cerr<<"]";
		for(u32 i=first_value_i+num_values_to_use; i < values.size(); i++)
			std::cerr<<values[i]<<" ";
	}
	int ret = 0;
	if(brightness_count == 0){
		MapNode n = getNodeNoEx(floatToInt(m_camera_position, BS));
		if(ndef->get(n).param_type == CPT_LIGHT){
			ret = decode_light(n.getLightBlend(daylight_factor, ndef));
		} else {
			ret = oldvalue;
			//ret = blend_light(255, 0, daylight_factor);
		}
	} else {
		/*float pre = (float)brightness_sum / (float)brightness_count;
		float tmp = pre;
		const float d = 0.2;
		pre *= 1.0 + d*2;
		pre -= tmp * d;
		int preint = pre;
		ret = MYMAX(0, MYMIN(255, preint));*/
		ret = brightness_sum / brightness_count;
	}
	if(debugprint)
		std::cerr<<"Result: "<<ret<<" sunlight_seen_count="
				<<sunlight_seen_count<<std::endl;
	*sunlight_seen_result = (sunlight_seen_count > 0);
	return ret;
}
Exemplo n.º 29
0
static bool getVisibleBrightness(Map *map, v3f p0, v3f dir, float step,
		float step_multiplier, float start_distance, float end_distance,
		INodeDefManager *ndef, u32 daylight_factor, float sunlight_min_d,
		int *result, bool *sunlight_seen)
{
	int brightness_sum = 0;
	int brightness_count = 0;
	float distance = start_distance;
	dir.normalize();
	v3f pf = p0;
	pf += dir * distance;
	int noncount = 0;
	bool nonlight_seen = false;
	bool allow_allowing_non_sunlight_propagates = false;
	bool allow_non_sunlight_propagates = false;
	// Check content nearly at camera position
	{
		v3s16 p = floatToInt(p0 /*+ dir * 3*BS*/, BS);
		MapNode n = map->getNodeNoEx(p);
		if(ndef->get(n).param_type == CPT_LIGHT &&
				!ndef->get(n).sunlight_propagates)
			allow_allowing_non_sunlight_propagates = true;
	}
	// If would start at CONTENT_IGNORE, start closer
	{
		v3s16 p = floatToInt(pf, BS);
		MapNode n = map->getNodeNoEx(p);
		if(n.getContent() == CONTENT_IGNORE){
			float newd = 2*BS;
			pf = p0 + dir * 2*newd;
			distance = newd;
			sunlight_min_d = 0;
		}
	}
	for(int i=0; distance < end_distance; i++){
		pf += dir * step;
		distance += step;
		step *= step_multiplier;
		
		v3s16 p = floatToInt(pf, BS);
		MapNode n = map->getNodeNoEx(p);
		if(allow_allowing_non_sunlight_propagates && i == 0 &&
				ndef->get(n).param_type == CPT_LIGHT &&
				!ndef->get(n).sunlight_propagates){
			allow_non_sunlight_propagates = true;
		}
		if(ndef->get(n).param_type != CPT_LIGHT ||
				(!ndef->get(n).sunlight_propagates &&
					!allow_non_sunlight_propagates)){
			nonlight_seen = true;
			noncount++;
			if(noncount >= 4)
				break;
			continue;
		}
		if(distance >= sunlight_min_d && *sunlight_seen == false
				&& nonlight_seen == false)
			if(n.getLight(LIGHTBANK_DAY, ndef) == LIGHT_SUN)
				*sunlight_seen = true;
		noncount = 0;
		brightness_sum += decode_light(n.getLightBlend(daylight_factor, ndef));
		brightness_count++;
	}
	*result = 0;
	if(brightness_count == 0)
		return false;
	*result = brightness_sum / brightness_count;
	/*std::cerr<<"Sampled "<<brightness_count<<" points; result="
			<<(*result)<<std::endl;*/
	return true;
}
Exemplo n.º 30
0
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{
	DSTACK(__FUNCTION_NAME);

	bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
	
	std::string prefix;
	if(pass == scene::ESNRP_SOLID)
		prefix = "CM: solid: ";
	else
		prefix = "CM: transparent: ";

	/*
		This is called two times per frame, reset on the non-transparent one
	*/
	if(pass == scene::ESNRP_SOLID)
	{
		m_last_drawn_sectors.clear();
	}

	bool use_trilinear_filter = g_settings->getBool("trilinear_filter");
	bool use_bilinear_filter = g_settings->getBool("bilinear_filter");
	bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter");

	/*
		Get time for measuring timeout.
		
		Measuring time is very useful for long delays when the
		machine is swapping a lot.
	*/
	int time1 = time(0);

	/*
		Get animation parameters
	*/
	float animation_time = m_client->getAnimationTime();
	int crack = m_client->getCrackLevel();
	u32 daynight_ratio = m_client->getEnv().getDayNightRatio();

	m_camera_mutex.Lock();
	v3f camera_position = m_camera_position;
	v3f camera_direction = m_camera_direction;
	f32 camera_fov = m_camera_fov;
	m_camera_mutex.Unlock();

	/*
		Get all blocks and draw all visible ones
	*/

	v3s16 cam_pos_nodes = floatToInt(camera_position, BS);
	
	v3s16 box_nodes_d = m_control.wanted_range * v3s16(1,1,1);

	v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
	v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;

	// Take a fair amount as we will be dropping more out later
	// Umm... these additions are a bit strange but they are needed.
	v3s16 p_blocks_min(
			p_nodes_min.X / MAP_BLOCKSIZE - 3,
			p_nodes_min.Y / MAP_BLOCKSIZE - 3,
			p_nodes_min.Z / MAP_BLOCKSIZE - 3);
	v3s16 p_blocks_max(
			p_nodes_max.X / MAP_BLOCKSIZE + 1,
			p_nodes_max.Y / MAP_BLOCKSIZE + 1,
			p_nodes_max.Z / MAP_BLOCKSIZE + 1);
	
	u32 vertex_count = 0;
	u32 meshbuffer_count = 0;
	
	// For limiting number of mesh animations per frame
	u32 mesh_animate_count = 0;
	u32 mesh_animate_count_far = 0;
	
	// Blocks that were drawn and had a mesh
	u32 blocks_drawn = 0;
	// Blocks which had a corresponding meshbuffer for this pass
	u32 blocks_had_pass_meshbuf = 0;
	// Blocks from which stuff was actually drawn
	u32 blocks_without_stuff = 0;

	/*
		Draw the selected MapBlocks
	*/

	{
	ScopeProfiler sp(g_profiler, prefix+"drawing blocks", SPT_AVG);

	MeshBufListList drawbufs;

	for(std::map<v3s16, MapBlock*>::iterator
			i = m_drawlist.begin();
			i != m_drawlist.end(); ++i)
	{
		MapBlock *block = i->second;

		// If the mesh of the block happened to get deleted, ignore it
		if(block->mesh == NULL)
			continue;
		
		float d = 0.0;
		if(isBlockInSight(block->getPos(), camera_position,
				camera_direction, camera_fov,
				100000*BS, &d) == false)
		{
			continue;
		}

		// Mesh animation
		{
			//JMutexAutoLock lock(block->mesh_mutex);
			MapBlockMesh *mapBlockMesh = block->mesh;
			assert(mapBlockMesh);
			// Pretty random but this should work somewhat nicely
			bool faraway = d >= BS*50;
			//bool faraway = d >= m_control.wanted_range * BS;
			if(mapBlockMesh->isAnimationForced() ||
					!faraway ||
					mesh_animate_count_far < (m_control.range_all ? 200 : 50))
			{
				bool animated = mapBlockMesh->animate(
						faraway,
						animation_time,
						crack,
						daynight_ratio);
				if(animated)
					mesh_animate_count++;
				if(animated && faraway)
					mesh_animate_count_far++;
			}
			else
			{
				mapBlockMesh->decreaseAnimationForceTimer();
			}
		}

		/*
			Get the meshbuffers of the block
		*/
		{
			//JMutexAutoLock lock(block->mesh_mutex);

			MapBlockMesh *mapBlockMesh = block->mesh;
			assert(mapBlockMesh);

			scene::SMesh *mesh = mapBlockMesh->getMesh();
			assert(mesh);

			u32 c = mesh->getMeshBufferCount();
			for(u32 i=0; i<c; i++)
			{
				scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);

				buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
				buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
				buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);

				const video::SMaterial& material = buf->getMaterial();
				video::IMaterialRenderer* rnd =
						driver->getMaterialRenderer(material.MaterialType);
				bool transparent = (rnd && rnd->isTransparent());
				if(transparent == is_transparent_pass)
				{
					if(buf->getVertexCount() == 0)
						errorstream<<"Block ["<<analyze_block(block)
								<<"] contains an empty meshbuf"<<std::endl;
					drawbufs.add(buf);
				}
			}
		}
	}
	
	std::list<MeshBufList> &lists = drawbufs.lists;
	
	int timecheck_counter = 0;
	for(std::list<MeshBufList>::iterator i = lists.begin();
			i != lists.end(); ++i)
	{
		{
			timecheck_counter++;
			if(timecheck_counter > 50)
			{
				timecheck_counter = 0;
				int time2 = time(0);
				if(time2 > time1 + 4)
				{
					infostream<<"ClientMap::renderMap(): "
						"Rendering takes ages, returning."
						<<std::endl;
					return;
				}
			}
		}

		MeshBufList &list = *i;
		
		driver->setMaterial(list.m);
		
		for(std::list<scene::IMeshBuffer*>::iterator j = list.bufs.begin();
				j != list.bufs.end(); ++j)
		{
			scene::IMeshBuffer *buf = *j;
			driver->drawMeshBuffer(buf);
			vertex_count += buf->getVertexCount();
			meshbuffer_count++;
		}
#if 0
		/*
			Draw the faces of the block
		*/
		{
			//JMutexAutoLock lock(block->mesh_mutex);

			MapBlockMesh *mapBlockMesh = block->mesh;
			assert(mapBlockMesh);

			scene::SMesh *mesh = mapBlockMesh->getMesh();
			assert(mesh);

			u32 c = mesh->getMeshBufferCount();
			bool stuff_actually_drawn = false;
			for(u32 i=0; i<c; i++)
			{
				scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
				const video::SMaterial& material = buf->getMaterial();
				video::IMaterialRenderer* rnd =
						driver->getMaterialRenderer(material.MaterialType);
				bool transparent = (rnd && rnd->isTransparent());
				// Render transparent on transparent pass and likewise.
				if(transparent == is_transparent_pass)
				{
					if(buf->getVertexCount() == 0)
						errorstream<<"Block ["<<analyze_block(block)
								<<"] contains an empty meshbuf"<<std::endl;
					/*
						This *shouldn't* hurt too much because Irrlicht
						doesn't change opengl textures if the old
						material has the same texture.
					*/
					driver->setMaterial(buf->getMaterial());
					driver->drawMeshBuffer(buf);
					vertex_count += buf->getVertexCount();
					meshbuffer_count++;
					stuff_actually_drawn = true;
				}
			}
			if(stuff_actually_drawn)
				blocks_had_pass_meshbuf++;
			else
				blocks_without_stuff++;
		}
#endif
	}
	} // ScopeProfiler
	
	// Log only on solid pass because values are the same
	if(pass == scene::ESNRP_SOLID){
		g_profiler->avg("CM: animated meshes", mesh_animate_count);
		g_profiler->avg("CM: animated meshes (far)", mesh_animate_count_far);
	}
	
	g_profiler->avg(prefix+"vertices drawn", vertex_count);
	if(blocks_had_pass_meshbuf != 0)
		g_profiler->avg(prefix+"meshbuffers per block",
				(float)meshbuffer_count / (float)blocks_had_pass_meshbuf);
	if(blocks_drawn != 0)
		g_profiler->avg(prefix+"empty blocks (frac)",
				(float)blocks_without_stuff / blocks_drawn);

	/*infostream<<"renderMap(): is_transparent_pass="******", rendered "<<vertex_count<<" vertices."<<std::endl;*/
}