예제 #1
0
GridPos Grid::positionOfPiece(Piece* piece) const {
    auto it = _piecePositions.find(piece);
    if (it != _piecePositions.end()) {
        return (*it).second;
    }
    return GridPos(0,0);
}
				void DataGridContentProvider::NotifySelectCell(vint row, vint column)
				{
					currentCell=GridPos(row, column);
					dataGrid->NotifySelectedCellChanged();

					if(listViewItemStyleProvider)
					{
						GuiListControl::IItemStyleController* selectedStyleController=0;
						GuiListControl::IItemArranger* arranger=dataGrid->GetArranger();
						if(arranger)
						{
							selectedStyleController=arranger->GetVisibleStyle(row);
						}
						
						vint count=listViewItemStyleProvider->GetCreatedItemStyles().Count();
						for(vint i=0;i<count;i++)
						{
							GuiListControl::IItemStyleController* itemStyleController=listViewItemStyleProvider->GetCreatedItemStyles().Get(i);
							ItemContent* itemContent=listViewItemStyleProvider->GetItemContent<ItemContent>(itemStyleController);
							if(itemContent)
							{
								if(itemStyleController==selectedStyleController)
								{
									itemContent->NotifySelectCell(column);
								}
								else
								{
									itemContent->NotifySelectCell(-1);
								}
							}
						}
					}
				}
				bool DataGridContentProvider::SetSelectedCell(const GridPos& value, bool openEditor)
				{
					if(currentCell!=value)
					{
						if(value==GridPos(-1, -1))
						{
							CloseEditor(false);
							return true;
						}
						else if(0<=value.row && value.row<dataProvider->GetRowCount() && 0<=value.column && value.column<dataProvider->GetColumnCount())
						{
							IDataEditorFactory* editorFactory=openEditor?dataProvider->GetCellDataEditorFactory(value.row, value.column):0;
							OpenEditor(value.row, value.column, editorFactory);
							return true;
						}
						return false;
					}
					return true;
				}
				void DataGridContentProvider::CloseEditor(bool forOpenNewEditor)
				{
					if(currentEditorRequestingSaveData)
					{
						NotifyCloseEditor();
					}
					else
					{
						if(currentCell!=GridPos(-1, -1))
						{
							if(currentEditor)
							{
								NotifyCloseEditor();
								currentEditor=0;
							}
							if(!forOpenNewEditor)
							{
								NotifySelectCell(-1, -1);
							}
						}
					}
				}
예제 #5
0
GridPos GridPos::operator+(const GridPos& p) const {
    return GridPos(q + p.q, r + p.r);
}
예제 #6
0
GridPos GridPos::operator-(const GridPos& p) const {
    return GridPos(q - p.q, r - p.r);
}
예제 #7
0
/* Core code contributed by Kevin Behilo, 2/20/04.
 *
 * Possible TODO: add code to soften and blend shadow edges
 *  (see aliasing comments in source).
 *
 * Definite TODO: the whole thing can be sped up by precalculating the
 *  surface normals once.  In fact that should be placed in a separate Shading
 *  Context, so that it could be re-used for quickly re-shading multiple times.
 */
void vtHeightFieldGrid3d::ShadowCastDib(vtBitmapBase *pBM, const FPoint3 &light_dir,
	float fLightFactor, float fAmbient, bool progress_callback(int)) const
{
	const IPoint2 bitmap_size = pBM->GetSize();

	// Compute area that we will sample for shading, bounded by the texel
	//  centers, which are 1/2 texel in from the grid extents.
	const DPoint2 texel_size(m_EarthExtents.Width() / bitmap_size.x,
							 m_EarthExtents.Height() / bitmap_size.y);
	DRECT texel_area = m_EarthExtents;
	texel_area.Grow(-texel_size.x/2, -texel_size.y/2);
	const DPoint2 texel_base(texel_area.left, texel_area.bottom);

	const bool b8bit = (pBM->GetDepth() == 8);

	// These values are hardcoded here but could be exposed in the GUI
	const float sun =  0.7f;

	// If we have light that's pointing UP, rather than down at the terrain,
	//  then it's only going to take a really long time to produce a
	//  completely dark terrain.  We can catch this case up front.
	if (light_dir.y > 0)
	{
		for (int i = 0; i < bitmap_size.x; i++)
		{
			for (int j = 0; j < bitmap_size.y; j++)
			{
				if (b8bit)
					pBM->ScalePixel8(i, j, fAmbient);
				else
					pBM->ScalePixel24(i, j, fAmbient);
			}
		}
		return;
	}

	// Create array to hold flags
	LightMap lightmap(bitmap_size.x, bitmap_size.y);

	// This factor is used when applying shading to non-shadowed areas to
	// try and keep the "contrast" down to a min. (still get "patches" of
	// dark/light spots though).
	// It is initialized to 1.0, because in case there are no shadows at all
	//  (such as at noon) we still need a reasonable value.
	float darkest_shadow = 1.0;

	// For the vector used to cast shadows, we need it in grid coordinates,
	//  which are (Column,Row) where Row is north.  But the direction passed
	//  in uses OpenGL coordinates where Z is south.  So flip Z.
	FPoint3 grid_light_dir = light_dir;
	grid_light_dir.z = -grid_light_dir.z;

	// Scale the light vector such that the X or Z component (whichever is
	//  larger) is 1.  This is will serve as our direction vector in grid
	//  coordinates, when drawing a line across the grid to cast the shadow.
	//
	// Code adapted from aaron_torpy:
	// http://www.geocities.com/aaron_torpy/algorithms.htm
	//
	float f, HScale;
	if ( fabs(grid_light_dir.x) > fabs(grid_light_dir.z) )
	{
		HScale = m_fStep.x;
		f = fabs(light_dir.x);
	}
	else
	{
		HScale = m_fStep.y;
		f = fabs(light_dir.z);
	}
	grid_light_dir /= f;

	int i_init, i_final, i_incr;
	int j_init, j_final, j_incr;
	if (grid_light_dir.x > 0)
	{
		i_init=0;
		i_final=bitmap_size.x;
		i_incr=1;
	}
	else
	{
		i_init=bitmap_size.x-1;
		i_final=-1;
		i_incr=-1;
	}
	if (grid_light_dir.z > 0)
	{
		j_init=0;
		j_final=bitmap_size.y;
		j_incr=1;
	}
	else
	{
		j_init=bitmap_size.y-1;
		j_final=-1;
		j_incr=-1;
	}

	// First pass: find each point that it is in shadow.
	DPoint2 pos;
	float shadowheight, elevation;
	FPoint3 normal;
	FPoint3 p3;
	int x, z;
	float shade;

	for (int j = j_init; j != j_final; j += j_incr)
	{
		if (progress_callback != NULL && (j%20) == 0)
			progress_callback(abs(j-j_init) * 100 / bitmap_size.y);

		for (int i = i_init; i != i_final; i += i_incr)
		{
			pos = GridPos(texel_base, texel_size, i, j);
			FindAltitudeOnEarth(pos, shadowheight, true);

			if (shadowheight == INVALID_ELEVATION)
			{
				// set a flag so we won't visit this one again
				lightmap.Set(i, j, 1);
				continue;
			}

			bool Under_Out = false;
			for (int k = 1; Under_Out == false; k++)
			{
				x = (int) (i + grid_light_dir.x*k + 0.5f);
				z = (int) (j + grid_light_dir.z*k + 0.5f);
				shadowheight += grid_light_dir.y * HScale;

				if ((x<0) || (x>bitmap_size.x-1) || (z<0) || (z>bitmap_size.y-1))
				{
					Under_Out = true; // Out of the grid
					break;
				}

				pos = GridPos(texel_base, texel_size, x, z);
				FindAltitudeOnEarth(pos, elevation, true);

				// skip holes in the grid
				if (elevation == INVALID_ELEVATION)
					continue;

				if (elevation > shadowheight)
				{
					if (k>1)
						Under_Out = true; // Under the terrain
					break;
				}

				// Combine color and shading.
				// Only do shadow if we have not shaded this i,j before.
				if (lightmap.Get(x,z) < 1)
				{
					// 3D elevation query to get slope
					m_LocalCS.EarthToLocal(pos, p3.x, p3.z);
					FindAltitudeAtPoint(p3, p3.y, true, 0, &normal);

					//*****************************************
					// Here the Sun(r, g, b) = 0 because we are in the shade
					// therefore I(r, g, b) = Amb(r, g, b) * (0.5*N[z] + 0.5)

				//	shade =  sun*normal.Dot(-light_direction) + fAmbient * (0.5f*normal.y + 0.5f);
					shade =  fAmbient * (0.5f*normal.y + 0.5f);
					//*****************************************
					//*****************************************
					if (darkest_shadow > shade)
						darkest_shadow = shade;

					// Rather than doing the shading at this point we may want to
					// simply save the value into the LightMap array. Then apply
					// some anti-aliasing or edge softening algorithm to the LightMap.
					// Once that's done, apply the whole LightMap to the DIB.
					if (b8bit)
						pBM->ScalePixel8(x, bitmap_size.y-1-z, shade);
					else
						pBM->ScalePixel24(x, bitmap_size.y-1-z, shade);

					// set a flag to show that this texel has been shaded.
					// (or set to value of the shading - see comment above)
					lightmap.Set(x, z, lightmap.Get(x, z)+1);
				}
			}
		} //for i
	} //for j

	// For dot-product lighting, we use the normal 3D vector, only inverted
	//  so that we can compare it to the upward-pointing ground normals.
	const FPoint3 inv_light_dir = -light_dir;

	// Second pass.  Now we are going to loop through the LightMap and apply
	//  the full lighting formula to each texel that has not been shaded yet.
	for (int j = 0; j < bitmap_size.y; j++)
	{
		if (progress_callback != NULL && (j%20) == 0)
			progress_callback(j * 100 / bitmap_size.y);

		for (int i = 0; i < bitmap_size.x; i++)
		{
			if (lightmap.Get(i, j) > 0)
				continue;

			pos = GridPos(texel_base, texel_size, i, j);

			// 2D elevation query to check for holes in the grid
			FindAltitudeOnEarth(pos, elevation, true);
			if (elevation == INVALID_ELEVATION)
				continue;

			// 3D elevation query to get slope
			m_LocalCS.EarthToLocal(pos, p3.x, p3.z);
			FindAltitudeAtPoint(p3, p3.y, true, 0, &normal);

			//*****************************************
			//*****************************************
			//shade formula based on:
			//http://www.geocities.com/aaron_torpy/algorithms.htm#calc_intensity

			// The Amb value was arbitrarily chosen
			// Need to experiment more to determine the best value
			// Perhaps calculating Sun(r, g, b) and Amb(r, g, b) for a
			//  given time of day (e.g. warmer colors close to sunset)
			// or give control to user since textures will differ

			// I(r, g, b) = Sun(r, g, b) * scalarprod(N, v) + Amb(r, g, b) * (0.5*N[z] + 0.5)
			shade = sun * normal.Dot(inv_light_dir);

			// It's a reasonable assuption that an angle of 45 degrees is
			//  sufficient to fully illuminate the ground.
			shade /= .7071f;

			// Now add ambient component
			shade += fAmbient * (0.5f*normal.y + 0.5f);

			// Maybe clipping values can be exposed to the user as well.
			// Clip - don't shade down below lowest ambient level
			if (shade < darkest_shadow)
				shade = darkest_shadow;
			else if (shade > 1.2f)
				shade = 1.2f;

			// Push the value of 'shade' toward 1.0 by the fLightFactor factor.
			// This means that fLightFactor=0 means no lighting, 1 means full lighting.
			float diff = 1 - shade;
			diff = diff * (1 - fLightFactor);
			shade += diff;

			// Rather than doing the shading at this point we may want to
			// simply save the value into the LightMap array. Then apply
			// some anti-aliasing or edge softening algorithm to the LightMap.
			// Once that's done, apply the whole LightMap to the DIB.
			// LightMap[I][J]= shade; // set to value of the shading - see comment above)
			if (b8bit)
				pBM->ScalePixel8(i, bitmap_size.y-1-j, shade);
			else
				pBM->ScalePixel24(i, bitmap_size.y-1-j, shade);
		}
	}

	// Possible TODO: Apply edge softening algorithm (?)
}
예제 #8
0
 /*!
   * @return the position below this position
   *
   * \sa left(), right(), up()
   */
 inline GridPos down()
 {
     return GridPos(row()+1, column());
 }
예제 #9
0
 /*!
   * @return the position above this position
   *
   * \sa left(), right(), down()
   */
 inline GridPos up()
 {
     return GridPos(row()-1, column());
 }
예제 #10
0
 /*!
   * @return the position to the right of this position
   *
   * \sa left(), up(), down()
   */
 inline GridPos right()
 {
     return GridPos(row(), column()+1);
 }
예제 #11
0
 /*!
   * @return the position to the left of this position
   *
   * \sa right(), up(), down()
   */
 inline GridPos left()
 {
     return GridPos(row(), column()-1);
 }