Ejemplo n.º 1
0
Metric CalcRandomMetric (CCodeChain &CC, ICCItem *pItem)

//	CalcRandomMetric
//
//	Parses an item to generate a Metric. The item may have one of the following
//	formats:
//
//	integer
//		We treat as a distance in light-seconds.
//
//	('gaussian min center max)
//		We return a random distance between min and max with center as the 
//		average, using a Gaussian random distribution. All values are expressed
//		in light-seconds, but we can return random numbers anywhere in between.

	{
	if (pItem == NULL || pItem->IsNil())
		return 0.0;
	else if (pItem->IsList())
		{
		if (pItem->GetCount() >= 4 && strEquals(pItem->GetElement(0)->GetStringValue(), FIELD_GAUSSIAN))
			{
			//	Get the parameters

			double rLow = pItem->GetElement(1)->GetIntegerValue();
			double rMid = pItem->GetElement(2)->GetIntegerValue();
			double rHigh = pItem->GetElement(3)->GetIntegerValue();
			if (rLow >= rMid || rLow >= rHigh || rMid >= rHigh)
				return 0.0;

			//	Compute some ranges

			double rHighRange = rHigh - rMid;
			double rLowRange = rMid - rLow;

			//	Generate a gaussian, but clip out after 3 standard deviations

			double rMaxStdDev = 3.0;
			double rValue;
			do
				{
				rValue = mathRandomGaussian();
				}
			while (rValue > rMaxStdDev || rValue < -rMaxStdDev);

			rValue = rValue / rMaxStdDev;

			//	Scale to proper value

			if (rValue >= 0.0)
				return (rMid + rValue * rHighRange) * LIGHT_SECOND;
			else
				return (rMid + rValue * rLowRange) * LIGHT_SECOND;
			}
		else
			return 0.0;
		}
	else
		return (pItem->GetIntegerValue() * LIGHT_SECOND);
	}
Ejemplo n.º 2
0
DWORD CCrewPsyche::GenerateNormalLevel (void)

//	GenerateNormalLevel
//
//	Generates a random level that clusters around neutral.

	{
	double rValue = SCrewMetrics::NEUTRAL_LEVEL + (mathRandomGaussian() * (SCrewMetrics::NEUTRAL_HIGH_LEVEL - SCrewMetrics::NEUTRAL_LOW_LEVEL));

	if (rValue <= (double)SCrewMetrics::MIN_LEVEL)
		return 0;
	else if (rValue >= (double)SCrewMetrics::MAX_LEVEL)
		return SCrewMetrics::MAX_LEVEL;
	else
		return (DWORD)rValue;
	}
Ejemplo n.º 3
0
void CRayEffectPainter::CalcIntermediates (void)

//	CalcIntermediates
//
//	Calculate intermediate values used for painting.

	{
	int i, v, w;

	if (!m_bInitialized)
		{
		enum EColorTypes
			{
			colorNone,
			colorGlow,
			};

		enum EOpacityTypes
			{
			opacityNone,
			opacityGlow,
			opacityGrainy,
			opacityTaperedGlow,
			};

		enum EWidthAdjTypes
			{
			widthAdjNone,
			widthAdjBlob,
			widthAdjDiamond,
			widthAdjJagged,
			widthAdjOval,
			widthAdjTapered,
			widthAdjCone,
			};

		EColorTypes iColorTypes = colorNone;
		EOpacityTypes iOpacityTypes = opacityNone;
		EWidthAdjTypes iWidthAdjType = widthAdjNone;
		EWidthAdjTypes iReshape = widthAdjNone;
		EOpacityTypes iTexture = opacityNone;

		m_iWidthCount = m_iWidth;
		m_iLengthCount = 2 * m_iLength;

		//	Every combination requires a slightly different set up

		switch (m_iShape)
			{
			case shapeCone:
				switch (m_iStyle)
					{
					case styleBlob:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjBlob;
						iReshape = widthAdjCone;
						break;

					case styleGlow:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjCone;
						break;

					case styleGrainy:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjCone;
						iTexture = opacityGrainy;
						break;

					case styleJagged:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjJagged;
						iReshape = widthAdjCone;
						break;
					}
				break;

			case shapeDiamond:
				switch (m_iStyle)
					{
					case styleBlob:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjBlob;
						iReshape = widthAdjDiamond;
						break;

					case styleGlow:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjDiamond;
						break;

					case styleGrainy:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjDiamond;
						iTexture = opacityGrainy;
						break;

					case styleJagged:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjJagged;
						iReshape = widthAdjDiamond;
						break;
					}
				break;

			case shapeOval:
				switch (m_iStyle)
					{
					case styleBlob:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjBlob;
						iReshape = widthAdjOval;
						break;

					case styleGlow:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjOval;
						break;

					case styleGrainy:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjOval;
						iTexture = opacityGrainy;
						break;

					case styleJagged:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjJagged;
						iReshape = widthAdjOval;
						break;
					}
				break;

			case shapeStraight:
				switch (m_iStyle)
					{
					case styleBlob:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityGlow;
						iWidthAdjType = widthAdjBlob;
						break;

					case styleGlow:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityGlow;
						break;

					case styleGrainy:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityGlow;
						iTexture = opacityGrainy;
						break;

					case styleJagged:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityGlow;
						iWidthAdjType = widthAdjJagged;
						break;
					}
				break;

			case shapeTapered:
				switch (m_iStyle)
					{
					case styleBlob:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjBlob;
						iReshape = widthAdjTapered;
						break;

					case styleGlow:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjTapered;
						break;

					case styleGrainy:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjTapered;
						iTexture = opacityGrainy;
						break;

					case styleJagged:
						iColorTypes = colorGlow;
						iOpacityTypes = opacityTaperedGlow;
						iWidthAdjType = widthAdjJagged;
						iReshape = widthAdjTapered;
						break;
					}
				break;
			}

		//	Full color map

		switch (iColorTypes)
			{
			case colorGlow:
				{
				m_ColorMap.InsertEmpty(1);
				m_ColorMap[0].InsertEmpty(m_iWidthCount);

				//	The center blends towards white

				WORD wCenter = CG16bitImage::BlendPixel(m_wPrimaryColor, CG16bitImage::RGBValue(255, 255, 255), (DWORD)(255.0 * Min(50, m_iIntensity) / 50.0));

				int iBrightPoint = (int)(BRIGHT_FACTOR * m_iWidthCount * m_iIntensity);
				for (i = 0; i < iBrightPoint; i++)
					m_ColorMap[0][i] = wCenter;

				//	The rest fades (linearly) from primary color to secondary color

				Metric rFadeInc = (m_iWidthCount > 0 ? (1.0 / (m_iWidthCount - iBrightPoint)) : 0.0);
				Metric rFade = 1.0;
				for (i = iBrightPoint; i < m_iWidthCount; i++, rFade -= rFadeInc)
					m_ColorMap[0][i] = CG16bitImage::BlendPixel(m_wSecondaryColor, m_wPrimaryColor, (DWORD)(255.0 * rFade));

				break;
				}
			}

		//	Full opacity

		switch (iOpacityTypes)
			{
			case opacityGlow:
				{
				m_OpacityMap.InsertEmpty(1);
				m_OpacityMap[0].InsertEmpty(m_iWidthCount);

				//	From center to peak we have solid opacity

				int iPeakPoint = (int)(SOLID_FACTOR * m_iIntensity * m_iWidthCount);
				for (i = 0; i < iPeakPoint; i++)
					m_OpacityMap[0][i] = 255;

				//	We decay exponentially to edge

				Metric rGlowLevel = MIN_GLOW_LEVEL + (m_iIntensity * GLOW_FACTOR);
				Metric rGlowInc = (m_iWidthCount > 0 ? (1.0 / (m_iWidthCount - iPeakPoint)) : 0.0);
				Metric rGlow = 1.0;
				for (i = iPeakPoint; i < m_iWidthCount; i++, rGlow -= rGlowInc)
					m_OpacityMap[0][i] = (int)(255.0 * rGlowLevel * rGlow * rGlow);

				break;
				}

			case opacityTaperedGlow:
				{
				m_OpacityMap.InsertEmpty(m_iLengthCount);
				for (i = 0; i < m_iLengthCount; i++)
					m_OpacityMap[i].InsertEmpty(m_iWidthCount);

				//	From center to peak we have solid opacity

				int iPeakPoint = (int)(SOLID_FACTOR * m_iIntensity * m_iWidthCount);

				//	After the 1/3 point start fading out (linearly)

				int iFadePoint = m_iLengthCount / TAPER_FRACTION;
				Metric rTaperInc = (m_iLengthCount > 0 ? (1.0 / (m_iLengthCount - iFadePoint)) : 0.0);

				//	From center to peak we have solid opacity plus taper

				for (w = 0; w < iPeakPoint; w++)
					{
					for (v = 0; v < iFadePoint; v++)
						m_OpacityMap[v][w] = 255;

					Metric rTaper = 1.0;
					for (v = iFadePoint; v < m_iLengthCount; v++, rTaper -= rTaperInc)
						m_OpacityMap[v][w] = (int)(255.0 * rTaper);
					}

				//	The glow around the peak decays exponentially

				Metric rGlowLevel = MIN_GLOW_LEVEL + (m_iIntensity * GLOW_FACTOR);
				Metric rGlowInc = (m_iWidthCount > 0 ? (1.0 / (m_iWidthCount - iPeakPoint)) : 0.0);
				Metric rGlow = 1.0;
				for (w = iPeakPoint; w < m_iWidthCount; w++, rGlow -= rGlowInc)
					{
					Metric rGlowPart = rGlowLevel * rGlow * rGlow;

					for (v = 0; v < iFadePoint; v++)
						m_OpacityMap[v][w] = (int)(255.0 * rGlowPart);

					Metric rTaper = 1.0;
					for (v = iFadePoint; v < m_iLengthCount; v++, rTaper -= rTaperInc)
						m_OpacityMap[v][w] = (int)(255.0 * rGlowPart * rTaper);
					}

				break;
				}
			}

		//	Width adjustments

		switch (iWidthAdjType)
			{
			case widthAdjBlob:
				{
				m_WidthAdjTop.InsertEmpty(m_iLengthCount);
				m_WidthAdjBottom.InsertEmpty(m_iLengthCount);

				//	Initialize jagged envelope

				CalcWaves(m_WidthAdjTop, BLOB_WAVE_SIZE, m_iWidth * WAVY_WAVELENGTH_FACTOR);
				CalcWaves(m_WidthAdjBottom, BLOB_WAVE_SIZE, m_iWidth * WAVY_WAVELENGTH_FACTOR);

				break;
				}

			case widthAdjCone:
				{
				m_WidthAdjTop.InsertEmpty(m_iLengthCount);

				CalcCone(m_WidthAdjTop);
				m_WidthAdjBottom = m_WidthAdjTop;

				break;
				}

			case widthAdjDiamond:
				{
				m_WidthAdjTop.InsertEmpty(m_iLengthCount);

				CalcDiamond(m_WidthAdjTop);
				m_WidthAdjBottom = m_WidthAdjTop;

				break;
				}

			case widthAdjJagged:
				{
				m_WidthAdjTop.InsertEmpty(m_iLengthCount);
				m_WidthAdjBottom.InsertEmpty(m_iLengthCount);

				//	Initialize jagged envelope

				CalcWaves(m_WidthAdjTop, JAGGED_AMPLITUDE, m_iWidth * JAGGED_WAVELENGTH_FACTOR);
				CalcWaves(m_WidthAdjBottom, JAGGED_AMPLITUDE, m_iWidth * JAGGED_WAVELENGTH_FACTOR);

				break;
				}

			case widthAdjOval:
				{
				m_WidthAdjTop.InsertEmpty(m_iLengthCount);

				CalcOval(m_WidthAdjTop);
				m_WidthAdjBottom = m_WidthAdjTop;

				break;
				}

			case widthAdjTapered:
				{
				m_WidthAdjTop.InsertEmpty(m_iLengthCount);

				CalcTaper(m_WidthAdjTop);
				m_WidthAdjBottom = m_WidthAdjTop;

				break;
				}
			}

		//	Adjust shape

		switch (iReshape)
			{
			case widthAdjCone:
				{
				TArray<Metric> TaperAdj;
				TaperAdj.InsertEmpty(m_iLengthCount);
				CalcCone(TaperAdj);

				for (i = 0; i < m_iLengthCount; i++)
					{
					m_WidthAdjTop[i] *= TaperAdj[i];
					m_WidthAdjBottom[i] *= TaperAdj[i];
					}
				break;
				}

			case widthAdjDiamond:
				{
				TArray<Metric> TaperAdj;
				TaperAdj.InsertEmpty(m_iLengthCount);
				CalcDiamond(TaperAdj);

				for (i = 0; i < m_iLengthCount; i++)
					{
					m_WidthAdjTop[i] *= TaperAdj[i];
					m_WidthAdjBottom[i] *= TaperAdj[i];
					}
				break;
				}

			case widthAdjOval:
				{
				TArray<Metric> TaperAdj;
				TaperAdj.InsertEmpty(m_iLengthCount);
				CalcOval(TaperAdj);

				for (i = 0; i < m_iLengthCount; i++)
					{
					m_WidthAdjTop[i] *= TaperAdj[i];
					m_WidthAdjBottom[i] *= TaperAdj[i];
					}
				break;
				}

			case widthAdjTapered:
				{
				TArray<Metric> TaperAdj;
				TaperAdj.InsertEmpty(m_iLengthCount);
				CalcTaper(TaperAdj);

				for (i = 0; i < m_iLengthCount; i++)
					{
					m_WidthAdjTop[i] *= TaperAdj[i];
					m_WidthAdjBottom[i] *= TaperAdj[i];
					}
				break;
				}
			}

		//	Apply texture

		switch (iTexture)
			{
			case opacityGrainy:
				{
				const int DIAMETER = 11;
				const int START = -(DIAMETER / 2);
				const int CENTER_X = (DIAMETER / 2);
				const int CENTER_Y = (DIAMETER / 2);
				const Metric RADIUS = (DIAMETER / 2.0);

				Metric Adj[DIAMETER][DIAMETER];
				for (v = 0; v < DIAMETER; v++)
					for (w = 0; w < DIAMETER; w++)
						{
						int vDiff = v - CENTER_X;
						int wDiff = w - CENTER_Y;

						Metric rDist = sqrt((Metric)(vDiff * vDiff + wDiff * wDiff)) / RADIUS;
						Adj[v][w] = Max(0.0, 1.0 - rDist);
						}

				int iPeakPoint = (int)(SOLID_FACTOR * m_iIntensity * m_iWidthCount);

				int iGrainCount = (int)(4 * sqrt((Metric)m_iLength * m_iWidth));
				for (i = 0; i < iGrainCount; i++)
					{
					int vCount = m_OpacityMap.GetCount();
					int wCount = m_OpacityMap[0].GetCount();
					int vCenter = mathRandom(0, vCount - 1);
					int wCenter = mathRandom(0, wCount - 1);

					Metric rCenter = GRAINY_SIGMA * mathRandomGaussian();

					for (v = 0; v < DIAMETER; v++)
						{
						int vPos = START + vCenter + v;
						if (vPos < 0 || vPos >= vCount)
							continue;

						for (w = 0; w < DIAMETER; w++)
							{
							int wPos = START + wCenter + w;
							if (wPos < iPeakPoint || wPos >= wCount)
								continue;

							m_OpacityMap[vPos][wPos] = (BYTE)Min(Max(0, (int)((Metric)m_OpacityMap[vPos][wPos] * (1.0 + rCenter * Adj[v][w]))), 255);
							}
						}
					}
				
				break;
				}
			}

		//	Done

		m_bInitialized = true;
		}
	}