//------------------------------------------------------------------------------ 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; }
//------------------------------------------------------------------------------ CColor4 CStaticIlluminator::DirectLighting( const sMaterial& material, const CVector3f& position, const CVector3f& normal ) { float NdotL = normal.Dot(-this->globalLight.getDIRECTION()); CColor4 diffuse = this->ambient * material.Ambient + this->globalLight.GetColor() * max(NdotL, 0.0f) * material.Diffuse; return diffuse; }
// looking for silhouettes recursively void TXOctree::FindSilhouettes(const CVector3f& n, float d, std::vector<TXEdge*>& silhouettes, float bias) { if (m_isLeaf) { TXEdge* e; for (ULONG i = 0; i <m_edges.size(); i++) { if (!m_edges[i]->IsChecked()) { m_edges[i]->Check(); bool b1 = n.Dot(m_edges[i]->GetDualPosition(0)) + d >= bias; bool b2 = n.Dot(m_edges[i]->GetDualPosition(1)) + d >= bias; e = m_edges[i]->GetEdge(); if (b1 != b2) { e->m_issilhouette = true; silhouettes.push_back(e); } else e->m_issilhouette = false; } } } else { for (int i = 0; i < 8; i++) { if (m_child[i]) if (m_child[i]->TouchPlane(n, d,bias)) m_child[i]->FindSilhouettes(n, d, silhouettes,bias); } } }
// intersect a ray with the mesh bool TXGrid3D::IntersectRay(const CVector3f& start, const CVector3f& end) { // pick rays m_rays.push_back(TXRay(start, end)); CVector3f dir; dir.Sub(start,end); int idir[3] = { fabs(dir.GetX()) < DBL_EPSILON ? 0 : (dir.GetX() > 0 ? 1 : -1), fabs(dir.GetY()) < DBL_EPSILON ? 0 : (dir.GetY() > 0 ? 1 : -1), fabs(dir.GetZ()) < DBL_EPSILON ? 0 : (dir.GetZ() > 0 ? 1 : -1) }; double dist = 0; CVector3f pos; pos.Sub(end, m_min); int ix = (int)floor((end.GetX() - m_min.GetX())/m_xstep), iy = (int)floor((end.GetY() - m_min.GetY())/m_ystep), iz = (int)floor((end.GetZ() - m_min.GetZ())/m_zstep); double tx = 1.0, ty = 1.0, tz = 1.0; // first cell ix = MIN(MAX(ix, 0), m_size-1); iy = MIN(MAX(iy, 0), m_size-1); iz = MIN(MAX(iz, 0), m_size-1); // intersection test, from end to start while ((dist < 1) && (ix >= 0) && (ix < m_size) &&(iy >= 0) && (iy < m_size) && (iz >= 0) && (iz < m_size)) { int csz = m_grid[ix][iy][iz].size(); for (int i=0; i<csz; i++) { TXGridTriangle* gt = m_grid[ix][iy][iz][i]; double rpdot = dir.Dot(gt->m_n); if (rpdot != 0) { CVector3f tmp; tmp.Sub(gt->m_t->m_v[0]->m_pos,end); double t = tmp.Dot(gt->m_n) / rpdot; if (t > DBL_EPSILON && t < 1) { CVector3f pt; pt.ScaleAdd(t,dir,end); CVector3f pt0,pt1,pt2; pt0.Sub(pt,gt->m_t->m_v[0]->m_pos); pt1.Sub(pt,gt->m_t->m_v[1]->m_pos); pt2.Sub(pt,gt->m_t->m_v[2]->m_pos); if (pt0.Dot(gt->m_en1)> -DBL_EPSILON && pt1.Dot(gt->m_en2)>-DBL_EPSILON && pt2.Dot(gt->m_en3)>-DBL_EPSILON) { m_rays[m_rays.size()-1].m_p = t; return true; } } } } // next cell if (idir[0] != 0) tx = (m_min.GetX() + (ix+(idir[0]+1)/2)*m_xstep - end.GetX()) / dir.GetX(); if (idir[1] != 0) ty = (m_min.GetY() + (iy+(idir[1]+1)/2)*m_ystep - end.GetY()) / dir.GetY(); if (idir[2] != 0) tz = (m_min.GetZ() + (iz+(idir[2]+1)/2)*m_zstep - end.GetZ()) / dir.GetZ(); if ((tx <= ty) && (tx <= tz)) { dist = tx, ix += idir[0]; if (ty == tx) iy += idir[1]; if (tz == tx) iz += idir[2]; } else if (ty <= tz) { dist = ty, iy += idir[1]; if (tz == ty) iz += idir[2]; } else dist = tz, iz += idir[2]; } return false; }