Example #1
0
Sphere GLight::effectSphere(float cutoff) const {
    if (position.w == 0) {
        // Directional light
        return Sphere(Vector3::zero(), finf());
    } else {
        // Avoid divide by zero
        cutoff = max(cutoff, 0.00001f);
        float maxIntensity = max(color.r, max(color.g, color.b));

        float radius = finf();
            
        if (attenuation[2] != 0) {

            // Solve I / attenuation.dot(1, r, r^2) < cutoff for r
            //
            //  a[0] + a[1] r + a[2] r^2 > I/cutoff
            //
            
            float a = attenuation[2];
            float b = attenuation[1];
            float c = attenuation[0] - maxIntensity / cutoff;
            
            float discrim = square(b) - 4 * a * c;
            
            if (discrim >= 0) {
                discrim = sqrt(discrim);
                
                float r1 = (-b + discrim) / (2 * a);
                float r2 = (-b - discrim) / (2 * a);

                if (r1 < 0) {
                    if (r2 > 0) {
                        radius = r2;
                    }
                } else if (r2 > 0) {
                    radius = min(r1, r2);
                } else {
                    radius = r1;
                }
            }
                
        } else if (attenuation[1] != 0) {
            
            // Solve I / attenuation.dot(1, r) < cutoff for r
            //
            // r * a[1] + a[0] = I / cutoff
            // r = (I / cutoff - a[0]) / a[1]

            float radius = (maxIntensity / cutoff - attenuation[0]) / attenuation[1];
            radius = max(radius, 0.0f);
        }

        return Sphere(position.xyz(), radius);

    }
}
Example #2
0
bool ArticulatedViewer::onEvent(const GEvent& e, App* app) {
    if ((e.type == GEventType::MOUSE_BUTTON_DOWN) && (e.button.button == 0) && ! app->userInput->keyDown(GKey::LCTRL)) {
        // Intersect all tri lists with the ray from the camera
        const Ray& ray = app->activeCamera()->worldRay(e.button.x, e.button.y, 
            app->renderDevice->viewport());

        m_selectedPart = NULL;
        m_selectedMesh = NULL;
        m_selectedTriangleIndex = -1;
        Model::HitInfo hitInfo;
        float distance = finf();
        const bool hit = m_model->intersect(ray, m_offset, ArticulatedModel::defaultPose(), distance, hitInfo);

        if (hit) {
//            shared_ptr<ArticulatedModel> model = dynamic_pointer_cast<ArticulatedModel>(hitInfo.model);
//            alwaysAssertM(notNull(model), "Not a model!");
            m_selectedMesh = m_model->mesh(hitInfo.meshID);
            m_selectedTriangleIndex = hitInfo.primitiveIndex;
        }

        if (notNull(m_selectedMesh)) {
            m_selectedPart = m_selectedMesh->logicalPart;
        }
        return hit;
    } else if ((e.type == GEventType::KEY_DOWN) && (e.key.keysym.sym == 'r')) {
        onInit(m_filename);
        return true;
    }

    return false;
}
Example #3
0
Vector2 GFont::appendToCharVertexArrayWordWrap
(Array<CPUCharVertex>&       cpuCharArray,
 Array<int>&                 indexArray,
 RenderDevice*               renderDevice,
 float                       maxWidth,
 const String&               s,
 const Vector2&              pos2D,
 float                       size,
 const Color4&               color,
 const Color4&               border,
 XAlign                      xalign,
 YAlign                      yalign,
 Spacing                     spacing) const {

    if (maxWidth == finf()) {
        return appendToCharVertexArray(cpuCharArray, indexArray, renderDevice, s, pos2D, size, color, border, xalign, yalign, spacing);
    }

    Vector2 bounds = Vector2::zero();
    Point2 p = pos2D;
    String rest = s;
    String first = "";

    while (! rest.empty()) {
        wordWrapCut(maxWidth, rest, first, size, spacing);
        Vector2 extent = appendToCharVertexArray(cpuCharArray, indexArray, renderDevice, first, p, size, color, border, xalign, yalign, spacing);
        bounds.x = max(bounds.x, extent.x);
        bounds.y += extent.y;
        p.y += iCeil(extent.y * 0.8f);
    }

    return bounds;
}
void RayTracer::traceOnePixel(int x, int y, int threadID) {

    //used for constructing viewport
    Vector2 tmp(m_settings.width, m_settings.height);

    Ray primaryRay;

    // If one ray per pixel: (kinda debugging mode with blue color for places with no surfel hit
    if (m_settings.raysPerPixel == 1){
        //Get the primary ray from the pixel x,y
        primaryRay = m_camera->worldRay(x + 0.5f, y + 0.5f, Rect2D(tmp));
        
        //Get the first surfel hit.
        //Can't call L_i unfortunately because we want the blue background for debugging
        const shared_ptr<Surfel>& s = RayTracer::castRay(primaryRay, finf(), 0);

        //If there is a surfel hit, get the direct illumination value and apply to the pixel
        if (s){
            //Call L_scatteredDirect to get direct illumination. Invert primaryRay to get the direction for incident light
            m_image->set(Point2int32(x,y), L_o(s, -primaryRay.direction(), m_settings.recursiveBounces, *(m_rnd[threadID])));
        } else{
            //Set the pixels with no surfel hit. Include this line so we could make it a specific color for debug purposes.
            m_image->set(Point2int32(x,y), Color3(0,0,1));
        }
    } else {
        Radiance3 L(0,0,0);
        //If more than one ray, randomly generate required number of rays within the pixel
        for (int i = 0; i < m_settings.raysPerPixel; ++i){
            primaryRay = m_camera->worldRay(x + m_rnd[threadID]->uniform(), y + m_rnd[threadID]->uniform(), Rect2D(tmp));
            L += L_i(primaryRay.origin(), primaryRay.direction(), m_settings.recursiveBounces, *(m_rnd[threadID]));
        }
        m_image->set(Point2int32(x,y), L/m_settings.raysPerPixel);
    }
}
Example #5
0
Matrix4 Matrix4::perspectiveProjection(
    float left,
    float right,
    float bottom,
    float top,
    float nearval,
    float farval,
    float upDirection) {

    float x, y, a, b, c, d;

    x = (2.0f*nearval) / (right-left);
    y = (2.0f*nearval) / (top-bottom);
    a = (right+left) / (right-left);
    b = (top+bottom) / (top-bottom);

    if (farval >= finf()) {
       // Infinite view frustum
       c = -1.0f;
       d = -2.0f * nearval;
    } else {
       c = -(farval+nearval) / (farval-nearval);
       d = -(2.0f*farval*nearval) / (farval-nearval);
    }

    debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
    y *= upDirection;
    b *= upDirection;

    return Matrix4(
        x,  0,  a,  0,
        0,  y,  b,  0,
        0,  0,  c,  d,
        0,  0, -1,  0);
}
Example #6
0
float Camera::worldToScreenSpaceArea(float area, float z, const Rect2D& viewport) const {
    (void)viewport;
    if (z >= 0) {
        return finf();
    }
    return area * (float)square(-nearPlaneZ() / z);
}
Example #7
0
shared_ptr<Entity> Scene::intersectEyeRay(const shared_ptr<Camera>& camera, const Vector2& pixel, const Rect2D& viewport, const Vector2int16 guardBandThickness, bool hitMarkers, const Array<shared_ptr<Entity> >& exclude, Model::HitInfo& selectionInfo) const {
    const Ray& ray = camera->worldRay(pixel.x + guardBandThickness.x, pixel.y + guardBandThickness.y, Rect2D(Vector2(viewport.width() + 2 * guardBandThickness.x, viewport.height() + 2 * guardBandThickness.y)));

    // clear old selection info
    selectionInfo.clear();
    float distance = finf();
    return intersect(ray, distance, hitMarkers, exclude, selectionInfo);
}
Radiance3 RayTracer::L_i(const Point3 P, const Vector3& wi, int bouncesLeft, Random& rnd) const{
    //Get the surfel hit and call L_o to compute radiance at the surfel
    shared_ptr<Surfel> surfel = castRay(G3D::Ray(P,wi).bumpedRay(0.0001), finf(), 0);
    if (surfel){
        return L_o(surfel, -wi, bouncesLeft, rnd);
    } else{
        //No surfel, return black
        return Radiance3(0,0,0);
    }
}
Example #9
0
void App::onInit() {
    GApp::onInit();


	renderDevice->setSwapBuffersAutomatically(true);
    logPrintf("App::onInit()\n");
    createDeveloperHUD();
    showRenderingStats = false;

    developerWindow->cameraControlWindow->setVisible(false);
    developerWindow->setVisible(false);
    developerWindow->videoRecordDialog->setCaptureGui(false);

    m_debugCamera->filmSettings().setBloomStrength(0.20f);
    m_debugCamera->filmSettings().setBloomRadiusFraction(0.017f);
    m_debugCamera->filmSettings().setAntialiasingEnabled(true);
    m_debugCamera->filmSettings().setCelluloidToneCurve();

    if (! filename.empty()) {
        window()->setCaption(filenameBaseExt(filename) + " - G3D Viewer");
    }

    lighting = shared_ptr<LightingEnvironment>(new LightingEnvironment());
    lighting->lightArray.clear();
    // The spot light is designed to just barely fit the 3D models.  Note that it has no attenuation
    lighting->lightArray.append(Light::spotTarget("Light", Point3(40, 120, 80), Point3::zero(), 10 * units::degrees(), Power3(50.0f), 1, 0, 0, true, 8192));
    lighting->lightArray.last()->shadowMap()->setBias(0.1f);

    Texture::Encoding e;
    e.readMultiplyFirst = Color4(Color3(0.5f));
    e.format = ImageFormat::RGB32F();

    lighting->environmentMapArray.append(Texture::fromFile(System::findDataFile("uffizi/uffizi-*.exr"), e, Texture::DIM_CUBE_MAP));
    lighting->ambientOcclusionSettings.numSamples   = 24;
    lighting->ambientOcclusionSettings.radius       = 0.75f * units::meters();
    lighting->ambientOcclusionSettings.intensity    = 2.0f;
    lighting->ambientOcclusionSettings.bias         = 0.06f * units::meters();
    lighting->ambientOcclusionSettings.useDepthPeelBuffer = true;

    m_debugCamera->setFarPlaneZ(-finf());
    m_debugCamera->setNearPlaneZ(-0.05f);

    // Don't clip to the near plane
    glDisable(GL_DEPTH_CLAMP);	
    colorClear = Color3::white() * 0.9f;

    //modelController = ThirdPersonManipulator::create();
    m_gbufferSpecification.encoding[GBuffer::Field::CS_POSITION_CHANGE].format = NULL;
    gbuffer()->setSpecification(m_gbufferSpecification);

    setViewer(filename);
    developerWindow->sceneEditorWindow->setVisible(false);
    logPrintf("Done App::onInit()\n");
}
Example #10
0
QString MainWindowTask::getFileName(QString fileName)
{
    QFileInfo finf(fileName);

    QFileDialog dialog(this,trUtf8("Открыть файл"),curDir, "("+finf.fileName()+")");
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
    if(!dialog.exec())return "";
    QFileInfo fi(dialog.selectedFiles().first());

    return dialog.selectedFiles().first();
};
bool PhysicsFrameSplineEditor::hitsSpline(const Ray& r) {
    int j = m_spline.control.size();
    for (int i = 0; i < j; ++i) {
        const CFrame& c = m_spline.control[i];
        if(r.intersectionTime(Sphere(c.translation, CONTROL_POINT_RADIUS), true) != finf()) {
            setSelectedControlPointIndex(i);
            return true;
        }
    }
    return false;
}
Example #12
0
float Ray::intersectionTime(const class Box& box) const {
    Vector3 dummy;
    float time = CollisionDetection::collisionTimeForMovingPointFixedBox(
            m_origin, m_direction, box, dummy);

    if ((time == finf()) && (box.contains(m_origin))) {
        return 0.0f;
    } else {
        return time;
    }
}
Example #13
0
float Ray::intersectionTime(const class AABox& box) const {
    Vector3 dummy;
    bool inside;
    float time = CollisionDetection::collisionTimeForMovingPointFixedAABox(
            m_origin, m_direction, box, dummy, inside);

    if ((time == finf()) && inside) {
        return 0.0f;
    } else {
        return time;
    }
}
Example #14
0
bool Sphere::culledBy(
    const class Plane*  plane,
    int                 numPlanes,
    int&				cullingPlane,
    const uint32		_inMask,
    uint32&             childMask) const {

    if (radius == finf()) {
        // No plane can cull the infinite box
        return false;
    }

	uint32 inMask = _inMask;
	assert(numPlanes < 31);

    childMask = 0;

    // See if there is one plane for which all of the
	// vertices are in the negative half space.
    for (int p = 0; p < numPlanes; p++) {

		// Only test planes that are not masked
		if ((inMask & 1) != 0) {
		
            bool culledLow = ! plane[p].halfSpaceContainsFinite(center + plane[p].normal() * radius);
            bool culledHigh = ! plane[p].halfSpaceContainsFinite(center - plane[p].normal() * radius);

			if (culledLow) {
				// Plane p culled the sphere
				cullingPlane = p;

                // The caller should not recurse into the children,
                // since the parent is culled.  If they do recurse,
                // make them only test against this one plane, which
                // will immediately cull the volume.
                childMask = 1 << p;
				return true;

            } else if (culledHigh) {
                // The bounding volume straddled the plane; we have
                // to keep testing against this plane
                childMask |= (1 << p);
            }
		}

        // Move on to the next bit.
		inMask = inMask >> 1;
    }

    // None of the planes could cull this box
	cullingPlane = -1;
    return false;
}
Example #15
0
void RayTracer::traceOnePhoton(int ignoreX, int ignoreY, int threadID) {
    ThreadData& threadData(m_threadData[threadID]);

    Photon photon;
    emitPhoton(*threadData.rnd, photon);

    const float MIN_POWER_THRESHOLD = 0.001f / m_settings.photon.numEmitted;

    float probabilityHint = 1.0;

    for (int numBounces = 0;
            (numBounces < m_settings.photon.numBounces) &&
            (photon.power.sum() > MIN_POWER_THRESHOLD);
            ++numBounces) {
        // Find the first surface
        float distance = finf();
        const shared_ptr<Surfel>& surfel = castRay(photon.position, -photon.wi, distance, false);

        if (isNull(surfel)) {
            return;
        }

        // Store the photon (if this is not the first bounce and it is
        // not a purely specular surface)
        if ((numBounces > 0) && surfel->nonZeroFiniteScattering()) {
            photon.effectRadius = photonEffectRadius(probabilityHint);

            // Update photon position. Store it slightly before it hit the surface
            // to improve filtering later.
            photon.position = surfel->position + photon.wi * min(photon.effectRadius, distance) / 4;

            // Store a copy of this photon
            m_photonList[threadID].append(photon);
        }

        // Scatter
        Color3  weight;
        Vector3 wo;
        float   probabilityScale;
        surfel->scatter(PathDirection::SOURCE_TO_EYE, photon.wi, true, *threadData.rnd, weight, wo, probabilityScale);

        probabilityHint *= probabilityScale;

        // Update photon power and direction
        photon.power *= weight;
        photon.wi = -wo;

        photon.position = bump(surfel, wo);
    }
}
Example #16
0
Module::Module( const char *name, WCValSList<String> & enabled,
                WCValSList<String> & disabled )
//------------------------------------------------------------
{
    WCPtrOrderedVector<ComponentFile> components;
    FileInfo                          finf( name );
    int                               i;
    MsgRetType                        ret;

    _dataFile = new ElfFile( name, false );

    DwarfFileMerger merger( name, enabled, disabled );

    if( !merger.upToDate() ) {
        if( !finf.exists() ) {
            merger.doMerge();
        } else {
            if( enabled.entries() != 0 ) {
                ret = WMessageDialog::messagef( topWindow,
                        MsgQuestion, MsgYesNo, "Source Browser",
                        "Database %s is not consistent with module files.\n"
                        "Merge the database now?", name );

                if( ret == MsgRetYes ) {
                    merger.doMerge();
                }
            }
        }
    }

    _dataFile->initSections();

    _dataFile->getEnabledComponents( &components );
    for( i = 0; i < components.entries(); i += 1 ) {
        _enabledFiles.add( new WFileName( components[i]->name ) );
    }

    components.clear();
    _dataFile->getDisabledComponents( &components );
    for( i = 0; i < components.entries(); i += 1 ) {
        _disabledFiles.add( new WFileName( components[i]->name ) );
    }

    checkSourceTime();

    _dbgInfo = DRDbgInit( this, _dataFile->getDRSizes(), false );
    DRSetDebug( _dbgInfo );
}
Example #17
0
void Matrix4::getPerspectiveProjectionParameters(
    float& left,    
    float& right,
    float& bottom,  
    float& top,
    float& nearval, 
    float& farval,
    float upDirection) const {

    assert(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");

    float x = elt[0][0];
    float y = elt[1][1] * upDirection;
    float a = elt[0][2];
    float b = elt[1][2] * upDirection;
    float c = elt[2][2];
    float d = elt[2][3];

    
    assert(elt[3][2] == -1, "Not a projection matrix");
    assert(elt[0][1] == 0, "Not a projection matrix");
    assert(elt[0][3] == 0, "Not a projection matrix");
    assert(elt[1][3] == 0, "Not a projection matrix");
    assert(elt[3][3] == 0, "Not a projection matrix");
    assert(elt[1][0] == 0, "Not a projection matrix");
    assert(elt[2][0] == 0, "Not a projection matrix");
    assert(elt[2][1] == 0, "Not a projection matrix");
    assert(elt[3][0] == 0, "Not a projection matrix");
    assert(elt[3][1] == 0, "Not a projection matrix");

    if (c == -1) {
        farval = finf();
        nearval = -d / 2.0f;
    } else {
        nearval = d * ((c - 1.0f) / (c + 1.0f) - 1.0f) / (-2.0f * (c - 1.0f) / (c + 1.0f));
        farval = nearval * ((c - 1.0f) / (c + 1.0f));
    }


    left = (a - 1.0f) * nearval / x;
    right = 2.0f * nearval / x + left;

    bottom = (b - 1.0f) * nearval / y;
    top = 2.0f * nearval / y + bottom;
}
Example #18
0
void Matrix4::getPerspectiveProjectionParameters(
    double& left,    
    double& right,
    double& bottom,  
    double& top,
    double& nearval, 
    double& farval,
    float upDirection) const {

    debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");

    double x = elt[0][0];
    double y = elt[1][1] * upDirection;
    double a = elt[0][2];
    double b = elt[1][2] * upDirection;
    double c = elt[2][2];
    double d = elt[2][3];

    // Verify that this really is a projection matrix
    debugAssertM(elt[3][2] == -1, "Not a projection matrix");
    debugAssertM(elt[0][1] == 0, "Not a projection matrix");
    debugAssertM(elt[0][3] == 0, "Not a projection matrix");
    debugAssertM(elt[1][3] == 0, "Not a projection matrix");
    debugAssertM(elt[3][3] == 0, "Not a projection matrix");
    debugAssertM(elt[1][0] == 0, "Not a projection matrix");
    debugAssertM(elt[2][0] == 0, "Not a projection matrix");
    debugAssertM(elt[2][1] == 0, "Not a projection matrix");
    debugAssertM(elt[3][0] == 0, "Not a projection matrix");
    debugAssertM(elt[3][1] == 0, "Not a projection matrix");

    if (c == -1) {
        farval = finf();
        nearval = -d / 2.0;
    } else {
        nearval = d * ((c - 1.0) / (c + 1.0) - 1.0) / (-2.0 * (c - 1.0) / (c + 1.0));
        farval = nearval * ((c - 1.0) / (c + 1.0));
    }


    left = (a - 1.0) * nearval / x;
    right = 2.0 * nearval / x + left;

    bottom = (b - 1.0) * nearval / y;
    top = 2.0 * nearval / y + bottom;
}
Example #19
0
float movingDiskFixedLineSegmentCollisionTime(Point2 center, float radius, Vector2 velocity, const LineSegment2D& segment, Point2& collisionLocation) {
    // Ridiculously implemented in terms of existing 3D functionality 

    Point3 X;
    const float t = CollisionDetection::collisionTimeForMovingSphereFixedTriangle
        (Sphere(Point3(center, 0.0f), radius),
         Vector3(velocity, 0.0f),
         Triangle(Point3(segment.point(0), +1.0f),
                  Point3(segment.point(0), -1.0f),
                  Point3(segment.point(1),  0.0f)),
                  X);

    if (t < finf()) {
        collisionLocation = X.xy();
    }

    return t;
}
Example #20
0
Radiance3 RayTracer::L_in(const Point3& X, const Vector3& wi, ThreadData& threadData, int bouncesLeft) const {
    if (bouncesLeft == 0) {
        // We aren't allowed to trace farther, so estimate from the
        // environment map
        return BACKGROUND_RADIANCE;
    }

    // Surface hit by the primary ray (at X)
    float maxDistance = finf();
    shared_ptr<Surfel> surfel(castRay(X, wi, maxDistance));

    if (notNull(surfel)) {
        // Hit something
        return L_out(surfel, -wi, threadData, bouncesLeft);
    } else {
        // Hit background
        return BACKGROUND_RADIANCE;
    }
}
Example #21
0
void DirReader::recurseDir(const QString &path, int curDepth)
{
        QDir dir(path);
        dir.setSorting(flags);
        dir.setFilter(QDir::AllDirs|QDir::Files);

        const QStringList files = dir.entryList();
	foreach (QString f, files)
        {
                if (f == "." || f == "..")
                        continue;

                QFileInfo finf(dir, f);
		fileHandler(finf);
                if (finf.isDir()) // && (finf.absoluteFilePath() != path))
		{
			if (curDepth < maxDirDepth)
			{
				recurseDir(finf.absoluteFilePath(), curDepth+1);
			}
		}
        }
}
Example #22
0
bool App::onEvent(const GEvent& event) {
    if (GApp::onEvent(event)) {
        return true;
    }

    if (event.type == GEventType::VIDEO_RESIZE) {
        // Example GUI dynamic layout code.  Resize the debugWindow to fill
        // the screen horizontally.
        debugWindow->setRect(Rect2D::xywh(0, 0, window()->width(), debugWindow->rect().height()));
    }


    if (! m_preventEntitySelect && (event.type == GEventType::MOUSE_BUTTON_DOWN) && (event.button.button == 0)) {
        // Left click: select by casting a ray through the center of the pixel
        const Ray& ray = defaultCamera.worldRay(event.button.x + 0.5f, event.button.y + 0.5f, renderDevice->viewport());
        
        float distance = finf();

        selectEntity(m_scene->intersect(ray, distance));
    }
    

    if (! m_preventEntitySelect && (event.type == GEventType::GUI_ACTION) && (event.gui.control == m_entityList)) {
        // User clicked on dropdown list
        selectEntity(m_scene->entity(m_entityList->selectedValue().text()));
    }

    // If you need to track individual UI events, manage them here.
    // Return true if you want to prevent other parts of the system
    // from observing this specific event.
    //
    // For example,
    // if ((event.type == GEventType::GUI_ACTION) && (event.gui.control == m_button)) { ... return true;}
    // if ((event.type == GEventType::KEY_DOWN) && (event.key.keysym.sym == GKey::TAB)) { ... return true; }

    return false;
}
Example #23
0
void ElfFile::addComponentFile( const char * fileName, bool enable )
//------------------------------------------------------------------
{
    ComponentFile * comp;
    bool            found = false;
    FileInfo        finf( fileName );

    // NYI -- use the WCVector find!
    for( int i = 0; i < _components->entries(); i += 1 ) {
        if( strcmp( (*_components)[i]->name, fileName ) == 0 ) {
            comp = (*_components)[ i ];
            found = true;
        }
    }

    if( !found ) {
        comp = ComponentFile::createComponent( finf.st_mtime(), enable, fileName );
    }

    if( !found ) {
        strcpy( comp->name, fileName );
        _components->append( comp );
    }
}
Example #24
0
void MeshAlg::computeBounds(
    const Array<Vector3>&   vertexArray,
    AABox&                  box,
    Sphere&                 sphere) {

    Vector3 xmin, xmax, ymin, ymax, zmin, zmax;

    // FIRST PASS: find 6 minima/maxima points
    xmin.x = ymin.y = zmin.z = finf();
    xmax.x = ymax.y = zmax.z = -finf();

    for (int v = 0; v < vertexArray.size(); ++v) {
        const Vector3& vertex = vertexArray[v];

        if (vertex.x < xmin.x) {
            xmin = vertex;
        }

        if (vertex.x > xmax.x) {
            xmax = vertex;
        }

        if (vertex.y < ymin.y) {
            ymin = vertex;
        }

        if (vertex.y > ymax.y) {
            ymax = vertex;
        }

        if (vertex.z < zmin.z) {
            zmin = vertex;
        }

        if (vertex.z > zmax.z) {
            zmax = vertex;
        }
    }

    // Set points dia1 & dia2 to the maximally separated pair
    Vector3 dia1 = xmin;
    Vector3 dia2 = xmax;
    {
        // Set xspan = distance between the 2 points xmin & xmax (squared)
        double xspan = (xmax - xmin).squaredMagnitude();

        // Same for y & z spans
        double yspan = (ymax - ymin).squaredMagnitude();
        double zspan = (zmax - zmin).squaredMagnitude();

        double maxspan = xspan;

        if (yspan > maxspan) {
            maxspan = yspan;
            dia1    = ymin;
            dia2    = ymax;
        }

        if (zspan > maxspan) {
            maxspan = zspan;
            dia1    = zmin;
            dia2    = zmax;
        }
    }


    // dia1, dia2 is a diameter of initial sphere

    // calc initial center
    Vector3 center = (dia1 + dia2) / 2.0;

    // calculate initial radius^2 and radius
    Vector3 d = dia2 - sphere.center;

    double radSq = d.squaredMagnitude();
    double rad  = sqrt(radSq);

    // SECOND PASS: increment current sphere
    double old_to_p, old_to_new;

    for (int v = 0; v < vertexArray.size(); ++v) {
        const Vector3& vertex = vertexArray[v];

        d = vertex - center;

        double old_to_p_sq = d.squaredMagnitude();

        // do r^2 test first
        if (old_to_p_sq > radSq) {
            // this point is outside of current sphere
            old_to_p = sqrt(old_to_p_sq);

            // calc radius of new sphere
            rad = (rad + old_to_p) / 2.0;

            // for next r^2 compare
            radSq = rad * rad;
            old_to_new = old_to_p - rad;

            // calc center of new sphere
            center = (rad * center + old_to_new * vertex) / old_to_p;
        }
    }

    const Vector3 min(xmin.x, ymin.y, zmin.z);
    const Vector3 max(xmax.x, ymax.y, zmax.z);

        box = AABox(min, max);

    const float boxRadSq = (max - min).squaredMagnitude() * 0.25f;

    if (boxRadSq >= radSq){
            if (isNaN(center.x) || ! isFinite(rad)) {
                sphere = Sphere(Vector3::zero(), finf());
            } else {
                sphere = Sphere(center, rad);
            }
    } else {
            sphere = Sphere((max + min) * 0.5f, sqrt(boxRadSq));
    }
}
Example #25
0
void ParticleSystemModel::init() {
    // Extract the fade in and out times. 
    m_hasCoverageFadeTime = false;
    m_hasExpireTime = false;
    for (const shared_ptr<Emitter>& emitter : m_emitterArray) {
        const float fi = emitter->specification().coverageFadeInTime;
        const float fo = emitter->specification().coverageFadeOutTime;

        m_hasCoverageFadeTime = m_hasCoverageFadeTime || (fi > 0) || (fo > 0);
        m_coverageFadeTime.append(std::make_pair(fi, fo));
        m_hasExpireTime = m_hasExpireTime || (emitter->specification().particleLifetimeMean < finf());
    }
}
void RayTracer::tracePhotons(Photon p, int bouncesLeft){
    //Only trace the photon if more than one bounce
    if (bouncesLeft > 0){
        //Get the intersected surface
        shared_ptr<UniversalSurfel> surfel = dynamic_pointer_cast<UniversalSurfel>(castRay(G3D::Ray(p.origin,p.direction).bumpedRay(0.0001), finf(), 0));
        if (surfel){
            p.origin = surfel->position;
            //Don't store for mirror surfaces
            if (!(surfel->glossyReflectionCoefficient.nonZero() && (surfel->glossyReflectionExponent == inf()))){
                Vector3 D = p.origin -  m_camera->frame().translation;
                //if (D.length() < 10){
                    if(castRay(G3D::Ray(m_camera->frame().translation,D).bumpedRay(0.0001), D.length(), 1)) {
                        photons.insert(p);
                    }
                //}
            }
            shared_ptr<Random> rnd = m_rnd[0];
            
            Vector3 wo;
            Color3 weight;
            //scatter the photon using the method provided by G3D. Used to be a lot of lines which got deleted
            surfel->scatter(PathDirection::SOURCE_TO_EYE, -p.direction, true, *rnd, weight, wo);
            //If it scatters, continue tracing
            if (wo.magnitude() > 0){
                p.direction = wo;
                p.power *= weight;
                tracePhotons(p, bouncesLeft - 1);
            }

            rnd.reset();
        }
    }
}
Example #27
0
void Browse::positionEditor( char * fileName, ulong line, uint col,
                             int hiliteLen )
//-----------------------------------------------------------------
{
    FileInfo finf( fileName );

    if( finf.exists() ) {
        if( optManager()->isEditorDLL() ) {
            if( _editorDLL->isInitialized() ) {
                if( _editorDLL->EDITConnect() ) {
                    _editorDLL->EDITFile( fileName, "" );
                    _editorDLL->EDITLocate( line, col, hiliteLen );
                    _editorDLL->EDITShowWindow( EDIT_SHOWNORMAL );
                } else {
                    errMessage( "Unable to connect to editor" );
                }
            } else {
                ASSERTION( 0 /* uh-oh -- the menu item should be grayed */ );
            }
        } else {
            WString cmd( optManager()->getEditorName() );
            WString editorParms( optManager()->getEditorParms() );

            cmd.concat( ' ' ); // space after editor name before parms
            int parmsize = editorParms.size();

            for( int i=0; i < parmsize; i++ ) {
                switch( editorParms[i] ) {
                case '%':
                    switch( editorParms[i+1] ) {
                    case 'f': // file name
                        cmd.concat( fileName );
                        break;
                    case 'r': // row to go to
                        cmd.concatf( "%ld", line );
                        break;
                    case 'c': // column to go to
                        cmd.concatf( "%d", col );
                        break;
                    case 'l': // length of hilight
                        cmd.concatf( "%d", hiliteLen );
                        break;
                    #if 0
                    case 'h': // helpid
                        cmd.concat( x.stringAt( 5 ) );
                        break;
                    case 'e': // error message
                        cmd.concat( x.stringAt( 6 ) );
                        break;
                    #endif
                    case '%': // a real '%'
                        cmd.concat( '%' );
                        break;
                    default:
                        // ignore the '%' and the character
                        break;
                    }
                    i+=2; // skip % and following char
                default:
                    cmd.concat( editorParms[i] );
                    break;
                }
            }
            WSystemService::sysExec( cmd, WWinStateShowNormal, 0 );
        }
    } else {
        errMessage( "File \"%s\" not found", fileName );
    }
}
Example #28
0
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);
}
Example #29
0
void PlayerEntity::slideMove(GameTime timeLeft) { 
    static const float epsilon = 0.0001f;


    // Use constant velocity gravity (!)
    alwaysAssertM(((PhysicsScene*)m_scene)->gravity().x == 0.0f && ((PhysicsScene*)m_scene)->gravity().z == 0.0f, 
                            "We assume gravity points along the y axis to simplify implementation");
    
    m_desiredOSVelocity.y = max( ((PhysicsScene*)m_scene)->gravity().y, m_desiredOSVelocity.y + ((PhysicsScene*)m_scene)->gravity().y);
    // Initial velocity
    Vector3 velocity = frame().vectorToWorldSpace(m_desiredOSVelocity) + ((PhysicsScene*)m_scene)->gravity();

    Array<Tri> triArray;
    getConservativeCollisionTris(triArray, velocity, (float)timeLeft);
    
    // Trivial implementation that ignores collisions:
#   if 0
        m_frame.translation += velocity  * timeLeft;
        return;
#   endif

    // Keep simulating until we run out of time or velocity, at which point
    // no further movement is possible.
#   ifdef TRACE_COLLISIONS
        debugPrintf("================================\n");
        debugPrintf("Initial velocity = %s; position = %s\n", velocity.toString().c_str(),  m_frame.translation.toString().c_str());
#   endif
    int iterations = 0;
    while ((timeLeft > epsilon) && (velocity.length() > epsilon)) {
        float stepTime = float(timeLeft);
        Vector3 collisionNormal;
        Point3 collisionPoint;

        const bool collided = 
            findFirstCollision(triArray, velocity, stepTime, collisionNormal, collisionPoint);
#       ifdef TRACE_COLLISIONS
            debugPrintf("  stepTime = %f\n", stepTime);
#       endif
        // Advance to just before the collision
        stepTime = max(0.0f, stepTime - epsilon * 0.5f);
        m_frame.translation += velocity * stepTime;

        // Early out of loop when debugging
        //if (! runSimulation) { return; }
        
        if (collided) {
#           ifdef TRACE_COLLISIONS
                debugPrintf("  Collision C=%s, n=%s; position after=%s)\n", 
                            collisionPoint.toString().c_str(),
                            collisionNormal.toString().c_str(),
                            m_frame.translation.toString().c_str());
#           endif
            if (collisionProxy().contains(collisionPoint)) {
                // Interpenetration. This is bad because the
                // rest of the code assumes no interpenetration and
                // uses that to rise up steps.  Place the sphere
                // adjacent to the triangle and eliminate all velocity
                // towards the triangle.
                m_frame.translation = collisionPoint + collisionNormal * (m_collisionProxySphere.radius + epsilon * 2.0f);

                
#               ifdef TRACE_COLLISIONS
                    debugPrintf("  Interpenetration detected.  Position after = %s\n",
                        m_frame.translation.toString().c_str());
#               endif
            }
                
            // Constrain the velocity by subtracting the component
            // into the collision normal
            const Vector3& vPerp = collisionNormal * collisionNormal.dot(velocity);
            const Vector3& vPar  = velocity - vPerp;
#           ifdef SHOW_COLLISIONS
            if (collisionNormal.y < 0.95f) {
                float duration = 1.0f;
                debugDraw(new ArrowShape(collisionPoint, velocity), duration, Color3::green());
                debugDraw(new ArrowShape(collisionPoint, vPerp),    duration, Color3::yellow());
                debugDraw(new ArrowShape(collisionPoint, vPar),     duration, Color3::blue());
                if (duration == finf()) {
                    // Pause so we can see the result
                    runSimulation = false;
                }
            }
#           endif
            velocity = vPar;

#           ifdef TRACE_COLLISIONS
                debugPrintf("  velocity after collision = %s\n", velocity.toString().c_str());
#           endif
        }
#       ifdef TRACE_COLLISIONS
            debugPrintf("  --------------\n");
#       endif

        ++iterations;
        timeLeft -= stepTime;           
    }
    //screenPrintf("%d collision iterations", iterations);
}
Example #30
0
bool imageViewer::openImage(QString &filename,QString start,bool ask,bool showMessage,bool emitSignal,bool fromCache)
{
  QImage tempImage;
  QFile fi(filename);
  QFileInfo finf(filename);
  QString cacheFileName;
  jp2IO jp2;
  displayMBoxEvent *stmb=0;
  editorScene ed;
  bool success=false;
  bool cacheHit=false;



  if(activeMovie)
  {
    activeMovie=false;
    qm.stop();
  }
  if (filename.isEmpty()&&!ask) return false;
  if(ask)
  {
    dirDialog dd((QWidget *)this,"Browse");
    filename=dd.openFileName(start,"*");
  }
  if(filename.isEmpty())
  {
    imageFileName="";
    return false;
  }

  if(fromCache)
  {
    cacheFileName=finf.absolutePath()+"/cache/"+finf.baseName()+finf.created().toString()+".png";
    if(tempImage.load(cacheFileName))
    {
      cacheHit=true;
      success=true;
      orgWidth=tempImage.text("orgWidth").toInt();
      orgHeight=tempImage.text("orgHeight").toInt();
    }
  }
  if(!success)
  {
    if(tempImage.load(filename))
    {
      success=true;
    }
    else if(ed.load(fi))
    {
      success=true;
      tempImage=QImage(ed.renderImage(0,0)->copy());
    }
    else if(jp2.check(filename))
    {
      tempImage=jp2.decode(filename);
      if(!tempImage.isNull())
      {
        success=true;
      }
    }
  }

  if(!success)
  {
    if(showMessage)
    {
      stmb= new displayMBoxEvent("Image Loader",QString("Unable to load image:\n%1").arg(filename));
      QApplication::postEvent( dispatcherPtr, stmb );  // Qt will delete it when done
    }
    validImage=false;
    imageFileName="";
    return false;
  }

  if(fromCache)
  {
    sourceImage=QImage();

    if(!cacheHit)
    {
      orgWidth=tempImage.width();
      orgHeight=tempImage.height();
      tempImage=tempImage.scaledToWidth(120, Qt::FastTransformation);
      // save cacheImage for next time
      tempImage.setText("orgWidth",QString::number(orgWidth));
      tempImage.setText("orgHeight",QString::number(orgHeight));
      tempImage.save(cacheFileName,"PNG");
    }
    displayedImage=tempImage;
  }
  else
  {
    sourceImage=tempImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
    orgWidth=tempImage.width();
    orgHeight=tempImage.height();
    displayedImage=sourceImage;
  }

  imageFileName=filename;

  QFileInfo finfo(filename);
  if (finfo.suffix().toLower()=="gif")
  {
    //we will try a animated gif
    qm.setFileName(filename);
    if(qm.isValid())
    {
      if(qm.frameCount()>1)
      {
        activeMovie=true;
        setMovie(&qm);
        qm.start();
        displayedImage=QImage();
      }
      else
      {
        displayImage();  // we have a single image gif
      }
    }
  }
  else
  {
    displayImage();
  }
  validImage=true;
  if (emitSignal) emit imageChanged();
  return true;
}