bool Raytracer::isInSpotlight(const GLight& light, const Vector3 w_i) const { bool returnValue = false; // Spotlight const bool firstTerm = light.spotHalfAngle < halfPi(); const float lightIn_dot_spotDirection = -w_i.dot(light.spotDirection); const float cosSpotHalfAngle = cosf(light.spotHalfAngle); const bool secondTerm = lightIn_dot_spotDirection < cosSpotHalfAngle; const bool outsideSpotLight = firstTerm && secondTerm; if (!outsideSpotLight) { returnValue = true; } return returnValue; }
void App::setViewer(const G3D::String& newFilename) { logPrintf("App::setViewer(\"%s\")\n", filename.c_str()); drawMessage("Loading " + newFilename); filename = newFilename; m_debugCamera->setFrame(CFrame::fromXYZYPRDegrees(-11.8f, 25.2f, 31.8f, -23.5f, -39.0f, 0.0f)); m_debugController->setFrame(m_debugCamera->frame()); //modelController->setFrame(CoordinateFrame(Matrix3::fromAxisAngle(Vector3(0,1,0), toRadians(180)))); delete viewer; viewer = NULL; if (filename == "<events>") { viewer = new EventViewer(); } else { G3D::String ext = toLower(filenameExt(filename)); G3D::String base = toLower(filenameBase(filename)); if ((ext == "3ds") || (ext == "ifs") || (ext == "obj") || (ext == "ply2") || (ext == "off") || (ext == "ply") || (ext == "bsp") || (ext == "stl") || (ext == "lwo") || (ext == "stla") || (ext == "dae") || (ext == "fbx") || (ext == "any" && endsWith(base, ".material")) || (ext == "any" && endsWith(base, ".universalmaterial")) || ((ext == "any" && endsWith(base, ".am")) || (ext == "any" && endsWith(base, ".articulatedmodel")))) { showDebugText = false; viewer = new ArticulatedViewer(); } else if (Texture::isSupportedImage(filename)) { // Images can be either a Texture or a Sky, TextureViewer will figure it out viewer = new TextureViewer(); // Angle the camera slightly so a sky/cube map doesn't see only 1 face m_debugController->setFrame(Matrix3::fromAxisAngle(Vector3::unitY(), (float)halfPi() / 2.0f) * Matrix3::fromAxisAngle(Vector3::unitX(), (float)halfPi() / 2.0f)); } else if (ext == "fnt") { viewer = new FontViewer(debugFont); /* } else if (ext == "bsp") { viewer = new BSPViewer(); */ } else if (ext == "md2") { viewer = new MD2Viewer(); } else if (ext == "md3") { viewer = new MD3Viewer(); } else if (ext == "gtm") { viewer = new GUIViewer(this); } else if (ext == "icn") { viewer = new IconSetViewer(debugFont); } else if (ext == "pk3") { // Something in Quake format - figure out what we should load Array <String> files; bool set = false; // First, try for a .bsp map G3D::String search = filename + "/maps/*"; FileSystem::getFiles(search, files, true); for (int t = 0; t < files.length(); ++t) { if (filenameExt(files[t]) == "bsp") { filename = files[t]; viewer = new ArticulatedViewer(); set = true; } } if (! set) { viewer = new EmptyViewer(); } } else if (ext == "avi" || ext == "wmv" || ext == "mp4" || ext == "asf" || (ext == "mov") || (ext == "dv") || (ext == "qt") || (ext == "asf") || (ext == "mpg")) { viewer = new VideoViewer(); } else { viewer = new EmptyViewer(); } } if (viewer != NULL) { viewer->onInit(filename); } if (filename != "") { if (filename == "<events>") { window()->setCaption("Events - G3D Viewer"); } else { window()->setCaption(filenameBaseExt(filename) + " - G3D Viewer"); } } logPrintf("Done App::setViewer(...)\n"); }
void ShadowMap::computeMatrices (const shared_ptr<Light>& light, AABox sceneBounds, CFrame& lightFrame, Projection& lightProjection, Matrix4& lightProjectionMatrix, float lightProjX, float lightProjY, float lightProjNearMin, float lightProjFarMax, float intensityCutoff) { if (! sceneBounds.isFinite() || sceneBounds.isEmpty()) { // Produce some reasonable bounds sceneBounds = AABox(Point3(-20, -20, -20), Point3(20, 20, 20)); } lightFrame = light->frame(); if (light->type() == Light::Type::DIRECTIONAL) { Point3 center = sceneBounds.center(); if (! center.isFinite()) { center = Point3::zero(); } // Move directional light away from the scene. It must be far enough to see all objects lightFrame.translation = -lightFrame.lookVector() * min(1e6f, max(sceneBounds.extent().length() / 2.0f, lightProjNearMin, 30.0f)) + center; } const CFrame& f = lightFrame; float lightProjNear = finf(); float lightProjFar = 0.0f; // TODO: for a spot light, only consider objects this light can see // Find nearest and farthest corners of the scene bounding box for (int c = 0; c < 8; ++c) { const Vector3& v = sceneBounds.corner(c); const float distance = -f.pointToObjectSpace(v).z; lightProjNear = min(lightProjNear, distance); lightProjFar = max(lightProjFar, distance); } // Don't let the near get too close to the source, and obey // the specified hint. lightProjNear = max(lightProjNearMin, lightProjNear); // Don't bother tracking shadows past the effective radius lightProjFar = min(light->effectSphere(intensityCutoff).radius, lightProjFar); lightProjFar = max(lightProjNear + 0.1f, min(lightProjFarMax, lightProjFar)); debugAssert(lightProjNear < lightProjFar); if (light->type() != Light::Type::DIRECTIONAL) { // TODO: Square spot // Spot light; we can set the lightProj bounds intelligently alwaysAssertM(light->spotHalfAngle() <= halfPi(), "Spot light with shadow map and greater than 180-degree bounds"); // The cutoff is half the angle of extent (See the Red Book, page 193) const float angle = light->spotHalfAngle(); lightProjX = tan(angle) * lightProjNear; // Symmetric in x and y lightProjY = lightProjX; lightProjectionMatrix = Matrix4::perspectiveProjection (-lightProjX, lightProjX, -lightProjY, lightProjY, lightProjNear, lightProjFar); } else if (light->type() == Light::Type::DIRECTIONAL) { // Directional light // Construct a projection and view matrix for the camera so we can // render the scene from the light's point of view // // Since we're working with a directional light, // we want to make the center of projection for the shadow map // be in the direction of the light but at a finite distance // to preserve z precision. lightProjectionMatrix = Matrix4::orthogonalProjection (-lightProjX, lightProjX, -lightProjY, lightProjY, lightProjNear, lightProjFar); } else { // Omni light. Nothing good can happen here, but at least we // generate something lightProjectionMatrix = Matrix4::perspectiveProjection (-lightProjX, lightProjX, -lightProjY, lightProjY, lightProjNear, lightProjFar); } float fov = atan2(lightProjX, lightProjNear) * 2.0f; lightProjection.setFieldOfView(fov, FOVDirection::HORIZONTAL); lightProjection.setNearPlaneZ(-lightProjNear); lightProjection.setFarPlaneZ(-lightProjFar); }
void App::setViewer(const std::string& newFilename) { filename = newFilename; defaultCamera.setCoordinateFrame(CoordinateFrame(Vector3(0,0,5))); defaultController->setFrame(CoordinateFrame(Vector3(0,0,5))); //modelController->setFrame(CoordinateFrame(Matrix3::fromAxisAngle(Vector3(0,1,0), toRadians(180)))); delete viewer; viewer = NULL; shadowMap->setSize(0); std::string ext = toLower(filenameExt(filename)); std::string base = toLower(filenameBase(filename)); if ((ext == "3ds") || (ext == "ifs") || (ext == "obj") || (ext == "ply2") || (ext == "off") || (ext == "ply") || (ext == "any" && endsWith(base, ".am"))) { shadowMap->setSize(2048); viewer = new ArticulatedViewer(); } else if (Texture::isSupportedImage(filename)) { // Images can be either a Texture or a Sky, TextureViewer will figure it out viewer = new TextureViewer(); // Angle the camera slightly so a sky/cube map doesn't see only 1 face defaultController->setFrame(Matrix3::fromAxisAngle(Vector3::unitY(), halfPi() / 2.0) * Matrix3::fromAxisAngle(Vector3::unitX(), halfPi() / 2.0)); } else if (ext == "fnt") { viewer = new FontViewer(debugFont); } else if (ext == "bsp") { viewer = new BSPViewer(); } else if (ext == "md2") { viewer = new MD2Viewer(); } else if (ext == "gtm") { viewer = new GUIViewer(this); } else if (ext == "icn") { viewer = new IconSetViewer(debugFont); } else if (ext == "pk3") { // Something in Quake format - figure out what we should load Array <std::string> files; bool set = false; // First, try for a .bsp map std::string search = filename + "/maps/*"; FileSystem::getFiles(search, files, true); for (int t = 0; t < files.length(); ++t) { if (filenameExt(files[t]) == "bsp") { filename = files[t]; viewer = new BSPViewer(); set = true; } } if (!set) { viewer = new EmptyViewer(); } } else if (ext == "avi" || ext == "wmv" || ext == "mp4" || ext == "asf" || (ext == "mov") || (ext == "dv") || (ext == "qt") || (ext == "asf") || (ext == "mpg")) { viewer = new VideoViewer(); } else { viewer = new EmptyViewer(); } if (viewer != NULL) { viewer->onInit(filename); } window()->setCaption(filenameBaseExt(filename) + " - G3D Viewer"); }