Esempio n. 1
0
// 2nd pass: which roi would this operation need as input to fill the given output region?
void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out,
                   dt_iop_roi_t *roi_in)
{
  *roi_in = *roi_out;

  const float scale = roi_in->scale / piece->iscale;

  float aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width, roi_out->y + roi_out->height };

  float aabb_in[4] = { INFINITY, INFINITY, -INFINITY, -INFINITY };

  for(int c = 0; c < 4; c++)
  {
    float p[2], o[2];

    // get corner points of roi_out
    get_corner(aabb, c, p);

    backtransform(piece, scale, p, o);

    // transform to roi_in space, get aabb.
    adjust_aabb(o, aabb_in);
  }

  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);
  const float IW = interpolation->width * scale;

  // adjust roi_in to minimally needed region
  roi_in->x = aabb_in[0] - IW;
  roi_in->y = aabb_in[1] - IW;
  roi_in->width = aabb_in[2] - roi_in->x + IW;
  roi_in->height = aabb_in[3] - roi_in->y + IW;
}
// Return cached corner with the given lattice Location
bloomenthal_polygonizer::Corner* bloomenthal_polygonizer::get_cached_corner(const Location& L)
{
	Corner* c = get_corner(L);
	if(!c)
	{
		c = new Corner(L);
		c->p = location_vertex(L);
		c->value = m_FieldFunctor.implicit_value(c->p);

		m_Corners.insert(L, c);
	}

	return c;
}
Esempio n. 3
0
// 2nd pass: which roi would this operation need as input to fill the given output region?
void modify_roi_in(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out,
                   dt_iop_roi_t *roi_in)
{
  *roi_in = *roi_out;

  const float scale = roi_in->scale / piece->iscale;

  float aabb[4] = { roi_out->x, roi_out->y, roi_out->x + roi_out->width, roi_out->y + roi_out->height };

  float aabb_in[4] = { INFINITY, INFINITY, -INFINITY, -INFINITY };

  for(int c = 0; c < 4; c++)
  {
    float p[2], o[2];

    // get corner points of roi_out
    get_corner(aabb, c, p);

    backtransform(piece, scale, p, o);

    // transform to roi_in space, get aabb.
    adjust_aabb(o, aabb_in);
  }

  const struct dt_interpolation *interpolation = dt_interpolation_new(DT_INTERPOLATION_USERPREF);
  const float IW = (float)interpolation->width * scale;

  const float orig_w = roi_in->scale * piece->buf_in.width, orig_h = roi_in->scale * piece->buf_in.height;

  // adjust roi_in to minimally needed region
  roi_in->x = fmaxf(0.0f, aabb_in[0] - IW);
  roi_in->y = fmaxf(0.0f, aabb_in[1] - IW);
  roi_in->width = fminf(orig_w - roi_in->x, aabb_in[2] - roi_in->x + IW);
  roi_in->height = fminf(orig_h - roi_in->y, aabb_in[3] - roi_in->y + IW);

  // sanity check.
  roi_in->x = CLAMP(roi_in->x, 0, (int)floorf(orig_w));
  roi_in->y = CLAMP(roi_in->y, 0, (int)floorf(orig_h));
  roi_in->width = CLAMP(roi_in->width, 1, (int)ceilf(orig_w) - roi_in->x);
  roi_in->height = CLAMP(roi_in->height, 1, (int)ceilf(orig_h) - roi_in->y);
}
Esempio n. 4
0
void World::set_tera_height(Plasma &plasma)
{
	memset(corner_matrix, 0, sizeof(Corner)*(max_x_loc+1)*(max_y_loc+1));

	// short seaHeight = TerrainRes::max_height(TERRAIN_OCEAN);
	short seaHeight = 0;			// no more sea
	int y;
	int x;
	for(y = 0; y <= max_y_loc; ++y )
	{
		for(x = 0; x <= max_x_loc; ++x)
		{
			Corner *cornerPtr = get_corner(x,y);
			cornerPtr->set_altitude(plasma.get_pix(x,y));
			cornerPtr->set_sea_altitude(seaHeight);

			// set gradient_x
			float gradientX;
			if(x <= 0)
			{
				err_when(x < 0);
				gradientX = float(4*plasma.get_pix(x+1,y) - plasma.get_pix(x+2,y) - 3*plasma.get_pix(x,y)) 
					/ (2 * LOCATE_WIDTH);
			}
			else if( x >= max_x_loc )
			{
				err_when(x > max_x_loc);
				gradientX = float(plasma.get_pix(x-2,y) - 4*plasma.get_pix(x-1,y) + 3*plasma.get_pix(x,y)) 
					/ (2 * LOCATE_WIDTH);
			}
			else
			{
				gradientX = float(plasma.get_pix(x+1,y) - plasma.get_pix(x-1,y)) 
					/ (2 * LOCATE_WIDTH);
			}

//			if( gradientX >= 0.0f && gradientX <= 0.25f )
//				gradientX += 0.15f;
//			else if( gradientX < 0.0f && gradientX >= -0.25f )
//				gradientX -= 0.15f;
			cornerPtr->set_gradient_x( gradientX );

			// set gradient_y
			float gradientY;
			if(y <= 0)
			{
				err_when(y < 0);
				gradientY = float(4*plasma.get_pix(x,y+1) - plasma.get_pix(x,y+2) - 3*plasma.get_pix(x,y))
					/ (2 * LOCATE_HEIGHT);
			}
			else if( y >= max_y_loc )
			{
				err_when(y > max_y_loc);
				gradientY = float(plasma.get_pix(x,y-2) - 4*plasma.get_pix(x,y-1) + 3*plasma.get_pix(x,y))
					/ (2 * LOCATE_HEIGHT);
			}
			else
			{
				gradientY = float(plasma.get_pix(x,y+1) - plasma.get_pix(x,y-1))
					/ (2 * LOCATE_HEIGHT);
			}

//			if( gradientY >= 0.0f && gradientY <= 0.25f )
//				gradientY += 0.15f;
//			else if( gradientY < 0.0f && gradientY >= -0.25f )
//				gradientY -= 0.15f;
			cornerPtr->set_gradient_y( gradientY );

		}
	}

	// calculate polynomial coefficient
	for(y = 0; y < max_y_loc; ++y )
	{
		for(x = 0; x < max_x_loc; ++x)
		{
			LocationCorners lc;
			get_loc_corner(x,y, &lc);
			short &z0 = lc.top_left->altitude;
			short &z1 = lc.top_right->altitude;
			short &z2 = lc.bottom_left->altitude;
			short &z3 = lc.bottom_right->altitude;
			short &duz0w = lc.top_left->gradient_x;		// du/dz * LOCATE_WIDTH
			short &dvz0h = lc.top_left->gradient_y;
			short &duz1w = lc.top_right->gradient_x;
			short &dvz1h = lc.top_right->gradient_y;
			short &duz2w = lc.bottom_left->gradient_x;
			short &dvz2h = lc.bottom_left->gradient_y;
			short &duz3w = lc.bottom_right->gradient_x;
			short &dvz3h = lc.bottom_right->gradient_y;

			lc.loc_ptr->c30 = (duz1w + duz0w - (z1-z0) * 2) << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT);
			lc.loc_ptr->c21 = (duz3w + duz0w - duz1w - duz2w) << (C_MULTIPLIER_SHIFT - 1 - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_HEIGHT_SHIFT);
			lc.loc_ptr->c12 = (dvz3h + dvz0h - dvz1h - dvz2h) << (C_MULTIPLIER_SHIFT - 1 - LOCATE_WIDTH_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT);
			lc.loc_ptr->c03 = (dvz2h + dvz0h - (z2-z0) * 2) << (C_MULTIPLIER_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT);
			lc.loc_ptr->c20 = ( (z1-z0) * 3 - duz1w - duz0w * 2 ) << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_WIDTH_SHIFT);
			lc.loc_ptr->c11 = (( z3 + z0 - z1 - z2 ) << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT - LOCATE_HEIGHT_SHIFT))
				- (lc.loc_ptr->c21 << LOCATE_WIDTH_SHIFT) - (lc.loc_ptr->c12 << LOCATE_HEIGHT_SHIFT);
			lc.loc_ptr->c02 = ( (z2-z0) * 3 - dvz2h - dvz0h * 2 ) << (C_MULTIPLIER_SHIFT - LOCATE_HEIGHT_SHIFT - LOCATE_HEIGHT_SHIFT);
			lc.loc_ptr->c00 = z0 << C_MULTIPLIER_SHIFT;
			lc.loc_ptr->c10 = duz0w << (C_MULTIPLIER_SHIFT - LOCATE_WIDTH_SHIFT);
			lc.loc_ptr->c01 = dvz0h << (C_MULTIPLIER_SHIFT - LOCATE_HEIGHT_SHIFT);

			// find the height of the rendered bitmap
			{
				lc.loc_ptr->min_y = 0;
				lc.loc_ptr->max_y = 0;

				int seaLevel = 0;
				if( lc.top_left->is_sea() )
					seaLevel = lc.top_left->sea_altitude;
				if( lc.top_right->is_sea() )
					seaLevel = lc.top_right->sea_altitude;
				if( lc.bottom_left->is_sea() )
					seaLevel = lc.bottom_left->sea_altitude;
				if( lc.bottom_right->is_sea() )
					seaLevel = lc.bottom_right->sea_altitude;

				if( seaLevel )
					lc.loc_ptr->loc_flag |= LOCATE_SEA_COAST;
				else
					lc.loc_ptr->loc_flag &= ~LOCATE_SEA_COAST;


				// height relative to top left corner
				// int refHeight = ZoomMatrix::calc_abs_y(0, 0, lc.loc_ptr->evaluate_z(0, 0));
				int refHeight = ZoomMatrix::calc_abs_y(0, 0, lc.loc_ptr->c00 >> C_MULTIPLIER_SHIFT);

				// include LOCATE_WIDTH, LOCATE_HEIGHT for wider min_y, max_y
				for(int v = 0; v <= LOCATE_HEIGHT; v+=LOCATE_HEIGHT/4 )
				{
					for( int u = 0; u <= LOCATE_WIDTH; u+=LOCATE_WIDTH/4 )
					{
						long z = lc.loc_ptr->evaluate_z(u, v);

						// if cover by sea
						if( seaLevel && z < seaLevel )
							z = seaLevel;

						int pointY = ZoomMatrix::calc_abs_y(u, v, z) - refHeight;
							//(z - z0) * ZOOM_Z_HEIGHT
							//+ (u * ZOOM_LOC_X_HEIGHT * LOCATE_HEIGHT
							//+ v * ZOOM_LOC_Y_HEIGHT * LOCATE_WIDTH ) 
							//>> (LOCATE_WIDTH_SHIFT + LOCATE_HEIGHT_SHIFT);

						if( pointY < lc.loc_ptr->min_y)
							lc.loc_ptr->min_y = pointY;
						if( pointY > lc.loc_ptr->max_y)
							lc.loc_ptr->max_y = pointY;
					}
				}

				lc.loc_ptr->min_y -= 8;		// -4 for more space
				lc.loc_ptr->max_y += 8;		// +4 for more space
			}
		}
	}
}
Esempio n. 5
0
//---------- Begin of function MapMatrix::draw_map ------------//
// see also World::explore
//
void MapMatrix::draw_map()
{
	//----------- draw map now ------------//

	sys.yield();

	short	fireColor = vga_back.translate_color(FIRE_COLOR);
	short plantColor = vga_back.translate_color(plant_res.plant_map_color);
	short	seaColor = vga_back.translate_color(0x32);
	short rockColor = vga_back.translate_color( 0x59 );
	short mapModeColor = vga_back.translate_color( VGA_GRAY+10 );
	short unexploredColor = vga_back.translate_color(UNEXPLORED_COLOR);
	short shadowColor = vga_back.translate_color( VGA_GRAY+2 );
	short roadColor = vga_back.translate_color( VGA_GRAY+12 );
	short	nationColorArray[MAX_NATION+2];
	for( int n = 0; n < MAX_NATION+2; ++n )
		nationColorArray[n] = vga_back.translate_color(nation_array.nation_power_color_array[n]);
	// #### begin Ban 8/12 #######//
	int temp3 = vga_back.buf_true_pitch() -2;
	short *temp6 = vga_back.buf_ptr((image_x1 + image_x2)/2, image_y1);
#ifdef ASM_FOR_MSVC
	_asm
	{
		MOV AX , DS
		MOV	ES , AX
		MOV	EDX, temp3		
		MOV	EDI, temp6
		CLD                 
		MOV	AX, word ptr UNEXPLORED_COLOR
		MOV	CX, AX				// processing the color for drawing
		SHL	EAX, 16
		MOV	AX, CX
		MOV	EBX, 100
		XOR ECX, ECX
PutLineUpper:					// draw upper triangle
		INC	ECX
		REP	STOSD
		MOV ECX, 101			// restore ECX after STOSD for updating EDI
		SUB ECX, EBX
		ADD	EDI, EDX			// updating EDI to start point of next line
		SUB EDI, ECX
		SUB EDI, ECX
		SUB EDI, ECX
		SUB EDI, ECX
		DEC	EBX					// decrease the remain height
		JNZ	PutLineUpper		// loop
		MOV	EBX, 99				// ready parameters for drawing lower triangle
		ADD EDX, 4
		ADD EDI, 4
PutLineLower:					// draw lower triangle
		MOV ECX, EBX
		REP	STOSD
		ADD	EDI, EDX			// updating EDI to start point of next line
		SUB EDI, EBX
		SUB EDI, EBX
		SUB EDI, EBX
		SUB EDI, EBX
		DEC	EBX					// decrease the remain height
		JNZ	PutLineLower		// loop
	}
#else
		int lineDiff = temp3 / 2;
		int lineLength = 2;
		// Blacken upper half of minimap.
		for ( int i = 0; i < 100; ++i )
		{
			for ( int j = 0; j < lineLength; ++j )
			{
				*temp6 = UNEXPLORED_COLOR;
				++temp6;
			}
			temp6 += lineDiff - lineLength;
			lineLength += 2;
		}
		// Blacken lower half of minimap.
		lineLength = 99 * 2;
		lineDiff += 2;
		temp6 += 2;
		for ( int i = 0; i < 99; ++i )
		{
			for ( int j = 0; j < lineLength; ++j )
			{
				*temp6 = UNEXPLORED_COLOR;
				++temp6;
			}
			temp6 += lineDiff - lineLength;
			lineLength -= 2;
		}
#endif
	// #### end Ban 8/12 #######//
//	{	// traversal of location in MapMatrix
//		int pixelX = (image_x1 + image_x2 + 1) / 2;
//		int pixelY = image_y1;
//		int xLoc, yLoc;
//		int writePtrInc = vga_back.buf_pitch() + 1;
//		for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc )
//		{
//			short* writePtr  = vga_back.buf_ptr(pixelX, pixelY);
//			xLoc = 0;
//			Location *locPtr = get_loc( xLoc, yLoc );
//			for( xLoc = 0; xLoc < max_x_loc; (xLoc += 2), (writePtr += writePtrInc), (locPtr+=2) )
//			{
//			}
//		}
//	}

	switch(map_mode)
	{
	case MAP_MODE_TERRAIN:
		{
			int pixelX = (image_x1 + image_x2 + 1) / 2;
			int pixelY = image_y1;
			int xLoc, yLoc;
			int writePtrInc = vga_back.buf_pitch() + 1;
			for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc )
			{
				short* writePtr  = vga_back.buf_ptr(pixelX, pixelY);
				int tileYOffset = (yLoc & TERRAIN_TILE_Y_MASK) * TERRAIN_TILE_WIDTH;
				xLoc = 0;
				Location* locPtr = get_loc( xLoc, yLoc );
				for( ; xLoc < max_x_loc; (xLoc += 2), (locPtr += 2), (writePtr += writePtrInc) )
				{
					if( locPtr->explored() )
					{
						// ##### begin Gilbert 10/2 #######//
						if( filter_object_flag || filter_nation_flag )		// do not anything except filtered objects when filters are on
							*writePtr = mapModeColor;
						else if( locPtr->fire_str() > 0)
						// ##### end Gilbert 10/2 #######//
							*writePtr = fireColor;
						else if( locPtr->is_plant() || xLoc+1<max_x_loc && locPtr[1].is_plant() )
							*writePtr = plantColor;
						else if( locPtr->is_rock() )
							*writePtr = rockColor;
						else if( locPtr->has_dirt() )
						{
							Rock *dirtPtr = dirt_array[locPtr->dirt_recno()];
							RockInfo *dirtInfo = rock_res.get_rock_info(dirtPtr->rock_recno);
							if (dirtInfo->rock_type == 'P')
								*writePtr = seaColor;
							else
								*writePtr = rockColor;
						}

						else if( locPtr->is_road() )
							*writePtr = vga_back.translate_color(terrain_res.get_map_tile(locPtr->road_terrain_id)[tileYOffset + (xLoc & TERRAIN_TILE_X_MASK)]);
						else
						{
							if( xLoc < 2 || 
								terrain_res[locPtr->terrain_id]->average_type >=
								terrain_res[(locPtr-2)->terrain_id]->average_type )
							{
								// get terrain pixel from terrain_res
								*writePtr = vga_back.translate_color(terrain_res.get_map_tile(locPtr->terrain_id)[tileYOffset + (xLoc & TERRAIN_TILE_X_MASK)]);
							}
							else
							{
								*writePtr = shadowColor;
							}
						}
					}
					//else 	// not needed because filled black already
					//{
					//	*writePtr = unexploredColor;
					//}
				}
			}
		}
		break;


	// ##### begin Gilbert 2/11 #####//
	case MAP_MODE_TRADE:
	// ##### end Gilbert 2/11 #####//
	case MAP_MODE_SPOT:
		{	// traversal of location in MapMatrix
			int pixelX = (image_x1 + image_x2 + 1) / 2;
			int pixelY = image_y1;
			int xLoc, yLoc;
			int writePtrInc = vga_back.buf_pitch() + 1;
			for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc )
			{
				short* writePtr  = vga_back.buf_ptr(pixelX, pixelY);
				xLoc = 0;
				Location* locPtr = get_loc( xLoc, yLoc );
				for( ; xLoc < max_x_loc; (xLoc += 2), (locPtr +=2), (writePtr += writePtrInc) )
				{
					if( locPtr->explored() )
					{
						*writePtr = mapModeColor;
					}
				}
			}
		}
		break;

	case MAP_MODE_POWER:
		{
			int pixelX = (image_x1 + image_x2 + 1) / 2;
			int pixelY = image_y1;
			int xLoc, yLoc;
			int writePtrInc = vga_back.buf_pitch() + 1;
			for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc )
			{
				short* writePtr  = vga_back.buf_ptr(pixelX, pixelY);
				xLoc = 0;
				Location *locPtr = get_loc( xLoc, yLoc );
				for( xLoc = 0; xLoc < max_x_loc; (xLoc += 2), (locPtr +=2), (writePtr += writePtrInc) )
				{
					if( locPtr->explored() )
					{
						// ####### begin Gilbert 10/2 #########//
						if( filter_object_flag || filter_nation_flag )		// do not anything except filtered objects when filters are on
							*writePtr = mapModeColor;
						else if( locPtr->sailable() )
						// ####### end Gilbert 10/2 #########//
							*writePtr = seaColor;
						else if( locPtr->is_rock() || locPtr[1].is_rock() )
							*writePtr = rockColor;
/*						else if( locPtr->has_dirt() )
						{
							Rock *dirtPtr = dirt_array[locPtr->dirt_recno()];
							RockInfo *dirtInfo = rock_res.get_rock_info(dirtPtr->rock_recno);
							if (dirtInfo->rock_type == 'P')
								*writePtr = seaColor;
							else
								*writePtr = rockColor;
						}

						else if( locPtr->is_plant() || xLoc+1<max_x_loc && locPtr[1].is_plant() )
							*writePtr = plantColor;
*/						else
						// ###### begin Gilbert 21/12 ########//
						{
							if( power_mode )
								*writePtr = nationColorArray[locPtr->power_nation_recno];
							else
								*writePtr = nationColorArray[0];
						}
						// ###### end Gilbert 21/12 ########//
					}
				}
			}
		}
		break;

	case MAP_MODE_ALTITUDE:
		{
			int pixelX = (image_x1 + image_x2 + 1) / 2;
			int pixelY = image_y1;
			int xLoc, yLoc;
			int writePtrInc = vga_back.buf_pitch() + 1;
			for( yLoc = 0; yLoc < max_y_loc; (yLoc&1?++pixelY:--pixelX) , ++yLoc )
			{
				short* writePtr  = vga_back.buf_ptr(pixelX, pixelY);
				xLoc = 0;
				for( xLoc = 0; xLoc < max_x_loc; (xLoc += 2), (writePtr += writePtrInc) )
				{
					Corner *cornerPtr = get_corner( xLoc, yLoc );
					short alt = cornerPtr->get_altitude();
					if( alt > 255 )
						alt = 255;
					else if( alt < 0 )
						alt = 0;
					*writePtr = vga.make_pixel((BYTE)alt, 128, 32);
				}
			}
		}
		break;
	}

	sys.yield();
}