//------------------------------------------------------------------------------------------------------ //function that multiplies two Matrix objects together //------------------------------------------------------------------------------------------------------ Matrix4D& Matrix4D::operator*(Matrix4D& rhs) { //variable to keep track of each matrix element of final result int count = 0; //the final matrix result object and two Vector4D objects //are needed to calculate each row and column multiplication Matrix4D result; Vector4D<float> leftRow; Vector4D<float> topColumn; //loop through each of the top matrix columns for(int i = 0; i < 4; i++) { //assign the elements from top to bottom topColumn.X = rhs[i * 4]; topColumn.Y = rhs[i * 4 + 1]; topColumn.Z = rhs[i * 4 + 2]; topColumn.W = rhs[i * 4 + 3]; //loop through each of the left matrix rows for(int j = 0; j < 4; j++) { //assign the elements from left to right leftRow.X = m_matrix[j]; leftRow.Y = m_matrix[j + 4]; leftRow.Z = m_matrix[j + 8]; leftRow.W = m_matrix[j + 12]; //use dot product to produce each matrix element result result[count++] = leftRow.DotProduct(topColumn); } } //assign result to Matrix object and return reference //of lhs matrix to allow for multiplication chaining return (*this = result); }
//------------------------------------------------------------------------------------------------------ //function that multiplies a Matrix object by a Vector4D object //------------------------------------------------------------------------------------------------------ Vector4D<float> Matrix4D::operator*(const Vector4D<float>& rhs) { //temp result to be stored in a float array instead of a //4D vector because the array can then be used inside a loop float tempResult[4]; //variables for final result //and temp matrix row Vector4D<float> result; Vector4D<float> matrixRow; //loop through each of the left matrix rows for(int i = 0; i < 4; i++) { //assign the elements from left to right matrixRow.X = m_matrix[i]; matrixRow.Y = m_matrix[i + 4]; matrixRow.Z = m_matrix[i + 8]; matrixRow.W = m_matrix[i + 12]; //use dot product to produce each vector element result tempResult[i] = matrixRow.DotProduct(rhs); } //assign each temp result array element to Vector4D object result.X = tempResult[0]; result.Y = tempResult[1]; result.Z = tempResult[2]; result.W = tempResult[3]; return result; }
void CRenderObjectsManager::ProcessLighting(CRenderObject* pobj,POLYGON& poly) { VERTICESLIST &pointlist = pobj->m_translateverticesList; int v_index1 = poly.v[0]; int v_index2 = poly.v[1]; int v_index3 = poly.v[2]; //Get the original r,g,b,a bool bHasTexture = poly.state & OBJECT_HAS_TEXTURE; UCHAR r_base = bHasTexture ?255:poly.color.r; UCHAR g_base = bHasTexture ? 255:poly.color.g; UCHAR b_base = bHasTexture?255: poly.color.b; UCHAR a_base = bHasTexture?0:poly.color.a;//to do.modify here int r_sum=0,g_sum = 0,b_sum = 0; int ilightsize = m_pLightingManager->GetLightsCount(); const LIGHTSLIST& lightslist = m_pLightingManager->GetLights(); CLight *light = NULL; //Get the normal direction Vector4D P0P1 = pointlist[v_index2].vertex - pointlist[v_index1].vertex; Vector4D P1P2 = pointlist[v_index3].vertex - pointlist[v_index1].vertex; Vector4D N = P0P1.CrossProduct(P1P2); N.Normalize(); for(int i = 0; i < ilightsize;++i) { light = lightslist[i]; if(!light->IsEnable()) continue; //Get the cos value of the angle between the light and normal Vector4D lightdir = light->m_lightdir; float coslight2normal = N.DotProduct(-1*lightdir); const CLight::LightType lighttype = light->GetLightType(); if(lighttype == CLight::kAmbientLight) { r_sum += ((light->m_amblient.r * r_base)/256); g_sum += ((light->m_amblient.g * g_base)/256); b_sum += ((light->m_amblient.b * b_base)/256); } if(lighttype == CLight::kInfiniteLigtht) { if(coslight2normal>0) { r_sum += ((light->m_diffuse.r * r_base *coslight2normal)/256); g_sum += ((light->m_diffuse.g * g_base*coslight2normal)/256); b_sum += ((light->m_diffuse.b * b_base*coslight2normal)/256); } } if(lighttype == CLight::kPointLight) { // c = c_diffuse * I/(kc+kl*d+kq*d^2); // Vector4D vertex2lightpos = Vector4D(light->m_lightpos- pointlist[v_index1].vertex); float d = vertex2lightpos.GetLength(); float l = vertex2lightpos.DotProduct(N); float cosv = N.DotProduct(vertex2lightpos); if(cosv >0) { cosv = cosv/d; float k = light->m_kconst + light->m_klinear * d + light->m_kquadratic*d*d; float fDiv = k*256;//k*256 r_sum += ((light->m_diffuse.r * r_base *cosv)/fDiv); g_sum += ((light->m_diffuse.g * g_base*cosv)/fDiv); b_sum += ((light->m_diffuse.b * b_base*cosv)/fDiv); } } if(lighttype == CLight::kSpotLight) { //use this model // c = c_diffuse * I*MAX(COSa,0)^pf/(kc+kl*d+kq*d^2) float l = N.DotProduct(-1*lightdir); if(l >0) { Vector4D vertex2lightpos = Vector4D(light->m_lightpos-pointlist[v_index1].vertex ); float d = vertex2lightpos.GetLength(); //calculate the cos value of light direction and vertext->lightpos float l = N.DotProduct(vertex2lightpos); if(l > 0) { float cosv = l/d; float dl = cosv; for(int i = 1; i < light->m_pf;++i) dl *= cosv; float k = light->m_kconst + light->m_klinear * d + light->m_kquadratic*d*d; float fDiv = k*256;//k*256 r_sum += ((light->m_diffuse.r * r_base *dl)/fDiv); g_sum += ((light->m_diffuse.g * g_base*dl)/fDiv); b_sum += ((light->m_diffuse.b * b_base*dl)/fDiv); } } } } if(r_sum >255) r_sum = 255; if(g_sum > 255) g_sum = 255; if(b_sum > 255) b_sum = 255; poly.ret_color = RGBA(r_sum,g_sum,b_sum,0.0); }