geom::FieldCell<Scal> CalcRadiationField( const Mesh& mesh, const geom::MapFace<std::shared_ptr<solver::ConditionFace>>& mf_cond_radiation_shared, const geom::FieldCell<Scal>& fc_absorption_rate, Vect radiation_direction, geom::FieldCell<Scal> initial_guess) { if (radiation_direction.norm() == 0.) { return initial_guess; } radiation_direction /= radiation_direction.norm(); geom::FieldFace<Scal> ff_flux(mesh); for (auto idxface : mesh.Faces()) { ff_flux[idxface] = radiation_direction.dot(mesh.GetSurface(idxface)); } Scal time_step = 1e16; for (auto idxcell : mesh.Cells()) { for (size_t i = 0; i < mesh.GetNumNeighbourFaces(idxcell); ++i) { auto idxface = mesh.GetNeighbourFace(idxcell, i); Vect vect = mesh.GetCenter(idxcell) - mesh.GetCenter(idxface); Scal vel_dot_vect = std::abs(radiation_direction.dot(vect)); if (vel_dot_vect != 0.) { time_step = std::min(time_step, vect.sqrnorm() / vel_dot_vect); } } } geom::FieldCell<Scal> fc_source(mesh, 0.); solver::AdvectionSolverExplicit<Mesh, geom::FieldFace<Scal>> advection( mesh, initial_guess, mf_cond_radiation_shared, &ff_flux, &fc_source, 0., time_step); Scal error = 1e16; size_t count = 0; for (; count < 10 && error > 1e-3; ++count) { for (auto idxcell : mesh.Cells()) { fc_source[idxcell] = -fc_absorption_rate[idxcell] * advection.GetField()[idxcell]; } advection.StartStep(); advection.MakeIteration(); error = advection.GetConvergenceIndicator(); advection.FinishStep(); } return advection.GetField(); }
const bool Quat::isNormalized(const float precision) { bool answer = false; Vect tmp (this->qx, this->qy, this->qz); if ( fabs((this->qw * this->qw) + tmp.dot(tmp)) - 1 <= precision ) answer = true; return answer; };
TEST( VectCrossAddSubMatrixMultCross, combo_tests ) { Vect A(1.0f, 2.0f, 3.0f, 5.0f); Vect B(10.0f, 11.0f, 12.0f, 13.0f); Vect C; CHECK( A[x] == 1.0f ); CHECK( A[y] == 2.0f ); CHECK( A[z] == 3.0f ); CHECK( A[w] == 5.0f ); CHECK( B[x] == 10.0f ); CHECK( B[y] == 11.0f ); CHECK( B[z] == 12.0f ); CHECK( B[w] == 13.0f ); C = A + (A-B).cross(B); Vect D = C.dot(A) * B; CHECK( D[x] == 140.0f ); CHECK( D[y] == 154.0f ); CHECK( D[z] == 168.0f ); CHECK( D[w] == 1.0f ); CHECK( C[x] == -8.0f ); CHECK( C[y] == 20.0f ); CHECK( C[z] == -6.0f ); CHECK( C[w] == 1.0f ); CHECK( A[x] == 1.0f ); CHECK( A[y] == 2.0f ); CHECK( A[z] == 3.0f ); CHECK( A[w] == 5.0f ); CHECK( B[x] == 10.0f ); CHECK( B[y] == 11.0f ); CHECK( B[z] == 12.0f ); CHECK( B[w] == 13.0f ); Matrix M(A,B,C,D); A = Vect(1.0f, 0.0f, 4.0f,1.0f).cross(B * M); CHECK( A[x] == -9532.0f ); CHECK( A[y] == 5102.0f ); CHECK( A[z] == 2383.0f ); CHECK( A[w] == 1.0f ); }
void SphereOfSphereAndPt(Sphere &s, Vect &p) { // Compute squared distance between point and sphere center Vect d = p - s.cntr; float dist2 = d.dot( d); // Only update s if point p is outside it if (dist2 > s.rad * s.rad) { float dist = sqrtf(dist2); float newRadius = (s.rad + dist) * 0.5f; float k = (newRadius - s.rad) / dist; s.rad = newRadius; s.cntr += d * k; } }
Color traceRay(Ray* ray, Scene* scene, int objectCount, int lightCount, int maxBounces, double ambientLighting) { Color shaderResult (0,0,0); Ray* shadowRay = new Ray(); Ray* reflectionRay = new Ray(); RayIntersection primaryObjectHit = testRayIntersection(ray, scene, objectCount, 0, MINIMAL_DISTANCE); if(primaryObjectHit.objectId >= 0) { Object* sceneObject = scene->getObjectList().at(primaryObjectHit.objectId); // calulate brightness and specularity Color specular (0,0,0); Color diffuse (0,0,0); Color reflection (0,0,0); Vect intersectionPoint = primaryObjectHit.location; Color ambient = sceneObject->getColorAt(intersectionPoint).scale(ambientLighting); shadowRay->setOrigin(intersectionPoint); Vect normalAtIntersection = sceneObject->getNormalAt(intersectionPoint); Vect reflectionDirection = ray->getReflectingDirection(normalAtIntersection); double lightImportance = 1; if(lightCount > 1) { lightImportance = 1.0 / lightCount; } for(int lightIndex = 0; lightIndex < lightCount; lightIndex++) { Light *lightSource = scene->getLightList().at(lightIndex); Vect pointToLightVect = lightSource->getPosition().subtract(intersectionPoint); Vect lightDirection = pointToLightVect.normalize(); // Test if light is visible or hidden to render shadows double diffuseFactor = normalAtIntersection.dot(lightDirection); double specularFactor = reflectionDirection.dot(lightDirection); bool shadowed = false; if(diffuseFactor > 0) // object is facing the light source - add diffuse { // check if it is shadowed; shadowRay->setDirection(lightDirection); double lightDistance = pointToLightVect.magnitude(); shadowed = (testRayIntersection(shadowRay, scene, objectCount, lightDistance, MINIMAL_DISTANCE).objectId > -1); } if(!shadowed && diffuseFactor > 0) { diffuse = diffuse.add(sceneObject->getColorAt(intersectionPoint).scale(diffuseFactor)); } if(!shadowed && specularFactor > 0 && sceneObject->getMaterial().getRoughness() > 0) { specular = specular.add(lightSource->getColor().scale(pow(specularFactor, 10) * sceneObject->getMaterial().getRoughness())); } } if(maxBounces > 0 && sceneObject->getMaterial().getReflectivity() > 0) { reflectionRay->setOrigin(intersectionPoint); reflectionRay->setDirection(reflectionDirection); reflection = traceRay(reflectionRay, scene, objectCount, lightCount, --maxBounces, ambientLighting).scale(sceneObject->getMaterial().getReflectivity() * 0.25); } shaderResult = ambient.add(diffuse).add(specular).add(reflection).normalize(); } else { shaderResult = scene->getBackgroundColor(); } delete shadowRay; delete reflectionRay; return shaderResult; }
bool PyramidObject::checkCulling( void ) { Vect center = this->pyramidModel->cullC; center *= this->LocalToWorld; float radius = this->pyramidModel->cullR; ///////////////////////////////////////////////////////////////////GET NON UNIFORM SCALE OF RADIUS/////////////////////////////////////////////////////////////////// float scale_x = (this->LocalToWorld.m0 * this->LocalToWorld.m0) + (this->LocalToWorld.m1 * this->LocalToWorld.m1) + (this->LocalToWorld.m2 * this->LocalToWorld.m2); scale_x = sqrt(scale_x); float scale_y = (this->LocalToWorld.m4 * this->LocalToWorld.m4) + (this->LocalToWorld.m5 * this->LocalToWorld.m5) + (this->LocalToWorld.m6 * this->LocalToWorld.m6); scale_y = sqrt(scale_y); float scale_z = (this->LocalToWorld.m8 * this->LocalToWorld.m8) + (this->LocalToWorld.m9 * this->LocalToWorld.m9) + (this->LocalToWorld.m10 * this->LocalToWorld.m10); scale_z = sqrt(scale_z); if (scale_x > scale_y && scale_x > scale_z) radius *= scale_x; else if (scale_y > scale_x && scale_y > scale_z) radius *= scale_y; else radius *= scale_z; ////////////////////////////////////////////////////////////////CACLCULATE POINTS ON SPHERE//////////////////////////////////////////////////////////////////////////// Vect pX = center + (Vect(1.0, 0.0, 0.0) * this->pyramidModel->cullR); Vect pY = center + (Vect(0.0, 1.0, 0.0) * this->pyramidModel->cullR); Vect pZ = center + (Vect(0.0, 0.0, 1.0) * this->pyramidModel->cullR); pX *= this->LocalToWorld; pY *= this->LocalToWorld; pZ *= this->LocalToWorld; Vect FTR; Vect NBL; pCamera->getNearBottomLeft(NBL); pCamera->getFarTopRight(FTR); ///////////////////////////////////////////////////////////////CHECK IF IN FRUSTRUM///////////////////////////////////////////////////////////////////////////////////// Vect Normal; float Result; Vect Distance = (center - NBL); pCamera->getBottomNorm(Normal); Result = Distance.dot(Normal); if (Result > radius) return true; pCamera->getLeftNorm(Normal); Result = Distance.dot(Normal); if (Result > radius) return true; pCamera->getFrontNorm(Normal); Result = Distance.dot(Normal); if (Result > radius) return true; Distance = (center - FTR); pCamera->getBackNorm(Normal); Result = Distance.dot(Normal); if (Result > radius) return true; pCamera->getRightNorm(Normal); Result = Distance.dot(Normal); if (Result > radius) return true; pCamera->getTopNorm(Normal); Result = Distance.dot(Normal); if (Result > radius) return true; return false; }
const void Quat::Lqvqc(const Vect &vIn, Vect &vOut) { Vect tmp (this->qx, this->qy, this->qz); vOut = ((2 * this->qw) * vIn.cross(tmp)) + (((this->qw * this->qw) - tmp.dot(tmp)) * vIn) + 2 * (tmp.dot(vIn)) * tmp; };
const void Quat::operator *= (const Quat &q) { Vect vLeft (this->qx, this->qy, this->qz); Vect vRight (q.qx, q.qy, q.qz); *this = Quat(Vect(vRight.cross(vLeft) + (q.qw * vLeft) + (this->qw * vRight)), (this->qw * q.qw) - vLeft.dot(vRight)); };
const Quat Quat::operator * (const Quat &q)const { Vect vLeft (this->qx, this->qy, this->qz); Vect vRight (q.qx, q.qy, q.qz); return Quat(Vect(vRight.cross(vLeft) + (q.qw * vLeft) + (this->qw * vRight)), (this->qw * q.qw) - vLeft.dot(vRight)); };