Beispiel #1
0
Matrix BGE_NCP Matrix::SetLookAt(Vector4 BGE_NCP Position,
                                    Vector4 BGE_NCP Target,
                                    Vector4 BGE_NCP UpVector)
{
    Vector4 Forward = Target - Position;
    Forward.Normalize();

    Vector4 Side = Cross(Forward, UpVector);
    Side.Normalize();

    Vector4 Up = Cross(Side, Forward);
    Up.Normalize();

    Val[0] = Side[0];
    Val[4] = Side[1];
    Val[8] = Side[2];

    Val[1] = Up[0];
    Val[5] = Up[1];
    Val[9] = Up[2];

    Val[2] = -Forward[0];
    Val[6] = -Forward[1];
    Val[10] = -Forward[2];

    Val[3] = Val[7] = Val[11] = 0;

    Val[12] = -Dot(Side, Position);
    Val[13] = -Dot(Up, Position);
    Val[14] = Dot(Forward, Position);

    return *this;
}
Beispiel #2
0
Vector4 LightInfo::GetPointLightOnPoint(const Vector4& _cameraSpacePoint, const Vector4& _point, const Vector4& _normal, int _lightIndex, const Vector4& _diffuse, const Vector4& _specular) {
	// Get the difference in position from the light and the point.
	Vector4 diff = GetPointLights()[_lightIndex].GetPosition() - _point;
	Vector4 lightDirection = diff;

	// The distance
	float distance = diff.Length();
					
	// The direction
	diff.Normalize();

	// The attenuation
	float attenuation = GetPointLights()[_lightIndex].GetAttenuation(distance);
			
	// Diffuse lighting.
	Vector4 pointColor = GetPointLights()[_lightIndex].GetIntensity() 
								* diff.Dot(_normal)
									* attenuation
										* _diffuse;
	pointColor.Clamp();

	// Specular
	// We get the half angle between the camera and the direction to the camera.
	Vector4 halfAngle = lightDirection + _cameraSpacePoint;
	halfAngle.Normalize();

	Vector4 specular = _specular * powf(halfAngle.Dot(_normal), 10) * attenuation;
	specular.Clamp();
	pointColor += specular;

	return pointColor;
}
Beispiel #3
0
	void CSDFController::ComputeTNB(Face* tmp, Vector4& tang, Vector4& norm, Vector4& binor)
	{
		// compute tanget space matrix
		Vector4 U = Vector4(tmp->v[1]->P - tmp->v[0]->P);
		Vector4 V = Vector4(tmp->v[2]->P - tmp->v[0]->P);
		norm = (U % V) * (-1.0);
		norm.Normalize();

		tang = Vector4(tmp->v[0]->P - tmp->v[2]->P);
		tang.Normalize();
		binor = tang % norm;
		binor.Normalize();
	}
void Camera::BuildViewMatrix(const Maths::Vector4 &position, const Maths::Vector4 &lookAt, const Maths::Vector4 &up)
{
	Vector4 viewDir = lookAt - position;
	Vector4 viewSide, viewUp;
	
	// store values
	m_up = up;
	m_position = position;
	m_lookAt = lookAt;

	viewDir.Normalize();
	viewUp = up - viewDir * up.DotProduct( viewDir );
	viewUp.Normalize();
	viewSide = viewDir.CrossProduct( viewUp );

	// setup inverse rotation matrix
	Matrix4 rotation;
	rotation.SetRows( viewSide, viewUp, Vector4( -viewDir.X, -viewDir.Y, -viewDir.Z, -viewDir.W ), Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) );

	//transform translation
	Vector4 invPos;
	Matrix4::Transform( rotation, position, invPos );
	m_inversePosition = -invPos;

	// build view matrix
	Matrix4 view;
	Matrix4::Multiply( view, rotation, m_viewMatrix );
	m_viewMatrix( 0, 3 ) = m_inversePosition.X;
	m_viewMatrix( 1, 3 ) = m_inversePosition.Y;
	m_viewMatrix( 2, 3 ) = m_inversePosition.Z;
	m_viewMatrix( 3, 3 ) = m_inversePosition.W;

	m_viewDir = viewDir;
}
Beispiel #5
0
	/* Random */
	Vector4 Random(void) {
		int x = rand() - rand();
		int y = rand() - rand();
		int z = rand() - rand();

		// z = 0 for now until graphics issues sorted out
 		Vector4 toReturn = Vector4(x, y, 0);
		toReturn.Normalize();
		return toReturn;
	}
Beispiel #6
0
/* Get the light value for a point in space */
Vector4 LightInfo::GetDirectionalLightOnPoint(const Vector4& _cameraSpacePoint, const Vector4& _normal, int _lightIndex, const Vector4& _diffuse, const Vector4& _specular) {
	Vector4 directionalColor = GetDirectionalLights()[_lightIndex].GetIntensity() * GetDirectionalLights()[_lightIndex].GetDirection().Dot(_normal) * _diffuse;
	directionalColor.Clamp();

	// Specular
	Vector4 halfAngle  = GetDirectionalLights()[_lightIndex].GetDirection() + _cameraSpacePoint;
	halfAngle.Normalize();
	Vector4 specular = _specular * powf(halfAngle.Dot(_normal), 100) * GetDirectionalLights()[_lightIndex].GetIntensity();
	specular.Clamp();
	directionalColor += specular;

	return directionalColor;
}
Beispiel #7
0
// Get the spot light info on a point.
Vector4 LightInfo::GetSpotLightOnPoint(const Vector4& _cameraSpacePoint, const Vector4& _point, const Vector4& _normal, int _lightIndex, const Vector4& _diffuse, const Vector4& _specular) {
	// Get the difference in position from the light and the point.
	Vector4 diff = GetSpotLights()[_lightIndex].GetPosition() - _point;
	Vector4 lightDirection = diff;

	// The distance
	float distance = diff.Length();
					
	// The direction
	diff.Normalize();

	// Calculate the spot light values
	float spotLightValue = diff.Dot(GetSpotLights()[_lightIndex].GetDirection() * -1);
	if (spotLightValue > 0.2f)
		return Vector4(0, 0, 0, 0);
	float smoothing = GetSpotLights()[_lightIndex].SmoothStep(diff.Dot(_normal));

	// The attenuation
	float attenuation = GetSpotLights()[_lightIndex].GetAttenuation(distance);
			
	// Diffuse lighting.
	Vector4 pointColor = GetSpotLights()[_lightIndex].GetIntensity() 
								* diff.Dot(_normal)
									* attenuation
										* _diffuse
											* spotLightValue;

	// Specular
	// We get the half angle between the camera and the direction to the camera.
	Vector4 halfAngle = lightDirection + _cameraSpacePoint;
	halfAngle.Normalize();

	pointColor += _specular * powf(halfAngle.Dot(_normal), 10) * attenuation;

	return pointColor;	
}
Beispiel #8
0
	void Shader::BindLight(const std::shared_ptr<SceneNode> &lightNode)
	{
		Vector4 lightPos = lightNode->GetWorldPosition();
		Vector4 lightDir = lightNode->GetWorldMatrix().Multiply(Vector4(0, -1, 0, 0));
		lightDir.Normalize();
		if (auto light = lightNode->GetComponent<Light>())
		{
			Color color = light->GetColor();
			BindFloat("light_pos", lightPos.x, lightPos.y, lightPos.z);
			BindFloat("light_dir", lightDir.x, lightDir.y, lightDir.z);
			BindFloat("light_color", color.r, color.g, color.b);
			BindFloat("light_intensity", light->GetIntensity());
			BindFloat("light_innerangle", light->GetInnerAngle());
			BindFloat("light_outterangle", light->GetOutterAngle());
			BindFloat("light_falloff", light->GetFalloff());
			BindFloat("light_radius", light->GetRadius());
		}
	}
Beispiel #9
0
Matrix4 Matrix4::GetRotate(const Vector4& from, const Vector4& to) {
	Vector4 axis = from.Cross(to);
	axis.Normalize();
	float degrees = from.GetAngleBetween(to);
	return GetRotate(degrees, axis);
}
Beispiel #10
0
	// pocitanie funkcie pre vsetky trojuholniky, O(n2)
	void CSDFController::Compute(LinkedList<Face>* triangles, Octree* root)
	{
		float min = FLOAT_MAX;
		float max = 0.0;
		
		unsigned int n_rays = 30;
		float angle = 120.0f;
		unsigned int counter = 0;

		//------------------prealocated variables------------------
		Vector4 tangens, normal, binormal;
		Mat4 t_mat;
		std::vector<float> rays;
		std::vector<float> weights;

		// precompute those N rays
		srand (123);											// initial seed for random number generator
		float* rndy = new float[n_rays];
		float* rndx = new float[n_rays];
		for(unsigned int i = 0; i < n_rays; i++)
		{
			rndy[i] = float(rand()%int(angle / 2));
			rndx[i] = float(rand()%(360));
			if(rndy[i] == 0.0)
				rndy[i] = 0.5;
		}

		float dist = FLOAT_MAX;
		float dist2 = FLOAT_MAX;
		float theta = 0.0f;
		bool intersected = false;

		LinkedList<Face>* face_list = NULL;
		LinkedList<Face>::Cell<Face>* intersected_face = NULL;
		//------------------prealocated variables------------------

		LinkedList<Face>::Cell<Face>* current_face = triangles->start;
		while(current_face != NULL)
		{
			// vypocet TNB vektorov a matice
			ComputeTNB(current_face->data, tangens, normal, binormal);
			t_mat = Mat4(tangens, normal, binormal);

			rays.clear();
			weights.clear();
			for(unsigned int i = 0; i < n_rays; i++)
			{
				Vector4 ray = CalcRayFromAngle(rndx[i], rndy[i]) * t_mat;
				ray.Normalize();

				dist = FLOAT_MAX;
				face_list = GetFaceList(triangles, root, current_face->data->center, ray);
				intersected_face = face_list->start;
				while(intersected_face != NULL)
				{
					if(current_face == intersected_face)
					{
						intersected_face = intersected_face->next;
						continue;
					}

					dist2 = FLOAT_MAX;
					intersected = rayIntersectsTriangle(current_face->data->center, ray, intersected_face->data->v[0]->P, intersected_face->data->v[1]->P, intersected_face->data->v[2]->P, dist2);
					if(intersected == true)
					{
						theta = acos( (ray * intersected_face->data->normal) / (ray.Length() * intersected_face->data->normal.Length()) );
						theta = theta * float(180.0 / M_PI);
						//loggger->logInfo(MarshalString("pridany ray s thetou: " + theta));
						if((theta < 90.0f) && (dist2 < dist))
							dist = dist2;
					}

					intersected_face = intersected_face->next;
				}
				if(dist < (FLOAT_MAX - 1.0f))
				{
					//loggger->logInfo(MarshalString("pridany ray s dlzkou: " + dist));
					rays.push_back(dist);
					weights.push_back(180.0f - rndy[i]);
				}
				//if(root != NULL)
					//delete face_list;						// generated list, bez prealokovania
			}
			if(rays.size() > 0)
			{
				current_face->data->ComputeSDFValue(rays, weights);
				if(current_face->data->diameter->value < min)
					min = current_face->data->diameter->value;
				if(current_face->data->diameter->value > max)
					max = current_face->data->diameter->value;
			}
			counter = counter + 1;
			current_face = current_face->next;
		}
		fc_list->Clear();
		oc_list->Clear();
		delete [] rndy;
		delete [] rndx;

		// postprocessing - smoothing and normalization
		//float kernel[] = {1.0,4.0,6.0,4.0,1.0};
		float* kernel = ComputeGaussianKernel(kernel_size);
		current_face = triangles->start;
		while(current_face != NULL)
		{
			Smooth(current_face->data, kernel, kernel_size);
			current_face->data->diameter->Normalize1(min, max, 4.0);
			current_face->data->diameter->Normalize2(0, max, 4.0);
			//tmp->data->diameter->Normalize2(0, diagonal, 4.0);

			current_face = current_face->next;
		}
		delete kernel;
	}
Beispiel #11
0
void Mesh::CalculateLightingPoint( const std::vector<LightPoint>& light, int numLight, const Maths::Vector4& camera)
{
	Maths::Vector4 l;
	Maths::Vector4 temp, result, n, p;
	Maths::Vector4 cof( 1.0f, 1.0f, 10.0f );
	BYTE r, g, b;
	float distance = 0;
	float att = 0;
	float a = 0.05f;
	float bb = 0.05f;
	float c = 0.05f;
	float dif, spec;

	m_noLight = false;

	for ( int i = 0; i < m_numVerts; ++i )
	{
		if ( !m_transformed[i].IsCulled )
		{
			result.X = 0; //Red
			result.Y = 0; //green
			result.Z = 0; //blue

			for ( int j = 0; j < numLight; ++j )
			{
				p = light[j].Position;
				l = p - m_transformed[i].Position;
				distance = l.Length();

				//calculate the attenuation value
				att = 1 / (a + ( distance * bb ) + ( distance * distance ) * c );
				if ( att < 0 )
					att = 0;

				temp.X = light[j].Colour.GetR();
				temp.Y = light[j].Colour.GetG();
				temp.Z = light[j].Colour.GetB();
				
				n = m_transformed[i].Normal;
				n.Normalize();

				dif = max( 0.0, l.DotProduct( n ) ) * att;

				// calculate the speculation
				//Vector4 toEye = m_transformed[i].Position - camera;
				//Vector4 half = camera + p / 2;
				//toEye.Normalize();
				//half.Normalize();
				//float specPower = 1.0f;
				//float spec = pow( max( n.DotProduct( half ), 0.0f ), specPower ) * att;
				Vector4 toEye = m_transformed[i].Position - camera;
				Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) );
				toEye.Normalize();
				reflect.Normalize();
				float specPower = 1.0f;
				float spec = pow( max( reflect.DotProduct( toEye ), 0.0f ), specPower ) * att;

				temp.X =  temp.X * ( (dif + spec) * m_kd_red );
				temp.Y =  temp.Y * ( (dif + spec) * m_kd_green );
				temp.Z =  temp.Z * ( (dif + spec) * m_kd_blue );

				//temp.X =  temp.X * ( dif * m_kd_red ) );
				//temp.Y =  temp.Y * ( dif * m_kd_green ) );
				//temp.Z =  temp.Z * ( dif * m_kd_blue ) );

				result += temp;
			}

			//set colour
			if ( result.X > 255.0f ) result.X = 255.0f;
			if ( result.Y > 255.0f ) result.Y = 255.0f;
			if ( result.Z > 255.0f ) result.Z = 255.0f;
			if ( result.X < 0.0f ) result.X = 0.0f;
			if ( result.Y < 0.0f ) result.Y = 0.0f;
			if ( result.Z < 0.0f ) result.Z = 0.0f;
			r = (BYTE)result.X;
			g = (BYTE)result.Y;
			b = (BYTE)result.Z;
			m_transformed[i].Colour = Gdiplus::Color::MakeARGB( 255, r, g, b );
		}
	}
}
Beispiel #12
0
void Mesh::CalculateLightingDirectional(const LightDirectional& light, int numLights, const Vector4& camera)
{
	Maths::Vector4 total;
	Maths::Vector4 temp;
	Maths::Vector4 l( light.Position.X, light.Position.Y, light.Position.Z, 1.0f );
	Maths::Vector4 n( 0, 0, 0, 0 );
	BYTE r, g, b;
	float diff, spec = 0;

	m_noLight = false;
	l.Normalize();

	for ( int i = 0; i < m_numVerts; ++i )
	{
		if ( !m_transformed[i].IsCulled )
		{
			//reset the colout to black
			total.X = 0; //Red
			total.Y = 0; //green
			total.Z = 0; //blue

			for ( int j = 0; j < numLights; ++j )
			{
				Maths::Vector4 d;
				
				//modulate intensity with coresponding reflectance co-efficient values
				temp.X = light.Colour.GetR() * light.Intensity.X;
				temp.Y = light.Colour.GetG() * light.Intensity.Y;
				temp.Z = light.Colour.GetB() * light.Intensity.Z;

				n = m_transformed[i].Normal; 
				n.Normalize();

				//attentuate the rgb values with lambertian attenuation
				diff = max(0.0, l.DotProduct( n ));
				
				Vector4 toEye = m_transformed[i].Position - camera;
				Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) );
				toEye.Normalize();
				reflect.Normalize();
				float specPower = 1.0f;
				spec = pow( max( reflect.DotProduct( toEye ), 0.0f ), specPower )  * 0.01f;

				if ( diff <= 0.0f )
					spec = 0.0f;

				temp.X =  temp.X * ( (diff + spec) * m_kd_red );
				temp.Y =  temp.Y * ( (diff + spec) * m_kd_green );
				temp.Z =  temp.Z * ( (diff + spec) * m_kd_blue );

				//temp.X =  temp.X * ( diff * m_kd_red + spec ) );
				//temp.Y =  temp.Y * ( diff * m_kd_green + spec ) );
				//temp.Z =  temp.Z * ( diff * m_kd_blue + spec ) );
				total = total + temp;
			}

			if ( total.X > 255.0f ) total.X = 255.0f;
			if ( total.Y > 255.0f ) total.Y = 255.0f;
			if ( total.Z > 255.0f ) total.Z = 255.0f;
			if ( total.X < 0.0f ) total.X = 0.0f;
			if ( total.Y < 0.0f ) total.Y = 0.0f;
			if ( total.Z < 0.0f ) total.Z = 0.0f;

			r = (BYTE)total.X;
			g = (BYTE)total.Y;
			b = (BYTE)total.Z;

			m_transformed[i].Colour = Gdiplus::Color::MakeARGB( 255, r, g, b );
		}
	}
}
Beispiel #13
0
void Mesh::CalculateFlatLightingPoint(const std::vector<LightPoint>& light, int numLights, const Vector4& camera)
{
	Maths::Vector4 l;
	Maths::Vector4 temp, result, n, p;
	BYTE r, g, b;
	float distance = 0;
	float att = 0;
	float a = 0.05f;
	float bb = 0.05f;
	float c = 0.05f;
	float dif, spec;
	m_noLight = false;

	for ( int i = 0; i < m_numPolys; ++i )
	{
		result.X = 0; //Red
		result.Y = 0; //green
		result.Z = 0; //blue

		if ( !m_polys[i].IsCulled )
		{
			for ( int j = 0; j < numLights; ++j )
			{
				//get the position of the light and calculate the 
				//distance between the object and the lifght
				p = light[j].Position;
				l = p - m_transformed[ m_polys[i].Indices[0] ].Position;
				distance = l.Length();

				//calculate the attenuation value
				att = 1 / (a + ( distance * bb ) + ( distance * distance ) * c );
				if ( att < 0)
					att = 0;
				
				temp.X = light[j].Colour.GetR();
				temp.Y = light[j].Colour.GetG();
				temp.Z = light[j].Colour.GetB();
				
				// get the normalized value of the polygon normals
				//n = m_polys[i]._normalN;
				//n.Normalize();

				// calculate the diffuse value
				dif = max( l.DotProduct( m_polys[i].NormalN ), 0.0f ) * att;
				// multiply dif with materials

				// calculate the speculation
				//Vector4 toEye = m_transformed[ m_polys[i]._indices[0] ]._position - camera;
				//Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) );
				//toEye.Normalize();
				//reflect.Normalize();
				//float specPower = 1.0f;
				//float spec = pow( max( reflect.DotProduct( toEye ), 0.0f ), specPower ) * att;

				Vector4 toEye = m_transformed[ m_polys[i].Indices[0] ].Position - camera;
				Vector4 half = camera + p / 2;
				toEye.Normalize();
				half.Normalize();
				float specPower = 1.0f;
				float spec = pow( max( n.DotProduct( half ), 0.0f ), specPower ) * att;

				temp.X =  temp.X * ( (dif + spec) * m_kd_red );
				temp.Y =  temp.Y * ( (dif + spec) * m_kd_green );
				temp.Z =  temp.Z * ( (dif + spec) * m_kd_blue );

				result += temp;
			}

			//set colour
			if ( result.X > 255.0f ) result.X = 255;
			if ( result.Y > 255.0f ) result.Y = 255;
			if ( result.Z > 255.0f ) result.Z = 255;
			if ( result.X < 0.0f ) result.X = 0;
			if ( result.Y < 0.0f ) result.Y = 0;
			if ( result.Z < 0.0f ) result.Z = 0;
			r = (BYTE)result.X;
			g = (BYTE)result.Y;
			b = (BYTE)result.Z;

			m_polys[i].Colour = Gdiplus::Color::MakeARGB( 255, r, g, b );
		}
	}
}
Beispiel #14
0
void Mesh::CalculateFlatLightingDirectional(const LightDirectional &light, int numLights, const Vector4& cameraPos, const Matrix4& view)
{
	Maths::Vector4 total, temp;
	Maths::Vector4 reflect;
	Maths::Vector4 v = cameraPos;
	Maths::Vector4 l( light.Position.X, light.Position.Y, light.Position.Z, 1.0f  ); 
	Maths::Vector4 n( 0, 0, 0 );
	Maths::Vector4 t, halfWay;
	BYTE r, g, b;
	float spec = 0;
	float diff = 0;
	float ave = 0;

	m_noLight = false;

	//workout the "halfway" vector for specularity
	ave = v.Length();
	//halfWay = ( v + l ) / ave;
	//halfWay.Normalize();

	//normalize the light position
	l.Normalize();

	for ( int i = 0; i < m_numPolys; ++i )
	{
		if ( !m_polys[i].IsCulled )
		{
			//reset the colout to black
			total.X = 0; //Red
			total.Y = 0; //green
			total.Z = 0; //blue

			for ( int j = 0; j < numLights; ++j )
			{
				//store intensity to corresponding variables
				//modulate intensity with coresponding reflectance co-efficient values
				temp.X = light.Colour.GetR() * light.Intensity.X;
				temp.Y = light.Colour.GetG() * light.Intensity.Y;
				temp.Z = light.Colour.GetB() * light.Intensity.Z;

				//reflect = ( 2 * ( m_polys[i]._normal.DotProduct( light._position ) ) * ( m_polys[i]._normal - light );
				n.SetValues( m_polys[i].Normal.X, m_polys[i].Normal.Y, m_polys[i].Normal.Z, 1.0f );
				n.Normalize();

				//attentuate the rgb values with lambertian attenuation
				diff = max( 0.0f, l.DotProduct( n ) );

				//calculate specular coponent
				Vector4 toEye;
				Matrix4::Transform( view, m_transformed[ m_polys[i].Indices[0] ].Position, toEye );
				toEye.Normalize();

				float r = max( 0, m_transformed[ m_polys[i].Indices[0] ].Normal.DotProduct( l ) );
				Vector4 reflect = m_transformed[ m_polys[i].Indices[0] ].Normal;
				reflect.Multiply( 2 * r );
				reflect.Subtract( l );
			
				//Vector4 toEye = m_transformed[ m_polys[i]._indices[0] ]._position - viewer;
				//Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) );
				toEye.Normalize();
				reflect.Normalize();
				float specPower = 1.0f;
				float spec = 0; //max( 0, pow( max( 0.0f, reflect.DotProduct( toEye ) ), specPower ) ) * m_specular;

				if ( diff <= 0.0f )
					spec = 0.0f;

				temp.X =  temp.X * ( (diff + spec) * m_kd_red );
				temp.Y =  temp.Y * ( (diff + spec) * m_kd_green );
				temp.Z =  temp.Z * ( (diff + spec) * m_kd_blue );

				total = total + temp;
			}

			//clamp the values
			if (total.X > 255) total.X = 255;
			if (total.Y > 255) total.Y = 255;
			if (total.Z > 255) total.Z = 255;
			if (total.X < 0) total.X = 0;
			if (total.Y < 0) total.Y = 0;
			if (total.Z < 0) total.Z = 0;

			r = (BYTE)total.X;
			g = (BYTE)total.Y;
			b = (BYTE)total.Z;

			m_polys[i].Colour = Gdiplus::Color::MakeARGB(255, r, g, b);
		}
	}
}
Beispiel #15
0
Void Mesh::Transform( const Transform3 & vModelTransform, GPUDeferredContext * pContext )
{
    Assert( m_pIL != NULL && m_pVB != NULL );
    Assert( m_pIL->IsBound() && m_pVB->IsBound() );

    if ( vModelTransform.IsIdentity() )
        return;

    // Begin update
    Byte * pFirstVertex = NULL;
    if ( m_pVB->CanUpdate() ) {
        Assert( m_pVB->HasCPUData() );
        pFirstVertex = m_pVB->GetData( m_iVertexOffset );
    } else {
        Assert( m_pVB->CanLock() );
        UInt iByteSize = 0;
        pFirstVertex = (Byte*)( m_pVB->Lock( GPURESOURCE_LOCK_WRITE, 0, &iByteSize, pContext ) );
        Assert( iByteSize == m_pVB->GetSize() );
    }

    // Transform VB
    UInt iVertexSize = m_pVB->GetElementSize();

    UInt iOffset, iSize;
    Byte * arrPositions = NULL;
    Byte * arrNormals = NULL;
    Byte * arrTangents = NULL;
    Byte * arrBiNormals = NULL;

    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_POSITION, 0 );
    arrPositions = ( pFirstVertex + iOffset );
    if ( m_pIL->HasField(GPUINPUTFIELD_SEMANTIC_NORMAL, 0) ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
        arrNormals = ( pFirstVertex + iOffset );
    }
    if ( m_pIL->HasField(GPUINPUTFIELD_SEMANTIC_TANGENT, 0) ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_TANGENT, 0 );
        arrTangents = ( pFirstVertex + iOffset );
    }
    if ( m_pIL->HasField(GPUINPUTFIELD_SEMANTIC_BINORMAL, 0) ) {
        m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_BINORMAL, 0 );
        arrTangents = ( pFirstVertex + iOffset );
    }
    
    Vertex4 * pPosition;
    Vector4 * pNormal;
    Vector4 * pTangent;
    Vector4 * pBiNormal;

    for( UInt i = 0; i < m_iVertexCount; ++i ) {
        pPosition = (Vertex4*)( arrPositions );
        *pPosition = ( vModelTransform * (*pPosition) );
        arrPositions += iVertexSize;

        if ( arrNormals != NULL ) {
            pNormal = (Vector4*)( arrNormals );
            *pNormal = ( vModelTransform * (*pNormal) );
            pNormal->Normalize();
            arrNormals += iVertexSize;
        }

        if ( arrTangents != NULL ) {
            pTangent = (Vector4*)( arrTangents );
            *pTangent = ( vModelTransform * (*pTangent) );
            pTangent->Normalize();
            arrTangents += iVertexSize;
        }

        if ( arrBiNormals != NULL ) {
            pBiNormal = (Vector4*)( arrBiNormals );
            *pBiNormal = ( vModelTransform * (*pBiNormal) );
            pBiNormal->Normalize();
            arrBiNormals += iVertexSize;
        }
    }

    // End update
    if ( m_pVB->CanUpdate() )
        m_pVB->Update( 0, INVALID_OFFSET, pContext );
    else
        m_pVB->UnLock( pContext );
}
Beispiel #16
0
Void TriangleMesh::UpdateNormals( GPUDeferredContext * pContext )
{
    Assert( m_pIL != NULL && m_pVB != NULL );
    Assert( m_pIL->IsBound() && m_pVB->IsBound() );

    Bool bHasNormals = m_pIL->HasField( GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    if ( !bHasNormals )
        return;

    // Begin update
    Byte * pFirstVertex = NULL;
    if ( m_pVB->CanUpdate() ) {
        Assert( m_pVB->HasCPUData() );
        pFirstVertex = m_pVB->GetData( m_iVertexOffset );
    } else {
        Assert( m_pVB->CanLock() );
        UInt iByteSize = 0;
        pFirstVertex = (Byte*)( m_pVB->Lock( GPURESOURCE_LOCK_WRITE, 0, &iByteSize, pContext ) );
        Assert( iByteSize == m_pVB->GetSize() );
    }

    // Update normals
    UInt iVertexSize = m_pVB->GetElementSize();

    UInt iOffset, iSize;
    const Byte * arrPositions = NULL;
    Byte * arrNormals = NULL;

    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_POSITION, 0 );
    arrPositions = ( pFirstVertex + iOffset );
    m_pIL->GetFieldRange( &iOffset, &iSize, GPUINPUTFIELD_SEMANTIC_NORMAL, 0 );
    arrNormals = ( pFirstVertex + iOffset );

    UInt i, iTriangleCount = GetTriangleCount();

        // Set all normals to null vector
    Byte * pCurNormal = arrNormals;
    Vector4 * pNormal;

    for( i = 0; i < m_iVertexCount; ++i ) {
        pNormal = (Vector4*)pCurNormal;
        pNormal->X = 0.0f;
        pNormal->Y = 0.0f;
        pNormal->Z = 0.0f;
        pCurNormal += iVertexSize;
    }

        // Weighted sum of facet normals
    UInt iA, iB, iC;
    const Vertex4 *pA, *pB, *pC;

    Vector4 vAB, vAC, vFaceNormal;

    for( i = 0; i < iTriangleCount; ++i ) {
        GetTriangle( i, iA, iB, iC );
        iA *= iVertexSize;
        iB *= iVertexSize;
        iC *= iVertexSize;

        pA = (const Vertex4 *)( arrPositions + iA );
        pB = (const Vertex4 *)( arrPositions + iB );
        pC = (const Vertex4 *)( arrPositions + iC );

        vAB = ( *pB - *pA );
        vAC = ( *pC - *pA );
        vFaceNormal = ( vAB ^ vAC );
        vFaceNormal.Normalize();

        pNormal = (Vector4*)( arrNormals + iA );
        *pNormal += vFaceNormal;
        pNormal = (Vector4*)( arrNormals + iB );
        *pNormal += vFaceNormal;
        pNormal = (Vector4*)( arrNormals + iC );
        *pNormal += vFaceNormal;
    }

        // Normalize all again
    pCurNormal = arrNormals;
    for( i = 0; i < m_iVertexCount; ++i ) {
        pNormal = (Vector4*)pCurNormal;
        pNormal->Normalize();
        pCurNormal += iVertexSize;
    }

    // End update
    if ( m_pVB->CanUpdate() )
        m_pVB->Update( 0, INVALID_OFFSET, pContext );
    else
        m_pVB->UnLock( pContext );
}
Beispiel #17
0
	/* Normalize */
	Vector4 Normalize(Vector4 toNorm) {
		toNorm.Normalize();
		return toNorm;
	}
Beispiel #18
0
	Vector4 Vector4::Normalize( Vector4 vector )
	{
		vector.Normalize();
		return vector;
	}