Ejemplo n.º 1
0
/*
	startpos:
	translate_dir: unit vector with only one of x, y or z
	face_dir: unit vector with only one of x, y or z
*/
void updateFastFaceRow(
		u32 daynight_ratio,
		v3f posRelative_f,
		v3s16 startpos,
		u16 length,
		v3s16 translate_dir,
		v3f translate_dir_f,
		v3s16 face_dir,
		v3f face_dir_f,
		core::array<FastFace> &dest,
		NodeModMap &temp_mods,
		VoxelManipulator &vmanip,
		v3s16 blockpos_nodes,
		bool smooth_lighting)
{
	v3s16 p = startpos;
	
	u16 continuous_tiles_count = 0;
	
	bool makes_face;
	v3s16 p_corrected;
	v3s16 face_dir_corrected;
	u8 lights[4];
	TileSpec tile;
	getTileInfo(blockpos_nodes, p, face_dir, daynight_ratio,
			vmanip, temp_mods, smooth_lighting,
			makes_face, p_corrected, face_dir_corrected, lights, tile);

	for(u16 j=0; j<length; j++)
	{
		// If tiling can be done, this is set to false in the next step
		bool next_is_different = true;
		
		v3s16 p_next;
		
		bool next_makes_face = false;
		v3s16 next_p_corrected;
		v3s16 next_face_dir_corrected;
		u8 next_lights[4] = {0,0,0,0};
		TileSpec next_tile;
		
		// If at last position, there is nothing to compare to and
		// the face must be drawn anyway
		if(j != length - 1)
		{
			p_next = p + translate_dir;
			
			getTileInfo(blockpos_nodes, p_next, face_dir, daynight_ratio,
					vmanip, temp_mods, smooth_lighting,
					next_makes_face, next_p_corrected,
					next_face_dir_corrected, next_lights,
					next_tile);
			
			if(next_makes_face == makes_face
					&& next_p_corrected == p_corrected
					&& next_face_dir_corrected == face_dir_corrected
					&& next_lights[0] == lights[0]
					&& next_lights[1] == lights[1]
					&& next_lights[2] == lights[2]
					&& next_lights[3] == lights[3]
					&& next_tile == tile)
			{
				next_is_different = false;
			}
		}

		continuous_tiles_count++;
		
		// This is set to true if the texture doesn't allow more tiling
		bool end_of_texture = false;
		/*
			If there is no texture, it can be tiled infinitely.
			If tiled==0, it means the texture can be tiled infinitely.
			Otherwise check tiled agains continuous_tiles_count.
		*/
		if(tile.texture.atlas != NULL && tile.texture.tiled != 0)
		{
			if(tile.texture.tiled <= continuous_tiles_count)
				end_of_texture = true;
		}
		
		// Do this to disable tiling textures
		//end_of_texture = true; //DEBUG
		
		if(next_is_different || end_of_texture)
		{
			/*
				Create a face if there should be one
			*/
			if(makes_face)
			{
				// Floating point conversion of the position vector
				v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
				// Center point of face (kind of)
				v3f sp = pf - ((f32)continuous_tiles_count / 2. - 0.5) * translate_dir_f;
				v3f scale(1,1,1);

				if(translate_dir.X != 0)
				{
					scale.X = continuous_tiles_count;
				}
				if(translate_dir.Y != 0)
				{
					scale.Y = continuous_tiles_count;
				}
				if(translate_dir.Z != 0)
				{
					scale.Z = continuous_tiles_count;
				}
				
				makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
						sp, face_dir_corrected, scale,
						posRelative_f, dest);
			}

			continuous_tiles_count = 0;
			
			makes_face = next_makes_face;
			p_corrected = next_p_corrected;
			face_dir_corrected = next_face_dir_corrected;
			lights[0] = next_lights[0];
			lights[1] = next_lights[1];
			lights[2] = next_lights[2];
			lights[3] = next_lights[3];
			tile = next_tile;
		}
		
		p = p_next;
	}
}
Ejemplo n.º 2
0
/*
	startpos:
	translate_dir: unit vector with only one of x, y or z
	face_dir: unit vector with only one of x, y or z
*/
static void updateFastFaceRow(
    MeshMakeData *data,
    v3s16 startpos,
    v3s16 translate_dir,
    v3f translate_dir_f,
    v3s16 face_dir,
    v3f face_dir_f,
    core::array<FastFace> &dest)
{
    v3s16 p = startpos;

    u16 continuous_tiles_count = 0;

    bool makes_face = false;
    v3s16 p_corrected;
    v3s16 face_dir_corrected;
    u16 lights[4] = {0,0,0,0};
    TileSpec tile;
    u8 light_source = 0;
    getTileInfo(data, p, face_dir,
                makes_face, p_corrected, face_dir_corrected,
                lights, tile, light_source);

    for(u16 j=0; j<MAP_BLOCKSIZE; j++)
    {
        // If tiling can be done, this is set to false in the next step
        bool next_is_different = true;

        v3s16 p_next;

        bool next_makes_face = false;
        v3s16 next_p_corrected;
        v3s16 next_face_dir_corrected;
        u16 next_lights[4] = {0,0,0,0};
        TileSpec next_tile;
        u8 next_light_source = 0;

        // If at last position, there is nothing to compare to and
        // the face must be drawn anyway
        if(j != MAP_BLOCKSIZE - 1)
        {
            p_next = p + translate_dir;

            getTileInfo(data, p_next, face_dir,
                        next_makes_face, next_p_corrected,
                        next_face_dir_corrected, next_lights,
                        next_tile, next_light_source);

            if(next_makes_face == makes_face
                    && next_p_corrected == p_corrected + translate_dir
                    && next_face_dir_corrected == face_dir_corrected
                    && next_lights[0] == lights[0]
                    && next_lights[1] == lights[1]
                    && next_lights[2] == lights[2]
                    && next_lights[3] == lights[3]
                    && next_tile == tile
                    && next_light_source == light_source)
            {
                next_is_different = false;
            }
            else {
                /*if(makes_face){
                	g_profiler->add("Meshgen: diff: next_makes_face != makes_face",
                			next_makes_face != makes_face ? 1 : 0);
                	g_profiler->add("Meshgen: diff: n_p_corr != p_corr + t_dir",
                			(next_p_corrected != p_corrected + translate_dir) ? 1 : 0);
                	g_profiler->add("Meshgen: diff: next_f_dir_corr != f_dir_corr",
                			next_face_dir_corrected != face_dir_corrected ? 1 : 0);
                	g_profiler->add("Meshgen: diff: next_lights[] != lights[]",
                			(next_lights[0] != lights[0] ||
                			next_lights[0] != lights[0] ||
                			next_lights[0] != lights[0] ||
                			next_lights[0] != lights[0]) ? 1 : 0);
                	g_profiler->add("Meshgen: diff: !(next_tile == tile)",
                			!(next_tile == tile) ? 1 : 0);
                }*/
            }
            /*g_profiler->add("Meshgen: Total faces checked", 1);
            if(makes_face)
            	g_profiler->add("Meshgen: Total makes_face checked", 1);*/
        } else {
            /*if(makes_face)
            	g_profiler->add("Meshgen: diff: last position", 1);*/
        }

        continuous_tiles_count++;

        // This is set to true if the texture doesn't allow more tiling
        bool end_of_texture = false;
        /*
        	If there is no texture, it can be tiled infinitely.
        	If tiled==0, it means the texture can be tiled infinitely.
        	Otherwise check tiled agains continuous_tiles_count.
        */
        if(tile.texture.atlas != NULL && tile.texture.tiled != 0)
        {
            if(tile.texture.tiled <= continuous_tiles_count)
                end_of_texture = true;
        }

        // Do this to disable tiling textures
        //end_of_texture = true; //DEBUG

        if(next_is_different || end_of_texture)
        {
            /*
            	Create a face if there should be one
            */
            if(makes_face)
            {
                // Floating point conversion of the position vector
                v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
                // Center point of face (kind of)
                v3f sp = pf - ((f32)continuous_tiles_count / 2. - 0.5) * translate_dir_f;
                if(continuous_tiles_count != 1)
                    sp += translate_dir_f;
                v3f scale(1,1,1);

                if(translate_dir.X != 0)
                {
                    scale.X = continuous_tiles_count;
                }
                if(translate_dir.Y != 0)
                {
                    scale.Y = continuous_tiles_count;
                }
                if(translate_dir.Z != 0)
                {
                    scale.Z = continuous_tiles_count;
                }

                makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
                             sp, face_dir_corrected, scale, light_source,
                             dest);

                g_profiler->avg("Meshgen: faces drawn by tiling", 0);
                for(int i=1; i<continuous_tiles_count; i++) {
                    g_profiler->avg("Meshgen: faces drawn by tiling", 1);
                }
            }

            continuous_tiles_count = 0;

            makes_face = next_makes_face;
            p_corrected = next_p_corrected;
            face_dir_corrected = next_face_dir_corrected;
            lights[0] = next_lights[0];
            lights[1] = next_lights[1];
            lights[2] = next_lights[2];
            lights[3] = next_lights[3];
            tile = next_tile;
            light_source = next_light_source;
        }

        p = p_next;
    }
}
Ejemplo n.º 3
0
/*
	startpos:
	translate_dir: unit vector with only one of x, y or z
	face_dir: unit vector with only one of x, y or z
*/
static void updateFastFaceRow(
		MeshMakeData *data,
		v3s16 startpos,
		v3s16 translate_dir,
		v3f translate_dir_f,
		v3s16 face_dir,
		v3f face_dir_f,
		std::vector<FastFace> &dest,
		int step)
{
	v3s16 p = startpos;

	u16 continuous_tiles_count = 0;

	bool makes_face = false;
	v3s16 p_corrected;
	v3s16 face_dir_corrected;
	u16 lights[4] = {0,0,0,0};
	TileSpec tile;
	u8 light_source = 0;
	getTileInfo(data, p, face_dir,
			makes_face, p_corrected, face_dir_corrected,
			lights, tile, light_source, step);

	auto prev_p_corrected = p_corrected;

	u16 to = MAP_BLOCKSIZE/step;
	for(u16 j=0; j<to; j++)
	{
		// If tiling can be done, this is set to false in the next step
		bool next_is_different = true;

		v3s16 p_next;

		bool next_makes_face = false;
		v3s16 next_p_corrected;
		v3s16 next_face_dir_corrected;
		u16 next_lights[4] = {0,0,0,0};
		TileSpec next_tile;
		u8 next_light_source = 0;

		// If at last position, there is nothing to compare to and
		// the face must be drawn anyway
		if(j != to - 1)
		{
			p_next = p + translate_dir;

			getTileInfo(data, p_next, face_dir,
					next_makes_face, next_p_corrected,
					next_face_dir_corrected, next_lights,
					next_tile, next_light_source, step);

			if(next_makes_face == makes_face
					&& next_p_corrected == prev_p_corrected + translate_dir
					&& next_face_dir_corrected == face_dir_corrected
					&& next_lights[0] == lights[0]
					&& next_lights[1] == lights[1]
					&& next_lights[2] == lights[2]
					&& next_lights[3] == lights[3]
					&& next_tile == tile
					&& tile.rotation == 0
					&& next_light_source == light_source)
			{
				next_is_different = false;
			}
			else{
				/*if(makes_face){
					g_profiler->add("Meshgen: diff: next_makes_face != makes_face",
							next_makes_face != makes_face ? 1 : 0);
					g_profiler->add("Meshgen: diff: n_p_corr != p_corr + t_dir",
							(next_p_corrected != p_corrected + translate_dir) ? 1 : 0);
					g_profiler->add("Meshgen: diff: next_f_dir_corr != f_dir_corr",
							next_face_dir_corrected != face_dir_corrected ? 1 : 0);
					g_profiler->add("Meshgen: diff: next_lights[] != lights[]",
							(next_lights[0] != lights[0] ||
							next_lights[0] != lights[0] ||
							next_lights[0] != lights[0] ||
							next_lights[0] != lights[0]) ? 1 : 0);
					g_profiler->add("Meshgen: diff: !(next_tile == tile)",
							!(next_tile == tile) ? 1 : 0);
				}*/
			}
			/*g_profiler->add("Meshgen: Total faces checked", 1);
			if(makes_face)
				g_profiler->add("Meshgen: Total makes_face checked", 1);*/
		} else {
			/*if(makes_face)
				g_profiler->add("Meshgen: diff: last position", 1);*/
		}

		continuous_tiles_count++;

		if(next_is_different)
		{
			/*
				Create a face if there should be one
			*/
			if(makes_face)
			{
				// Floating point conversion of the position vector
				v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
				// Center point of face (kind of)
				v3f sp = pf - ((f32)continuous_tiles_count / 2.0 - 0.5) * translate_dir_f;
				if(continuous_tiles_count > 1)
					sp += translate_dir_f * (continuous_tiles_count - 1);
				v3f scale(1,1,1);

				if(translate_dir.X != 0) {
					scale.X = continuous_tiles_count;
				}
				if(translate_dir.Y != 0) {
					scale.Y = continuous_tiles_count;
				}
				if(translate_dir.Z != 0) {
					scale.Z = continuous_tiles_count;
				}

				makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
						sp, face_dir_corrected, scale, light_source,
						dest);

#if !defined(NDEBUG)
				g_profiler->avg("Meshgen: faces drawn by tiling", continuous_tiles_count);
#endif
			}

			continuous_tiles_count = 0;

			makes_face = next_makes_face;
			p_corrected = next_p_corrected;
			face_dir_corrected = next_face_dir_corrected;
			lights[0] = next_lights[0];
			lights[1] = next_lights[1];
			lights[2] = next_lights[2];
			lights[3] = next_lights[3];
			tile = next_tile;
			light_source = next_light_source;
		}

		p = p_next;
		prev_p_corrected = next_p_corrected;
	}
}