Beispiel #1
0
sRGBAfloat cRenderWorker::LightShading(const sShaderInputData &input, cLights::sLight light,
		int number, sRGBAfloat *outSpecular)
{
	sRGBAfloat shading;

	CVector3 d = light.position - input.point;

	double distance = d.Length();

	//angle of incidence
	CVector3 lightVector = d;
	lightVector.Normalize();

	double intensity = 100.0 * light.intensity / (distance * distance) / number;
	double shade = input.normal.Dot(lightVector);
	if (shade < 0) shade = 0;
	shade = shade * intensity;
	if (shade > 500.0) shade = 500.0;

	//specular
	CVector3 half = lightVector - input.viewVector;
	half.Normalize();
	double shade2 = input.normal.Dot(half);
	if (shade2 < 0.0) shade2 = 0.0;
	shade2 = pow(shade2, 30.0) * 1.0;
	shade2 *= intensity * params->specular;
	if (shade2 > 15.0) shade2 = 15.0;

	//calculate shadow
	if ((shade > 0.01 || shade2 > 0.01) && params->shadow)
	{
		double light = AuxShadow(input, distance, lightVector);
		shade *= light;
		shade2 *= light;
	}
	else
	{
		if (params->shadow)
		{
			shade = 0;
			shade2 = 0;
		}
	}

	shading.R = shade * light.colour.R / 65536.0;
	shading.G = shade * light.colour.G / 65536.0;
	shading.B = shade * light.colour.B / 65536.0;

	outSpecular->R = shade2 * light.colour.R / 65536.0;
	outSpecular->G = shade2 * light.colour.G / 65536.0;
	outSpecular->B = shade2 * light.colour.B / 65536.0;

	return shading;
}
double CalculateDistanceMinPlane(const sParamRender &params, const cNineFractals &fractals,
	const CVector3 planePoint, const CVector3 direction, const CVector3 orthDirection,
	bool *stopRequest)
{
	// the plane is defined by the 'planePoint' and the orthogogonal 'direction'
	// the method will return the minimum distance from the plane to the fractal
	double distStep = 0.0;
	CVector3 point = planePoint;
	const double detail = 0.5;
	const int transVectorAngles = 5;

	CVector3 rotationAxis = planePoint;
	rotationAxis.Normalize();

	while (distStep == 0 || distStep > 0.00001)
	{
		CVector3 pointNextBest(0, 0, 0);
		double newDistStepMin = 0;
		for (int i = 0; i <= transVectorAngles; i++)
		{
			const double angle = (double(i) / transVectorAngles) * 2.0 * M_PI;
			CVector3 transversalVect = orthDirection;
			transversalVect = transversalVect.RotateAroundVectorByAngle(rotationAxis, angle);
			transversalVect.Normalize();
			CVector3 pointNext = point + direction * distStep;
			if (i > 0) pointNext += transversalVect * distStep / 2.0;
			const sDistanceIn in(pointNext, 0, false);
			sDistanceOut out;
			const double dist = CalculateDistance(params, fractals, in, &out);
			const double newDistStep = dist * detail * 0.5;
			if (newDistStep < newDistStepMin || newDistStepMin == 0)
			{
				pointNextBest = pointNext;
				newDistStepMin = newDistStep;
			}
		}
		if (newDistStepMin > 1000) newDistStepMin = 1000;
		if (distStep != 0 && newDistStepMin > distStep) break;
		distStep = newDistStepMin;
		point = pointNextBest;
		// qDebug() << "pointNextBest" << pointNextBest.Debug();
		if (point.Length() > 1000000)
		{
			WriteLog("CalculateDistanceMinPlane(): surface not found!", 1);
			return 0;
		}
		gApplication->processEvents();
		if (*stopRequest)
		{
			return 0;
		}
	}
	return CVector3(point - planePoint).Dot(direction);
}
CVector3 cRenderWorker::NormalMapShader(const sShaderInputData &input)
{
	cObjectData objectData = data->objectData[input.objectId];
	CVector3 texX, texY;
	double texturePixelSize = 1.0;
	CVector2<double> texPoint =
		TextureMapping(input.point, input.normal, objectData, input.material, &texX, &texY)
		+ CVector2<double>(0.5, 0.5);

	// mipmapping - calculation of texture pixel size
	double delta = CalcDelta(input.point);
	double deltaTexX =
		((TextureMapping(input.point + texX * delta, input.normal, objectData, input.material)
			 + CVector2<double>(0.5, 0.5))
			- texPoint)
			.Length();
	double deltaTexY =
		((TextureMapping(input.point + texY * delta, input.normal, objectData, input.material)
			 + CVector2<double>(0.5, 0.5))
			- texPoint)
			.Length();
	deltaTexX = deltaTexX / fabs(input.viewVector.Dot(input.normal));
	deltaTexY = deltaTexY / fabs(input.viewVector.Dot(input.normal));
	texturePixelSize = 1.0 / max(deltaTexX, deltaTexY);

	CVector3 n = input.normal;
	// tangent vectors:
	CVector3 t = n.Cross(texX);
	t.Normalize();
	CVector3 b = n.Cross(texY);
	b.Normalize();
	CMatrix33 tbn(b, t, n);

	CVector3 tex;

	if (input.material->normalMapTextureFromBumpmap)
	{
		tex = input.material->normalMapTexture.NormalMapFromBumpMap(
			texPoint, input.material->normalMapTextureHeight, texturePixelSize);
	}
	else
	{
		tex = input.material->normalMapTexture.NormalMap(
			texPoint, input.material->normalMapTextureHeight, texturePixelSize);
	}

	CVector3 result = tbn * tex;
	result.Normalize();
	return result;
}
Beispiel #4
0
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CMatrix
//
//  - prototype : void RemoveScale()
//
//  - Purpose   : Removes matrix's scale values.
//
// -----------------------------------------------------------------------------
void CMatrix::RemoveScale()
{
	CVector3 xAxis = XAxis();
	CVector3 yAxis = YAxis();
	CVector3 zAxis = ZAxis();

	xAxis.Normalize();
	yAxis.Normalize();
	zAxis.Normalize();

	SetXAxis(xAxis);
	SetYAxis(yAxis);
	SetZAxis(zAxis);
}
Beispiel #5
0
void CBuzzControllerSpiri::SetDirection(const CVector3& c_heading) {
   CVector3 cDir = c_heading;
   if(cDir.SquareLength() > 0.01f) {
      cDir.Normalize();
      cDir *= 0.01;
   }
   m_pcPropellers->SetRelativePosition(cDir);
}
void game_physics_engine::CParticalDrag::UpdateForce( CPartical* pPartical, const real duration )
{
	CVector3 force = pPartical->GetVelocity();
	real dragCoeff = force.Magnitude();
	dragCoeff = m_k1 * dragCoeff + m_k2 * dragCoeff * dragCoeff;
	force.Normalize();
	force *= -dragCoeff;
	pPartical->AddForce(force);
}
Beispiel #7
0
void
Moose::Math::CPlane::Calculate( CVector3<float> vNormal, const CVector3<float> & vPoint )
{
  vNormal.Normalize();
  m_aValues[0] =  vNormal[0];
  m_aValues[1] =  vNormal[1];
  m_aValues[2] =  vNormal[2];
  m_aValues[3] = -(vNormal.Dot(vPoint));
}
Beispiel #8
0
sRGBAfloat cRenderWorker::MainSpecular(const sShaderInputData &input)
{
	sRGBAfloat specular;
	CVector3 half = input.lightVect - input.viewVector;
	half.Normalize();
	double shade2 = input.normal.Dot(half);
	if (shade2 < 0.0) shade2 = 0.0;
	shade2 = pow(shade2, 30.0) * 1.0;
	if (shade2 > 15.0) shade2 = 15.0;
	specular.R = shade2;
	specular.G = shade2;
	specular.B = shade2;
	return specular;
}
void game_physics_engine::CParticalAnchoredSpring::UpdateForce( CPartical* pOther, real fDuration )
{
	CVector3 force;
	force = pOther->GetPosition();
	force -= *m_pAnchor;

	real fMagnitude = force.Magnitude();
	//that is what written on the book, but I think it is wrong.
	//fMagnitude = real_abs(fMagnitude - m_fRestLength);
	fMagnitude = m_fRestLength - fMagnitude;
	fMagnitude *= m_fSpringConstant;

	force.Normalize();
	force *= -fMagnitude;
	pOther->AddForce(force);
}
sRGBAfloat cRenderWorker::MainSpecular(const sShaderInputData &input)
{
	sRGBAfloat specular;
	CVector3 half = input.lightVect - input.viewVector;
	half.Normalize();
	double shade2 = input.normal.Dot(half);
	if (shade2 < 0.0) shade2 = 0.0;
	double diffuse =
		10.0 * (1.1
						 - input.material->diffussionTextureIntensity
								 * (input.texDiffuse.R + input.texDiffuse.G + input.texDiffuse.B) / 3.0);
	shade2 = pow(shade2, 30.0 / input.material->specularWidth / diffuse) / diffuse;
	if (shade2 > 15.0) shade2 = 15.0;
	specular.R =
		shade2 * input.material->specularColor.R / 65536.0 * (input.texDiffuse.R * 0.5 + 0.5);
	specular.G =
		shade2 * input.material->specularColor.G / 65536.0 * (input.texDiffuse.G * 0.5 + 0.5);
	specular.B =
		shade2 * input.material->specularColor.B / 65536.0 * (input.texDiffuse.B * 0.5 + 0.5);
	return specular;
}
void game_physics_engine::CParticalBungee::UpdateForce( CPartical* pPartical, const real duration )
{
	assert(pPartical != nullptr);
	if (pPartical == NULL)
	{
		return;
	}

	CVector3 force = pPartical->GetPosition();
	force -= m_pOther->GetPosition();
	real magnitude = force.Magnitude();
	if (magnitude <= m_fRestLength)
	{
		return;
	}

	magnitude -= m_fRestLength;
	magnitude *= m_fSpringConstant;
	force.Normalize();
	force *= -magnitude;
	pPartical->AddForce(force);
}
Beispiel #12
0
CVector3 cTexture::NormalMapFromBumpMap(CVector2<double> point, double bump, double pixelSize) const
{
	int intX = point.x;
	int intY = point.y;
	point.x = point.x - intX;
	point.y = point.y - intY;
	if(point.x < 0.0) point.x += 1.0;
	if(point.y < 0.0) point.y += 1.0;

	double m[3][3];
	for(int y = 0; y<=2; y++)
	{
		for(int x = 0; x<=2; x++)
		{
			m[x][y] = MipMap(point.x*width + x - 1.0, point.y*height + y - 1.0, pixelSize).R;
		}
	}
	CVector3 normal;
	normal.x = bump * (m[2][2]-m[0][2]+2*(m[2][1]-m[0][1])+m[2][0]-m[0][0]);
	normal.y = bump * (m[0][0]-m[0][2]+2*(m[1][0]-m[1][2])+m[2][0]-m[2][2]);
	normal.z = 1.0;
	normal.Normalize();
	return normal;
}
Beispiel #13
0
void Main()
{
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	
	glColor3f(1.0f, 1.0f, 1.0f);
	APP->Print(.7f, .9f, "FPS: %4.2f", APP->GetFPS());
	APP->Print(.7f, .8f, "Cubes: %d", vCubes.size());
	APP->Print(.7f, .7f, "Active: %d", i_ActiveCube);
	APP->Print(-1.f, .9f, "Position: %.2lf %.2lf %.2lf", g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z);
	APP->Print(-1.f, .8f, "View: %.2lf %.2lf %.2lf", g_Camera.m_vView.x, g_Camera.m_vView.y, g_Camera.m_vView.z);
	APP->Print(-1.f, .7f, "Up: %.2lf %.2lf %.2lf", g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z);

	APP->Print(-1.f, .6f, "CameraRot: %.2lf", g_Camera.curRotY);
	if (APP->GetSet()->network)
		APP->Print(-1.f, .5f, "IP: %s", APP->GetSet()->ip_server);
	else
		APP->Print(-1.f, .5f, "IP: no");

	glLoadIdentity();

	EventKeysDown();

	if (i_ActiveCube >= 0 && i_ActiveCube < (int)vCubes.size())
	{
		if (changeActiveCube)
		{
			CVector3 vec = vCubes[i_ActiveCube]->GetCenter() - g_Camera.m_vView;

			float angle = vCubes[i_ActiveCube]->angleRotY - g_Camera.curRotY;
			if (g_Camera.curRotY > 0.0f && vCubes[i_ActiveCube]->angleRotY < 0.0f)
			{
				angle = minAbs(angle, 2.0f * Pi + vCubes[i_ActiveCube]->angleRotY - g_Camera.curRotY);
			}
			else if (g_Camera.curRotY < 0.0f && vCubes[i_ActiveCube]->angleRotY > 0.0f)
			{
				angle = minAbs(angle, -2.0f * Pi + vCubes[i_ActiveCube]->angleRotY - g_Camera.curRotY);
			}

			if (vec.Magnitude() <= 2.0f * MOVEMENT_SPEED)
			{
				if (abs(angle) <= MOVEMENT_ANGLE)
				{
					g_Camera.m_vView = vCubes[i_ActiveCube]->GetCenter();
					g_Camera.RotateAroundPoint(g_Camera.m_vView, angle, 0.0f, 1.0f, 0.0f);
					changeActiveCube = false;
				}
				else
				{
					if (angle > 0)
						g_Camera.RotateAroundPoint(g_Camera.m_vView, MOVEMENT_ANGLE, 0.0f, 1.0f, 0.0f);
					else
						g_Camera.RotateAroundPoint(g_Camera.m_vView, -MOVEMENT_ANGLE, 0.0f, 1.0f, 0.0f);
				}
			}
			else
			{
				float k = vec.Magnitude() / (2.0f * MOVEMENT_SPEED);

				if (k > 0.1f)
					g_Camera.RotateAroundPoint(g_Camera.m_vView, angle / k, 0.0f, 1.0f, 0.0f);

				vec.Normalize();
				vec *= 2.0f * MOVEMENT_SPEED;
				g_Camera.m_vView += vec;
				g_Camera.m_vPosition += vec;
			}
		}
		else
		{
			g_Camera.SetViewByMouse();

			vCubes[i_ActiveCube]->Set(g_Camera.m_vView.x, 0.0f, g_Camera.m_vView.z);
			vCubes[i_ActiveCube]->angleRotY = g_Camera.curRotY;
		}
	}

	gluLookAt(g_Camera.m_vPosition.x, g_Camera.m_vPosition.y, g_Camera.m_vPosition.z,
		g_Camera.m_vView.x,	  g_Camera.m_vView.y,	  g_Camera.m_vView.z,
		g_Camera.m_vUpVector.x, g_Camera.m_vUpVector.y, g_Camera.m_vUpVector.z);

	for (size_t i = 0; i < vCubes.size(); i++)
	{
		vCubes[i]->Render();
	}
}
sRGBAfloat cRenderWorker::VolumetricShader(
	const sShaderInputData &input, sRGBAfloat oldPixel, sRGBAfloat *opacityOut)
{
	sRGBAfloat output;
	float totalOpacity = 0.0;

	output.R = oldPixel.R;
	output.G = oldPixel.G;
	output.B = oldPixel.B;
	output.A = oldPixel.A;

	// volumetric fog init
	double colourThresh = params->volFogColour1Distance;
	double colourThresh2 = params->volFogColour2Distance;
	double fogReduce = params->volFogDistanceFactor;
	double fogIntensity = params->volFogDensity;

	// visible lights init
	int numberOfLights = data->lights.GetNumberOfLights();
	if (numberOfLights < 4) numberOfLights = 4;

	// glow init
	double glow = input.stepCount * params->glowIntensity / 512.0 * params->DEFactor;
	double glowN = 1.0 - glow;
	if (glowN < 0.0) glowN = 0.0;
	double glowR = (params->glowColor1.R * glowN + params->glowColor2.R * glow) / 65536.0;
	double glowG = (params->glowColor1.G * glowN + params->glowColor2.G * glow) / 65536.0;
	double glowB = (params->glowColor1.B * glowN + params->glowColor2.B * glow) / 65536.0;

	double totalStep = 0.0;

	// qDebug() << "Start volumetric shader &&&&&&&&&&&&&&&&&&&&";

	sShaderInputData input2 = input;
	for (int index = input.stepCount - 1; index > 0; index--)
	{
		double step = input.stepBuff[index].step;
		double distance = input.stepBuff[index].distance;
		CVector3 point = input.stepBuff[index].point;
		totalStep += step;

		input2.point = point;
		input2.distThresh = input.stepBuff[index].distThresh;

		// qDebug() << "i" << index << "dist" << distance << "iters" << input.stepBuff[index].iters <<
		// "distThresh" << input2.distThresh << "step" << step << "point" << point.Debug();

		if (totalStep < CalcDelta(point))
		{
			continue;
		}
		step = totalStep;
		totalStep = 0.0;

		//------------------- glow
		if (params->glowEnabled)
		{
			double glowOpacity = glow / input.stepCount;
			if (glowOpacity > 1.0) glowOpacity = 1.0;
			output.R = glowOpacity * glowR + (1.0 - glowOpacity) * output.R;
			output.G = glowOpacity * glowG + (1.0 - glowOpacity) * output.G;
			output.B = glowOpacity * glowB + (1.0 - glowOpacity) * output.B;
			output.A += glowOpacity;
		}
		// qDebug() << "step" << step;
		//------------------ visible light
		if (params->auxLightVisibility > 0)
		{
			double miniStep = 0.0;
			double lastMiniSteps = -1.0;

			for (double miniSteps = 0.0; miniSteps < step; miniSteps += miniStep)
			{
				double lowestLightSize = 1e10;
				double lowestLightDist = 1e10;
				for (int i = 0; i < numberOfLights; ++i)
				{
					const cLights::sLight *light = data->lights.GetLight(i);
					if (light->enabled)
					{
						CVector3 lightDistVect = (point - input.viewVector * miniSteps) - light->position;
						double lightDist = lightDistVect.Length();
						double lightSize = sqrt(light->intensity) * params->auxLightVisibilitySize;
						double distToLightSurface = lightDist - lightSize;
						if (distToLightSurface < 0.0) distToLightSurface = 0.0;
						if (distToLightSurface <= lowestLightDist)
						{
							if (lightSize < lowestLightSize)
							{
								lowestLightSize = lightSize;
							}
							lowestLightDist = distToLightSurface;
						}
					}
				}

				miniStep = 0.1 * (lowestLightDist + 0.1 * lowestLightSize);
				if (miniStep > step - miniSteps) miniStep = step - miniSteps;
				// qDebug() << "lowDist:" << lowestLightDist << "lowSize" << lowestLightSize << "miniStep"
				// << miniStep;

				for (int i = 0; i < numberOfLights; ++i)
				{
					const cLights::sLight *light = data->lights.GetLight(i);
					if (light->enabled)
					{
						CVector3 lightDistVect = (point - input.viewVector * miniSteps) - light->position;
						double lightDist = lightDistVect.Length();
						double lightSize = sqrt(light->intensity) * params->auxLightVisibilitySize;
						double r2 = lightDist / lightSize;
						double bellFunction = 1.0 / (1.0 + pow(r2, 4.0));
						double lightDensity = miniStep * bellFunction * params->auxLightVisibility / lightSize;

						output.R += lightDensity * light->colour.R / 65536.0;
						output.G += lightDensity * light->colour.G / 65536.0;
						output.B += lightDensity * light->colour.B / 65536.0;
						output.A += lightDensity;
					}
				}
				if (miniSteps == lastMiniSteps)
				{
					// qWarning() << "Dead computation\n"
					//		<< "\npoint:" << (point - input.viewVector * miniSteps).Debug();
					break;
				}
				lastMiniSteps = miniSteps;
			}
		}

		// fake lights (orbit trap)
		if (params->fakeLightsEnabled)
		{
			sFractalIn fractIn(point, params->minN, params->N, params->common, -1);
			sFractalOut fractOut;
			Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut);
			double r = fractOut.orbitTrapR;
			r = sqrt(1.0f / (r + 1.0e-30f));
			double fakeLight = 1.0 / (pow(r, 10.0 / params->fakeLightsVisibilitySize)
																	 * pow(10.0, 10.0 / params->fakeLightsVisibilitySize)
																 + 1e-100);
			output.R += fakeLight * step * params->fakeLightsVisibility;
			output.G += fakeLight * step * params->fakeLightsVisibility;
			output.B += fakeLight * step * params->fakeLightsVisibility;
			output.A += fakeLight * step * params->fakeLightsVisibility;
		}

		//---------------------- volumetric lights with shadows in fog

		for (int i = 0; i < 5; i++)
		{
			if (i == 0 && params->volumetricLightEnabled[0])
			{
				sRGBAfloat shadowOutputTemp = MainShadow(input2);
				output.R += shadowOutputTemp.R * step * params->volumetricLightIntensity[0]
										* params->mainLightColour.R / 65536.0;
				output.G += shadowOutputTemp.G * step * params->volumetricLightIntensity[0]
										* params->mainLightColour.G / 65536.0;
				output.B += shadowOutputTemp.B * step * params->volumetricLightIntensity[0]
										* params->mainLightColour.B / 65536.0;
				output.A += (shadowOutputTemp.R + shadowOutputTemp.G + shadowOutputTemp.B) / 3.0 * step
										* params->volumetricLightIntensity[0];
			}
			if (i > 0)
			{
				const cLights::sLight *light = data->lights.GetLight(i - 1);
				if (light->enabled && params->volumetricLightEnabled[i])
				{
					CVector3 lightVectorTemp = light->position - point;
					double distanceLight = lightVectorTemp.Length();
					double distanceLight2 = distanceLight * distanceLight;
					lightVectorTemp.Normalize();
					double lightShadow = AuxShadow(input2, distanceLight, lightVectorTemp);
					output.R += lightShadow * light->colour.R / 65536.0 * params->volumetricLightIntensity[i]
											* step / distanceLight2;
					output.G += lightShadow * light->colour.G / 65536.0 * params->volumetricLightIntensity[i]
											* step / distanceLight2;
					output.B += lightShadow * light->colour.B / 65536.0 * params->volumetricLightIntensity[i]
											* step / distanceLight2;
					output.A += lightShadow * params->volumetricLightIntensity[i] * step / distanceLight2;
				}
			}
		}

		//----------------------- basic fog
		if (params->fogEnabled)
		{
			double fogDensity = step / params->fogVisibility;
			if (fogDensity > 1.0) fogDensity = 1.0;
			output.R = fogDensity * params->fogColor.R / 65536.0 + (1.0 - fogDensity) * output.R;
			output.G = fogDensity * params->fogColor.G / 65536.0 + (1.0 - fogDensity) * output.G;
			output.B = fogDensity * params->fogColor.B / 65536.0 + (1.0 - fogDensity) * output.B;
			totalOpacity = fogDensity + (1.0 - fogDensity) * totalOpacity;
			output.A = fogDensity + (1.0 - fogDensity) * output.A;
		}

		//-------------------- volumetric fog
		if (fogIntensity > 0.0 && params->volFogEnabled)
		{
			double densityTemp = (step * fogReduce) / (distance * distance + fogReduce * fogReduce);

			double k = distance / colourThresh;
			if (k > 1) k = 1.0;
			double kn = 1.0 - k;
			double fogRtemp = (params->volFogColour1.R * kn + params->volFogColour2.R * k);
			double fogGtemp = (params->volFogColour1.G * kn + params->volFogColour2.G * k);
			double fogBtemp = (params->volFogColour1.B * kn + params->volFogColour2.B * k);

			double k2 = distance / colourThresh2 * k;
			if (k2 > 1) k2 = 1.0;
			kn = 1.0 - k2;
			fogRtemp = (fogRtemp * kn + params->volFogColour3.R * k2);
			fogGtemp = (fogGtemp * kn + params->volFogColour3.G * k2);
			fogBtemp = (fogBtemp * kn + params->volFogColour3.B * k2);

			double fogDensity = 0.3 * fogIntensity * densityTemp / (1.0 + fogIntensity * densityTemp);
			if (fogDensity > 1) fogDensity = 1.0;

			output.R = fogDensity * fogRtemp / 65536.0 + (1.0 - fogDensity) * output.R;
			output.G = fogDensity * fogGtemp / 65536.0 + (1.0 - fogDensity) * output.G;
			output.B = fogDensity * fogBtemp / 65536.0 + (1.0 - fogDensity) * output.B;
			// qDebug() << "densityTemp " << densityTemp << "k" << k << "k2" << k2 << "fogTempR" <<
			// fogRtemp << "fogDensity" << fogDensity << "output.R" << output.R;

			totalOpacity = fogDensity + (1.0 - fogDensity) * totalOpacity;
			output.A = fogDensity + (1.0 - fogDensity) * output.A;
		}

		// iter fog
		if (params->iterFogEnabled)
		{
			int L = input.stepBuff[index].iters;
			double opacity =
				IterOpacity(step, L, params->N, params->iterFogOpacityTrim, params->iterFogOpacity);

			sRGBAfloat newColour(0.0, 0.0, 0.0, 0.0);
			if (opacity > 0)
			{
				// fog colour
				double iterFactor1 = (L - params->iterFogOpacityTrim)
														 / (params->iterFogColor1Maxiter - params->iterFogOpacityTrim);
				double k = iterFactor1;
				if (k > 1.0) k = 1.0;
				if (k < 0.0) k = 0.0;
				double kn = 1.0 - k;
				double fogColR = (params->iterFogColour1.R * kn + params->iterFogColour2.R * k);
				double fogColG = (params->iterFogColour1.G * kn + params->iterFogColour2.G * k);
				double fogColB = (params->iterFogColour1.B * kn + params->iterFogColour2.B * k);

				double iterFactor2 = (L - params->iterFogColor1Maxiter)
														 / (params->iterFogColor2Maxiter - params->iterFogColor1Maxiter);
				double k2 = iterFactor2;
				if (k2 < 0.0) k2 = 0.0;
				if (k2 > 1.0) k2 = 1.0;
				kn = 1.0 - k2;
				fogColR = (fogColR * kn + params->iterFogColour3.R * k2);
				fogColG = (fogColG * kn + params->iterFogColour3.G * k2);
				fogColB = (fogColB * kn + params->iterFogColour3.B * k2);
				//----

				for (int i = 0; i < 5; i++)
				{
					if (i == 0)
					{
						if (params->mainLightEnable && params->mainLightIntensity > 0.0)
						{
							sRGBAfloat shadowOutputTemp = MainShadow(input2);
							newColour.R += shadowOutputTemp.R * params->mainLightColour.R / 65536.0
														 * params->mainLightIntensity;
							newColour.G += shadowOutputTemp.G * params->mainLightColour.G / 65536.0
														 * params->mainLightIntensity;
							newColour.B += shadowOutputTemp.B * params->mainLightColour.B / 65536.0
														 * params->mainLightIntensity;
						}
					}

					if (i > 0)
					{
						const cLights::sLight *light = data->lights.GetLight(i - 1);
						if (light->enabled)
						{
							CVector3 lightVectorTemp = light->position - point;
							double distanceLight = lightVectorTemp.Length();
							double distanceLight2 = distanceLight * distanceLight;
							lightVectorTemp.Normalize();
							double lightShadow = AuxShadow(input2, distanceLight, lightVectorTemp);
							double intensity = light->intensity * 100.0;
							newColour.R += lightShadow * light->colour.R / 65536.0 / distanceLight2 * intensity;
							newColour.G += lightShadow * light->colour.G / 65536.0 / distanceLight2 * intensity;
							newColour.B += lightShadow * light->colour.B / 65536.0 / distanceLight2 * intensity;
						}
					}
				}

				if (params->ambientOcclusionEnabled
						&& params->ambientOcclusionMode == params::AOmodeMultipeRays)
				{
					sRGBAfloat AO = AmbientOcclusion(input2);
					newColour.R += AO.R * params->ambientOcclusion;
					newColour.G += AO.G * params->ambientOcclusion;
					newColour.B += AO.B * params->ambientOcclusion;
				}

				if (opacity > 1.0) opacity = 1.0;

				output.R = output.R * (1.0 - opacity) + newColour.R * opacity * fogColR / 65536.0;
				output.G = output.G * (1.0 - opacity) + newColour.G * opacity * fogColG / 65536.0;
				output.B = output.B * (1.0 - opacity) + newColour.B * opacity * fogColB / 65536.0;
				totalOpacity = opacity + (1.0 - opacity) * totalOpacity;
				output.A = opacity + (1.0 - opacity) * output.A;
			}
		}

		if (totalOpacity > 1.0) totalOpacity = 1.0;
		if (output.A > 1.0) output.A = 1.0;
		(*opacityOut).R = totalOpacity;
		(*opacityOut).G = totalOpacity;
		(*opacityOut).B = totalOpacity;

	} // next stepCount

	return output;
}
sRGBAfloat cRenderWorker::BackgroundShader(const sShaderInputData &input)
{
	sRGBAfloat pixel2;

	if (params->texturedBackground)
	{
		switch (params->texturedBackgroundMapType)
		{
			case params::mapDoubleHemisphere:
			{
				double alphaTexture = input.viewVector.GetAlpha();
				double betaTexture = input.viewVector.GetBeta();
				int texWidth = data->textures.backgroundTexture.Width() * 0.5;
				int texHeight = data->textures.backgroundTexture.Height();
				int offset = 0;

				if (betaTexture < 0)
				{
					betaTexture = -betaTexture;
					alphaTexture = M_PI - alphaTexture;
					offset = texWidth;
				}
				double texX = 0.5 * texWidth
											+ cos(alphaTexture) * (1.0 - betaTexture / (0.5 * M_PI)) * texWidth * 0.5
											+ offset;
				double texY = 0.5 * texHeight
											+ sin(alphaTexture) * (1.0 - betaTexture / (0.5 * M_PI)) * texHeight * 0.5;
				sRGBfloat pixel = data->textures.backgroundTexture.Pixel(texX, texY);
				pixel2.R = pixel.R;
				pixel2.G = pixel.G;
				pixel2.B = pixel.B;
				break;
			}
			case params::mapEquirectangular:
			{
				double alphaTexture = fmod(-input.viewVector.GetAlpha() + 3.5 * M_PI, 2 * M_PI);
				double betaTexture = -input.viewVector.GetBeta();
				if (betaTexture > 0.5 * M_PI) betaTexture = 0.5 * M_PI - betaTexture;
				if (betaTexture < -0.5 * M_PI) betaTexture = -0.5 * M_PI + betaTexture;
				double texX = alphaTexture / (2.0 * M_PI) * data->textures.backgroundTexture.Width();
				double texY = (betaTexture / (M_PI) + 0.5) * data->textures.backgroundTexture.Height();
				sRGBfloat pixel = data->textures.backgroundTexture.Pixel(texX, texY);
				pixel2.R = pixel.R;
				pixel2.G = pixel.G;
				pixel2.B = pixel.B;
				break;
			}
			case params::mapFlat:
			{
				CVector3 vect = mRotInv.RotateVector(input.viewVector);

				double texX = vect.x / vect.y / params->fov * params->imageHeight / params->imageWidth;
				double texY = -vect.z / vect.y / params->fov;
				texX = (texX + 0.5);
				texY = (texY + 0.5);

				sRGBfloat pixel = data->textures.backgroundTexture.Pixel(CVector2<double>(texX, texY));
				pixel2.R = pixel.R;
				pixel2.G = pixel.G;
				pixel2.B = pixel.B;
				break;
			}
		}
		pixel2.R *= params->background_brightness;
		pixel2.G *= params->background_brightness;
		pixel2.B *= params->background_brightness;
	}
	else
	{
		CVector3 vector(0.0, 0.0, 1.0);
		vector.Normalize();
		CVector3 viewVectorNorm = input.viewVector;
		viewVectorNorm.Normalize();
		double grad = (viewVectorNorm.Dot(vector) + 1.0);
		sRGB16 pixel;
		if (grad < 1)
		{
			double Ngrad = 1.0 - grad;
			pixel.R = (params->background_color3.R * Ngrad + params->background_color2.R * grad);
			pixel.G = (params->background_color3.G * Ngrad + params->background_color2.G * grad);
			pixel.B = (params->background_color3.B * Ngrad + params->background_color2.B * grad);
		}
		else
		{
			grad = grad - 1;
			double Ngrad = 1.0 - grad;
			pixel.R = (params->background_color2.R * Ngrad + params->background_color1.R * grad);
			pixel.G = (params->background_color2.G * Ngrad + params->background_color1.G * grad);
			pixel.B = (params->background_color2.B * Ngrad + params->background_color1.B * grad);
		}

		pixel2.R = pixel.R / 65536.0;
		pixel2.G = pixel.G / 65536.0;
		pixel2.B = pixel.B / 65536.0;
		pixel2.A = 0.0;
	}

	CVector3 viewVectorNorm = input.viewVector;
	viewVectorNorm.Normalize();
	double light =
		(viewVectorNorm.Dot(input.lightVect) - 1.0) * 360.0 / params->mainLightVisibilitySize;
	light = 1.0 / (1.0 + pow(light, 6.0)) * params->mainLightVisibility * params->mainLightIntensity;
	pixel2.R += light * params->mainLightColour.R / 65536.0;
	pixel2.G += light * params->mainLightColour.G / 65536.0;
	pixel2.B += light * params->mainLightColour.B / 65536.0;

	return pixel2;
}
CVector2<double> TextureMapping(CVector3 inPoint, CVector3 normalVector,
	const cObjectData &objectData, const cMaterial *material, CVector3 *textureVectorX,
	CVector3 *textureVectorY)
{
	CVector2<double> textureCoordinates;
	CVector3 point = inPoint - objectData.position;
	point = objectData.rotationMatrix.RotateVector(point);
	point /= objectData.size;
	point = material->rotMatrix.RotateVector(point);

	switch (material->textureMappingType)
	{
		case cMaterial::mappingPlanar:
		{
			textureCoordinates = CVector2<double>(point.x, point.y);
			textureCoordinates.x /= -material->textureScale.x;
			textureCoordinates.y /= material->textureScale.y;
			textureCoordinates.x -= material->textureCenter.x;
			textureCoordinates.y -= material->textureCenter.y;

			if (textureVectorX && textureVectorY)
			{
				CVector3 texX(1.0, 0.0, 0.0);
				texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
				texX = material->rotMatrix.Transpose().RotateVector(texX);
				*textureVectorX = texX;

				CVector3 texY(0.0, -1.0, 0.0);
				texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
				texY = material->rotMatrix.Transpose().RotateVector(texY);
				*textureVectorY = texY;
			}
			break;
		}
		case cMaterial::mappingCylindrical:
		{
			double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI);
			textureCoordinates.x = alphaTexture / (2.0 * M_PI);
			textureCoordinates.y = -point.z;
			textureCoordinates.x /= material->textureScale.x;
			textureCoordinates.y /= material->textureScale.y;
			textureCoordinates.x -= material->textureCenter.x;
			textureCoordinates.y -= material->textureCenter.y;

			if (textureVectorX && textureVectorY)
			{
				CVector3 texY(0.0, 0.0, 1.0);
				CVector3 texX = point.Cross(texY);
				texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
				texX = material->rotMatrix.Transpose().RotateVector(texX);
				*textureVectorX = texX;
				texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
				texY = material->rotMatrix.Transpose().RotateVector(texY);
				*textureVectorY = texY;
			}

			break;
		}
		case cMaterial::mappingSpherical:
		{
			double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI);
			double betaTexture = -point.GetBeta();
			textureCoordinates.x = alphaTexture / (2.0 * M_PI);
			textureCoordinates.y = (betaTexture / M_PI);
			textureCoordinates.x /= material->textureScale.x;
			textureCoordinates.y /= material->textureScale.y;
			textureCoordinates.x -= material->textureCenter.x;
			textureCoordinates.y -= material->textureCenter.y;

			CVector3 texY(0.0, 0.0, -1.0);
			CVector3 texX = texY.Cross(point);
			texX.Normalize();
			texY = texX.Cross(point);

			if (textureVectorX && textureVectorY)
			{
				texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
				texX = material->rotMatrix.Transpose().RotateVector(texX);
				*textureVectorX = texX;
				texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
				texY = material->rotMatrix.Transpose().RotateVector(texY);
				*textureVectorY = texY;
			}

			break;
		}
		case cMaterial::mappingCubic:
		{
			point /= material->textureScale;
			point -= material->textureCenter;

			CVector3 texX, texY;
			if (fabs(normalVector.x) > fabs(normalVector.y))
			{
				if (fabs(normalVector.x) > fabs(normalVector.z))
				{
					// x
					if (normalVector.x > 0)
						textureCoordinates = CVector2<double>(point.y, -point.z);
					else
						textureCoordinates = CVector2<double>(-point.y, -point.z);

					if (textureVectorX && textureVectorY)
					{
						if (normalVector.x > 0)
						{
							texX = CVector3(0.0, -1.0, 0.0);
							texY = CVector3(0.0, 0.0, 1.0);
						}
						else
						{
							texX = CVector3(0.0, 1.0, 0.0);
							texY = CVector3(0.0, 0.0, 1.0);
						}
					}
				}
				else
				{
					// z
					if (normalVector.z > 0)
						textureCoordinates = CVector2<double>(-point.x, point.y);
					else
						textureCoordinates = CVector2<double>(point.x, point.y);

					if (textureVectorX && textureVectorY)
					{
						if (normalVector.z > 0)
						{
							texX = CVector3(1.0, 0.0, 0.0);
							texY = CVector3(0.0, -1.0, 0.0);
						}
						else
						{
							texX = CVector3(-1.0, 0.0, 0.0);
							texY = CVector3(0.0, -1.0, 0.0);
						}
					}
				}
			}
			else
			{
				if (fabs(normalVector.y) > fabs(normalVector.z))
				{
					// y
					if (normalVector.y > 0)
						textureCoordinates = CVector2<double>(-point.x, -point.z);
					else
						textureCoordinates = CVector2<double>(point.x, -point.z);

					if (textureVectorX && textureVectorY)
					{
						if (normalVector.y > 0)
						{
							texX = CVector3(1.0, 0.0, 0.0);
							texY = CVector3(0.0, 0.0, 1.0);
						}
						else
						{
							texX = CVector3(-1.0, 0.0, 0.0);
							texY = CVector3(0.0, 0.0, 1.0);
						}
					}
				}
				else
				{
					// z
					if (normalVector.z > 0)
						textureCoordinates = CVector2<double>(-point.x, point.y);
					else
						textureCoordinates = CVector2<double>(point.x, point.y);

					if (textureVectorX && textureVectorY)
					{
						if (normalVector.z > 0)
						{
							texX = CVector3(1.0, 0.0, 0.0);
							texY = CVector3(0.0, -1.0, 0.0);
						}
						else
						{
							texX = CVector3(-1.0, 0.0, 0.0);
							texY = CVector3(0.0, -1.0, 0.0);
						}
					}
				}
			}

			if (textureVectorX && textureVectorY)
			{
				texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
				texX = material->rotMatrix.Transpose().RotateVector(texX);
				*textureVectorX = texX;
				texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
				texY = material->rotMatrix.Transpose().RotateVector(texY);
				*textureVectorY = texY;
			}

			break;
		}
	}
	return textureCoordinates;
}
// will be done later
sRGBAfloat cRenderWorker::FakeLights(const sShaderInputData &input, sRGBAfloat *fakeSpec)
{
	sRGBAfloat fakeLights;

	double delta = input.distThresh * params->smoothness;

	sFractalIn fractIn(input.point, params->minN, params->N, params->common, -1);
	sFractalOut fractOut;
	Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut);
	double rr = fractOut.orbitTrapR;

	double fakeLight = params->fakeLightsIntensity / rr;
	double r = 1.0 / (rr + 1e-30);

	CVector3 deltax(delta, 0.0, 0.0);
	CVector3 deltay(0.0, delta, 0.0);
	CVector3 deltaz(0.0, 0.0, delta);

	fractIn.point = input.point + deltax;
	Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut);
	double rx = 1.0 / (fractOut.orbitTrapR + 1e-30);

	fractIn.point = input.point + deltay;
	Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut);
	double ry = 1.0 / (fractOut.orbitTrapR + 1e-30);

	fractIn.point = input.point + deltaz;
	Compute<fractal::calcModeOrbitTrap>(*fractal, fractIn, &fractOut);
	double rz = 1.0 / (fractOut.orbitTrapR + 1e-30);

	CVector3 fakeLightNormal;
	fakeLightNormal.x = r - rx;
	fakeLightNormal.y = r - ry;
	fakeLightNormal.z = r - rz;

	if (fakeLightNormal.x == 0 && fakeLightNormal.y == 0 && fakeLightNormal.z == 0)
	{
		fakeLightNormal.x = 0.0;
	}
	else
	{
		fakeLightNormal.Normalize();
	}
	double fakeLight2 = fakeLight * input.normal.Dot(fakeLightNormal);
	if (fakeLight2 < 0) fakeLight2 = 0;

	fakeLights.R = fakeLight2;
	fakeLights.G = fakeLight2;
	fakeLights.B = fakeLight2;

	CVector3 half = fakeLightNormal - input.viewVector;
	half.Normalize();
	double fakeSpecular = input.normal.Dot(half);
	if (fakeSpecular < 0.0) fakeSpecular = 0.0;
	double diffuse =
		10.0 * (1.1
						 - input.material->diffussionTextureIntensity
								 * (input.texDiffuse.R + input.texDiffuse.G + input.texDiffuse.B) / 3.0);
	fakeSpecular = pow(fakeSpecular, 30.0 / input.material->specularWidth / diffuse) / diffuse;
	if (fakeSpecular > 15.0) fakeSpecular = 15.0;
	fakeSpec->R = fakeSpecular;
	fakeSpec->G = fakeSpecular;
	fakeSpec->B = fakeSpecular;

	*fakeSpec = sRGBAfloat();
	return fakeLights;
}
sRGBAfloat cRenderWorker::LightShading(
	const sShaderInputData &input, const cLights::sLight *light, int number, sRGBAfloat *outSpecular)
{
	sRGBAfloat shading;

	CVector3 d = light->position - input.point;

	double distance = d.Length();

	// angle of incidence
	CVector3 lightVector = d;
	lightVector.Normalize();

	double intensity = 100.0 * light->intensity / (distance * distance) / number;
	double shade = input.normal.Dot(lightVector);
	if (shade < 0) shade = 0;
	shade = (1.0 - input.material->shading) + shade * input.material->shading;

	shade = shade * intensity;
	if (shade > 500.0) shade = 500.0;

	// specular
	CVector3 half = lightVector - input.viewVector;
	half.Normalize();
	double shade2 = input.normal.Dot(half);
	if (shade2 < 0.0) shade2 = 0.0;

	double diffuse =
		10.0 * (1.1
						 - input.material->diffussionTextureIntensity
								 * (input.texDiffuse.R + input.texDiffuse.G + input.texDiffuse.B) / 3.0);

	shade2 = pow(shade2, 30.0 / input.material->specularWidth / diffuse) / diffuse;
	shade2 *= intensity * input.material->specular;
	if (shade2 > 15.0) shade2 = 15.0;

	// calculate shadow
	if ((shade > 0.01 || shade2 > 0.01) && params->shadow)
	{
		double auxShadow = AuxShadow(input, distance, lightVector);
		shade *= auxShadow;
		shade2 *= auxShadow;
	}
	else
	{
		if (params->shadow)
		{
			shade = 0;
			shade2 = 0;
		}
	}

	shading.R = shade * light->colour.R / 65536.0;
	shading.G = shade * light->colour.G / 65536.0;
	shading.B = shade * light->colour.B / 65536.0;

	outSpecular->R = shade2 * light->colour.R / 65536.0;
	outSpecular->G = shade2 * light->colour.G / 65536.0;
	outSpecular->B = shade2 * light->colour.B / 65536.0;

	return shading;
}
/*!
* @brief	衝突検出と解決。
*@param[in]	nextPosition		次の座標。
*/
void EnemyTest::CollisionDetectAndResolve(CVector3 nextPosition)
{
	//XZ平面を調べる。
	{
		int loopCount = 0;
		while (true) {
			CVector3 addPos;
			addPos.Subtract(nextPosition, position);
			CVector3 posTmp = position;
			posTmp.y += radius + 0.2f;
			btTransform start, end;
			start.setIdentity();
			end.setIdentity();
			start.setOrigin(*(btVector3*)(&posTmp));
			CVector3 newPos;
			SweepResultWall callback;
			callback.startPos = position;
			CVector3 addPosXZ = addPos;
			addPosXZ.y = 0.0f;
			if (addPosXZ.Length() > 0.0001f) {
				newPos.Add(posTmp, addPosXZ);
				end.setOrigin(btVector3(newPos.x, newPos.y, newPos.z));

				PhysicsWorld().ConvexSweepTest((const btConvexShape*)collider.GetBody(), start, end, callback);
			}
			if (callback.isHit) {
				//当たった。
				float t = fabsf(acosf(callback.hitNormal.Dot(CVector3::Up)));
				if (t >= CMath::PI * 0.3f) {
					//壁。
					nextPosition.x = callback.hitPos.x;
					nextPosition.z = callback.hitPos.z;
					//半径分押し戻す。
					CVector3 hitNormalXZ = callback.hitNormal;
					hitNormalXZ.y = 0.0f;
					hitNormalXZ.Normalize();
					CVector3 t = hitNormalXZ;
					t.Scale(radius);
					nextPosition.Add(t);
					//続いて壁に沿って滑らせる。
					t.Cross(hitNormalXZ, CVector3::Up);
					t.Normalize();
					//押し戻しで動いた分は減算する。
					CVector3 t2;
					t2.Subtract(nextPosition, position);
					t2.y = 0.0f;
					addPosXZ.Subtract(t2);
					t.Scale(t.Dot(addPosXZ));
					nextPosition.Add(t);
				}
			}
			else {
				//どことも当たらないので終わり。
				break;
			}
			loopCount++;
			if (loopCount == 5) {
				break;
			}
		}
	}
	//下方向を調べる。
	{
		CVector3 addPos;
		addPos.Subtract(nextPosition, position);
		btTransform start, end;
		start.setIdentity();
		end.setIdentity();
		start.setOrigin(btVector3(position.x, position.y + radius, position.z));
		CVector3 newPos;
		SweepResultGround callback;
		callback.startPos = position;
		if (addPos.y < 0.0f) {
			newPos = (*(CVector3*)&start.getOrigin());
			newPos.y += addPos.y;

			end.setOrigin(btVector3(newPos.x, newPos.y, newPos.z));

			PhysicsWorld().ConvexSweepTest((const btConvexShape*)collider.GetBody(), start, end, callback);
		}
		if (callback.isHit) {
			//当たった。
			float t = fabsf(acosf(callback.hitNormal.Dot(CVector3::Up)));
			if (t < CMath::PI * 0.3f) {
				//地面。
				CVector3 Circle;
				float x = 0.0f;
				float offset = 0.0f;	//押し戻す量。
				Circle = CVector3::Zero;

				Circle = position;
				Circle.y = callback.hitPos.y;//円の中心
				CVector3 v;
				v.Subtract(Circle, callback.hitPos);
				x = v.Length();//物体の角とプレイヤーの間の横幅の距離が求まる。

				offset = sqrt(max(0.0f, radius*radius - x*x));//yの平方根を求める。

				moveSpeed.y = 0.0f;
				isJump = false;
				nextPosition.y = callback.hitPos.y + offset - radius;
			}
		}
	}
	position = nextPosition;
}
void EnemyTest::Update()
{
	CVector3 nextPosition = position;
	const float MOVE_SPEED = 5.0f;
	if (state == enStateRun || state == enStateStand) {
		if (Pad(0).IsTrigger(enButtonRB3)) {
			isPointLightOn = !isPointLightOn;
		}
		if (Pad(0).IsPress(enButtonA)) {
			//Aボタンが押された。
			//車との距離を調べる。
			CVector3 diff = g_car->GetPosition();
			diff.Subtract(position);
			if (diff.Length() < 2.0f) {
				//車との距離が2m以内。
				state = enState_RideOnCar;
				skinModel.SetShadowReceiverFlag(false);
				skinModel.SetShadowCasterFlag(false);
				g_car->SetRideOnFlag(true);
				g_camera->SetCar(g_car);
				return;
			}
			else if(!isJump){
				//車との距離が離れていたらジャンプ。
				moveSpeed.y = 8.0f;
				isJump = true;
			}
		}
		//走りか立ち状態の時。
		CVector3 moveDirLocal;
		moveDirLocal.y = 0.0f;
		moveDirLocal.x = Pad(0).GetLStickXF();
		moveDirLocal.z = Pad(0).GetLStickYF();
		const CMatrix& mViewInv = g_camera->GetCamera().GetViewMatrixInv();
		//カメラ空間から見た奥方向のベクトルを取得。
		CVector3 cameraZ;
		cameraZ.x = mViewInv.m[2][0];
		cameraZ.y = 0.0f;		//Y軸いらない。
		cameraZ.z = mViewInv.m[2][2];
		cameraZ.Normalize();	//Y軸を打ち消しているので正規化する。
								//カメラから見た横方向のベクトルを取得。
		CVector3 cameraX;
		cameraX.x = mViewInv.m[0][0];
		cameraX.y = 0.0f;		//Y軸はいらない。
		cameraX.z = mViewInv.m[0][2];
		cameraX.Normalize();	//Y軸を打ち消しているので正規化する。

		CVector3 moveDir;
		moveDir.x = cameraX.x * moveDirLocal.x + cameraZ.x * moveDirLocal.z;
		moveDir.y = 0.0f;	//Y軸はいらない。
		moveDir.z = cameraX.z * moveDirLocal.x + cameraZ.z * moveDirLocal.z;

		moveSpeed.x = moveDir.x * MOVE_SPEED;
		moveSpeed.z = moveDir.z * MOVE_SPEED;
		
		//Y方向には重力落下を加える。
		const float GRAVITY = -18.8f;
		moveSpeed.y += GRAVITY * GameTime().GetFrameDeltaTime();
		CVector3 addPos = moveSpeed;
		addPos.Scale(GameTime().GetFrameDeltaTime());
		nextPosition.Add(addPos);
		if (moveDir.LengthSq() > 0.0001f) {
			rotation.SetRotation(CVector3::Up, atan2f(moveDir.x, moveDir.z));
			//走り状態に遷移。
			state = enStateRun;
		}
		else {
			//立ち状態。
			state = enStateStand;
		}
		
		ShadowMap().SetLightTarget(position);
		CVector3 lightPos;
		lightPos.Add(position, toLightPos);
		ShadowMap().SetLightPosition(lightPos);
		//コリジョン検出と解決を行う。
		CollisionDetectAndResolve(nextPosition);
	}
	else if (state == enState_RideOnCar) {
		ShadowMap().SetLightTarget(g_car->GetPosition());
		CVector3 lightPos;
		lightPos.Add(g_car->GetPosition(), toLightPos);
		ShadowMap().SetLightPosition(lightPos);
		if (g_car->GetMoveSpeed().Length() < 0.1f) {
			//車が停止状態。
			if (Pad(0).IsPress(enButtonB)) {
				//降車。
				g_camera->SetCar(NULL);
				g_car->SetRideOnFlag(false);
				skinModel.SetShadowReceiverFlag(true);
				skinModel.SetShadowCasterFlag(true);
				position = g_car->GetPosition();
				state = enStateStand;
			}
		}
	}
	
	skinModel.Update(position, rotation, CVector3::One);
	
	//ポイントライトの位置を更新。
	UpdatePointLightPosition();
	//アニメーションコントロール。
	AnimationControl();
	lastFrameState = state;
}
void CSoundManager::FillCurrentBuffer( Float* a_CurrentBuffer, const Uint a_SoundChannels, const Uint a_SampleRate, const Uint a_SamplesInBuffer )
{
	m_SoundsCriticalSection.Enter();

	m_SampleRate = a_SampleRate;	
	//If this is the first time we enter create and memset the echo buffer
	if ( m_EchoBuffer == NULL )
	{
		m_EchoBuffer = new Float[a_SamplesInBuffer * m_EchoCount ];
		memset( m_EchoBuffer, 0, sizeof(Float) * a_SamplesInBuffer * m_EchoCount );
		m_ReadPositionInEchoBuffer = m_SampleRate * ( ( m_EchoDelayMS / 1000.0f ) / 1.0f );
	}

	//Calculate listener data
	m_ListenersCritcalSection.Enter();	
	CVector3 up = m_ActiveListener->GetUp();
	CVector3 lookAtCrossUp = m_ActiveListener->GetDirection();
	lookAtCrossUp = lookAtCrossUp.Cross( up );
	lookAtCrossUp.Normalize();
	CVector3 listenerPosition = m_ActiveListener->GetWorldPosition();
	m_ListenersCritcalSection.Leave();
	
	//Loop through sound to let them fill the buffer
	m_SoundIt = m_SoundsMap.begin();
	while( m_SoundIt != m_SoundsMap.end() )
	{
		if ( m_SoundIt->second->IsPlaying() == true )
		{
			m_SoundIt->second->FillCurrentBuffer( a_SoundChannels, a_SampleRate, a_SamplesInBuffer, lookAtCrossUp, listenerPosition, m_GlobalAttenuation );
		}
		
		m_SoundIt++;
	}

	Float* targetPointer = a_CurrentBuffer;
	Float* sourcePointer;

	//Brickwall max
	Float max = 0.0f;

	//Loop again now collecting the buffers and adding them into a final buffer
	m_SoundIt = m_SoundsMap.begin();
	Float oneOverSize = 1.0f / m_SoundsMap.size();
	Float value;
	while( m_SoundIt != m_SoundsMap.end() )
	{
		targetPointer = a_CurrentBuffer;
		
		if ( m_SoundIt->second->IsPlaying() == true )
		{
			sourcePointer = m_SoundIt->second->GetCurrentBuffer();
			
			for ( Uint i = 0; i < a_SamplesInBuffer; ++i )
			{
				//Multiply with globalvolume and the one-over ( kind of ugly to prevent clipping )
				value = ( *sourcePointer ) * m_GlobalVolume;
				

				//Anti distortion
				if ( m_DistortFunction == AntiDistortNumChannels )
				{
					value *= oneOverSize;
				}
				else if ( m_DistortFunction == AntiDistortMagicValue )
				{
					value *= m_MagicValue;
				}

				*targetPointer += value;		

				Float abs = fabs( *targetPointer );
				if ( abs > max )
				{
					max = abs;
				}

				sourcePointer++;
				targetPointer++;
			}
		}

		m_SoundIt++;
	}

	//Apply echo
	if ( m_EchoActive == true )
	{
		targetPointer = a_CurrentBuffer;

		for ( Uint i = 0; i < a_SamplesInBuffer; ++i )	
		{
			//Write to the current buffer
			*targetPointer += ( m_EchoBuffer[m_ReadPositionInEchoBuffer++] );
		
			//If we reach the end of buffer wrap around
			if ( m_ReadPositionInEchoBuffer >= ( a_SamplesInBuffer * m_EchoCount ) )
			{
				m_ReadPositionInEchoBuffer = 0;
			}
			//Abs for echo
			Float abs = fabs( *targetPointer );
			if ( abs > max )
			{
				max = abs;
			}
			//Increment target point
			targetPointer++;

			//Write current buffer into echo buffer
			m_EchoBuffer[m_PositionInEchoBuffer++] = a_CurrentBuffer[i] * m_EchoDecay;
			if ( m_PositionInEchoBuffer >= ( a_SamplesInBuffer * m_EchoCount ) )
				m_PositionInEchoBuffer = 0;
		}
	}

	//Brickwall
	Float oneOverMax = 1.0f / max;
	if ( m_DistortFunction == AntiDistortBrickWall ) for ( Uint i = 0; i < a_SamplesInBuffer; ++i )
	{
		a_CurrentBuffer[i] *= oneOverMax;
	}

	m_SoundsCriticalSection.Leave();
}
//main render engine function called as multiple threads
void cRenderWorker::doWork(void)
{
	// here will be rendering thread
	QTextStream out(stdout);

	int width = image->GetWidth();
	int height = image->GetHeight();
	double aspectRatio = (double) width / height;

	PrepareMainVectors();
	PrepareReflectionBuffer();
	if (params->ambientOcclusionEnabled && params->ambientOcclusionMode == params::AOmodeMultipeRays) PrepareAOVectors();

	//init of scheduler
	cScheduler *scheduler = threadData->scheduler;

	//start point for ray-marching
	CVector3 start = params->camera;

	scheduler->InitFirstLine(threadData->id, threadData->startLine);

	bool lastLineWasBroken = false;

	//main loop for y
	for (int ys = threadData->startLine; scheduler->ThereIsStillSomethingToDo(threadData->id); ys =
			scheduler->NextLine(threadData->id, ys, lastLineWasBroken))
	{
		//skip if line is out of region
		if (ys < 0) break;
		if (ys < data->screenRegion.y1 || ys > data->screenRegion.y2) continue;

		//main loop for x
		for (int xs = 0; xs < width; xs += scheduler->GetProgressiveStep())
		{

			//break if by coincidence this thread started rendering the same line as some other
			lastLineWasBroken = false;
			if (scheduler->ShouldIBreak(threadData->id, ys))
			{
				lastLineWasBroken = true;
				break;
			}

			if (scheduler->GetProgressivePass() > 1 && xs % (scheduler->GetProgressiveStep() * 2) == 0
					&& ys % (scheduler->GetProgressiveStep() * 2) == 0) continue;

			//skip if pixel is out of region;
			if (xs < data->screenRegion.x1 || xs > data->screenRegion.x2) continue;

			//calculate point in image coordinate system
			CVector2<int> screenPoint(xs, ys);
			CVector2<double> imagePoint = data->screenRegion.transpose(data->imageRegion, screenPoint);
			imagePoint.x *= aspectRatio;

			//full dome shemisphere cut
			bool hemisphereCut = false;
			if (params->perspectiveType == params::perspFishEyeCut
					&& imagePoint.Length() > 0.5 / params->fov) hemisphereCut = true;

			//calculate direction of ray-marching
			CVector3 viewVector = CalculateViewVector(imagePoint,
																								params->fov,
																								params->perspectiveType,
																								mRot);

			//---------------- 1us -------------

			//Ray marching
			CVector3 point;
			CVector3 startRay = start;
			sRGBAfloat resultShader;
			sRGBAfloat objectColour;
			CVector3 normal;
			double depth = 1e20;
			double opacity = 1.0;

			//raymarching loop (reflections)

			if (!hemisphereCut) //in fulldome mode, will not render pixels out of the fulldome
			{
				sRayRecursionIn recursionIn;

				sRayMarchingIn rayMarchingIn;
				CVector3 direction = viewVector;
				direction.Normalize();
				rayMarchingIn.binaryEnable = true;
				rayMarchingIn.direction = direction;
				rayMarchingIn.maxScan = params->viewDistanceMax;
				rayMarchingIn.minScan = params->viewDistanceMin;
				rayMarchingIn.start = startRay;
				rayMarchingIn.invertMode = false;
				recursionIn.rayMarchingIn = rayMarchingIn;
				recursionIn.calcInside = false;
				recursionIn.resultShader = resultShader;
				recursionIn.objectColour = objectColour;

				sRayRecursionInOut recursionInOut;
				sRayMarchingInOut rayMarchingInOut;
				rayMarchingInOut.buffCount = &rayBuffer[0].buffCount;
				rayMarchingInOut.stepBuff = rayBuffer[0].stepBuff;
				recursionInOut.rayMarchingInOut = rayMarchingInOut;
				recursionInOut.rayIndex = 0;

				sRayRecursionOut recursionOut = RayRecursion(recursionIn, recursionInOut);

				resultShader = recursionOut.resultShader;
				objectColour = recursionOut.objectColour;
				depth = recursionOut.rayMarchingOut.depth;
				if (!recursionOut.found) depth = 1e20;
				opacity = recursionOut.fogOpacity;
				normal = recursionOut.normal;
			}

			sRGBfloat pixel2;
			pixel2.R = resultShader.R;
			pixel2.G = resultShader.G;
			pixel2.B = resultShader.B;
			unsigned short alpha = resultShader.A * 65535;
			unsigned short opacity16 = opacity * 65535;

			sRGB8 colour;
			colour.R = objectColour.R * 255;
			colour.G = objectColour.G * 255;
			colour.B = objectColour.B * 255;

			sRGBfloat normalFloat;
			if(image->GetImageOptional()->optionalNormal)
			{
				CVector3 normalRotated = mRotInv.RotateVector(normal);
				normalFloat.R = (1.0 + normalRotated.x) / 2.0;
				normalFloat.G = (1.0 + normalRotated.z) / 2.0;
				normalFloat.B = 1.0 - normalRotated.y;
			}

			for (int xx = 0; xx < scheduler->GetProgressiveStep(); ++xx)
			{
				for (int yy = 0; yy < scheduler->GetProgressiveStep(); ++yy)
				{
					image->PutPixelImage(screenPoint.x + xx, screenPoint.y + yy, pixel2);
					image->PutPixelColour(screenPoint.x + xx, screenPoint.y + yy, colour);
					image->PutPixelAlpha(screenPoint.x + xx, screenPoint.y + yy, alpha);
					image->PutPixelZBuffer(screenPoint.x + xx, screenPoint.y + yy, (float) depth);
					image->PutPixelOpacity(screenPoint.x + xx, screenPoint.y + yy, opacity16);
					if(image->GetImageOptional()->optionalNormal)
						image->PutPixelNormal(screenPoint.x + xx, screenPoint.y + yy, normalFloat);
				}
			}

			data->statistics.numberOfRenderedPixels++;
		}
	}

	//emit signal to main thread when finished
	emit finished();
	return;
}