/** * * @param P0 * @param P1 * @param P2 * @param P * @param n * @return * * @see http://www.cs.cornell.edu/courses/cs465/2003fa/homeworks/raytri.pdf */ bool isInsideTheTriangle(Vector4& P0, Vector4& P1, Vector4& P2, Vector4& P, Vector4& n){ //Vector from one vertex to other vertex. auto_ptr<Vector4> Edge01(P0.Subtract(P1, P0)); auto_ptr<Vector4> Edge12(P1.Subtract(P2, P1)); auto_ptr<Vector4> Edge20(P2.Subtract(P0, P2)); //Vector from one vertex to the point of intersection. auto_ptr<Vector4> X0(P.Subtract(P,P0)); auto_ptr<Vector4> X1(P.Subtract(P,P1)); auto_ptr<Vector4> X2(P.Subtract(P,P2)); //Cross Products of the above two. auto_ptr<Vector4> Product1(Edge01->CrossProduct(*Edge01, *X0)); auto_ptr<Vector4> Product2(Edge12->CrossProduct(*Edge12, *X1)); auto_ptr<Vector4> Product3(Edge20->CrossProduct(*Edge20, *X2)); //Dot product with normals. double d1 = Product1->DotProduct(*Product1, n); double d2 = Product2->DotProduct(*Product2, n); double d3 = Product3->DotProduct(*Product3, n); if((d1>=0 and d2>=0 and d3>=0) or (d1<=0 and d2<=0 and d3<=0)){ return true; }else{ return false; } }
Vector4* findReflectedRayDirection(Vector4 &N, Vector4& L){ Vector4* R; Vector4* Rtemp = new Vector4(); Rtemp->SetVector4(0,0,0,1); Rtemp->GetCopyOf(N); double N_dot_L = N.DotProduct(N,L); Rtemp->Elongate(2*N_dot_L); R = Rtemp->Subtract(*Rtemp,L); delete Rtemp; return R; }
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); } } }