//------------------------------------------------------------------------------ CColor4 CStaticIlluminator::SpotLighting( const sMaterial& material, const CVector3f& position, const CVector3f& normal ) { CColor4 color = CColor4::Black; for (vector<CLight>::iterator it = this->spotLights.begin(); it != this->spotLights.end(); ++it) { CLight& light = *it; LightStruct &tLight = *(light.GetLightStruct()); CVector3f direction = tLight.Position - position; float distance = direction.Mag(); if (tLight.Range < distance) continue; direction.Normalize(); float NdotL = direction.Dot(normal); NdotL = max(NdotL, 0.0f); float attenuation = 1.0f / (tLight.Attenuation0 + tLight.Attenuation1 * distance + tLight.Attenuation2 * distance * distance); // spot tLight factor float cosAlpha = (-direction).Dot(tLight.Direction); float cosHalfPhi = cos(tLight.Phi * 0.5f); if (cosAlpha <= cosHalfPhi) continue; float cosHalfTheta = cos(tLight.Theta * 0.5f); float intensity = (cosAlpha - cosHalfPhi) / (cosHalfTheta - cosHalfPhi); intensity = pow(intensity, tLight.Falloff); color += tLight.Diffuse * material.Diffuse * NdotL * attenuation * intensity; } return color; }
//------------------------------------------------------------------------------ CColor4 CStaticIlluminator::PointLighting( const sMaterial& material, const CVector3f& position, const CVector3f& normal ) { CColor4 color = CColor4::Black; for (vector<CLight>::iterator it = this->pointLights.begin(); it != this->pointLights.end(); ++it) { CLight& light = *it; CVector3f direction = light.GetPosition() - position; float distance = direction.Mag(); if (light.GetRange() < distance) continue; direction.Normalize(); float NdotL = direction.Dot(normal); NdotL = max(NdotL, 0.0f); LightStruct &tLight = *(light.GetLightStruct()); float attenuation = 1.0f / (tLight.Attenuation0 + tLight.Attenuation1 * distance + tLight.Attenuation2 * distance * distance); color += tLight.Diffuse * material.Diffuse * NdotL * attenuation; } return color; }
void CCamera::lookTo( const CVector3f& fVector ) { if (CVector3f::ZERO == fVector) return; if (m_bYawFixed) { CVector3f dirFixed = fVector; dirFixed.Normalize(); CVector3f xVec,yVec; CMatrix kRot; xVec = m_vYawFixed.Cross(dirFixed); xVec.Normalize(); yVec = dirFixed.Cross(xVec); yVec.Normalize(); m_Quaternion.FromAxes( xVec,yVec,dirFixed ); m_bNeedUpdate = true; } else { setDIRECTION(fVector); } }
/** Initialize the plane from a points and a normal vector */ Void CPlane::Set( const CVector3f& pos, const CVector3f& norm ) { CVector3f n = norm; n.Normalize(); m_Coef.SetX( n.GetX() ); m_Coef.SetY( n.GetY() ); m_Coef.SetZ( n.GetZ() ); m_Coef.SetW( -(m_Coef.GetX()*pos.GetX() + m_Coef.GetY()*pos.GetY() + m_Coef.GetZ()*pos.GetZ() ) ); }
/** "Intersecting a Ray with a Cylinder" by Joseph M. Cychosz and Warren N. Waggenspack, Jr., ([email protected], [email protected]) in "Graphics Gems IV", Academic Press, 1994 */ Float32 CCylinder::Intersect( const CRay& r ) { Float32 in, out; Bool hit; // True if ray intersects cyl CVector3f rc; // Ray base to cylinder base Float32 dist; // Shortest distance between Float32 t, s; // Distances along the ray CVector3f n, o; Float32 ln; CVector3f axis = GetAxis(); rc = r.Origin - PointA; n.CrossProduct( r.Direction, axis ); ln = n.GetLength(); if ( ln == 0.0f ) { CVector3f tmp; // ray parallel to cyl dist = rc.DotProduct( axis ); tmp = rc - axis * dist; dist = tmp.GetLength(); in = -FLOAT32_MAX_VAL; out = FLOAT32_MAX_VAL; if( dist <= Radius ) // true if ray is in cyl { return 1.0; } } n.Normalize(); dist = MathAbs( rc.DotProduct( n ) ); // shortest distance hit = (dist <= Radius); if (hit) { // if ray hits cylinder o.CrossProduct( rc, axis ); t = - o.DotProduct( n ) / ln; o.CrossProduct( n, axis ); o.Normalize(); s = MathAbs( MathSqrt( Radius*Radius - dist*dist) / r.Direction.DotProduct( o ) ); in = t - s; // entering distance out = t + s; // exiting distance // Test for capped cylinder CVector3f intersection = r.Origin + r.Direction * in; CVector3f cylBaseToInter = intersection - PointA; ln = cylBaseToInter.GetLength(); cylBaseToInter.Normalize(); if( axis.DotProduct( cylBaseToInter ) >= 0.0f ) { Float32 cylLength = CVector3f( PointA-PointB ).GetLength(); if( ln <= cylLength ) return in; } } return -1.0f; }
CVector3f CCylinder::GetAxis() const { CVector3f tmp = PointB - PointA; tmp.Normalize(); return tmp; }