예제 #1
0
void OGL3DBase::PerspectiveSetup(double eyeSepMult)
{
    Coord3D zeroOffset(0.0, 0.0, 0.0);
    Coord3D minCoord = plotBase.GetNormalizedCoord(currView.viewLimits.minLim, zeroOffset);
    Coord3D maxCoord = plotBase.GetNormalizedCoord(currView.viewLimits.maxLim, zeroOffset);;

    double maxSceneWidth = minCoord.Distance(maxCoord);
    double sceneWidth = maxSceneWidth / currView.scale;
    double fovRadians = Radians(plot3Dbase.fieldOfView);
    double focalLength = sceneWidth / 2.0 / tan(fovRadians / 2.0);

    double nearDist = focalLength / 5.0;
    double farDist  = focalLength + maxSceneWidth * 4.0;
    double wd2 = nearDist * tan(fovRadians);
    double ndfl = nearDist / focalLength;
    double eyeSep = focalLength * eyeSepMult;

    int width, height;
    plotBase.CalcAvailablePixels(width, height);
    double aspect = double(width)/ double(height);

    double left  = -aspect * wd2 + eyeSep * ndfl;
    double right = aspect * wd2 + eyeSep * ndfl;
    double top    =   wd2;
    double bottom = - wd2;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(left, right, bottom, top, nearDist, farDist);

    Coord3D spanOffset((1.0 - xOrthoSpan)/ 2.0 , (1.0 - yOrthoSpan)/ 2.0 , (1.0 - zOrthoSpan)/ 2.0 );
    Coord3D translation = currView.translation + spanOffset;
    translation *= (maxCoord - minCoord);

    Coord3D lookAtPoint = (minCoord + maxCoord) / 2.0;
    lookAtPoint -= translation;

    double elevAngle = Radians(currView.elevation);
    double rotAngle = Radians(currView.azimuth);

    double dz = focalLength * sin(elevAngle);
    double xylen = focalLength * cos(elevAngle);
    double dx = - xylen * sin(rotAngle);
    double dy = - xylen * cos(rotAngle);

    Coord3D eyeCoord = lookAtPoint;
    eyeCoord.cX += dx;
    eyeCoord.cY += dy;
    eyeCoord.cZ += dz;

    Coord3D upVec(0.0, 0.0, 1.0);
    if (fabs(sin(elevAngle)) > 0.95)
    {
        upVec = Coord3D(sin(rotAngle), cos(rotAngle), 0.0);
        upVec.Normalize();
    }

    if (eyeSep > stdEps)
    {
        Coord3D rsep = CrossProduct(eyeCoord, upVec);
        rsep.Normalize();
        rsep *= eyeSep;
        eyeCoord += rsep;
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(eyeCoord.cX, eyeCoord.cY, eyeCoord.cZ,
              lookAtPoint.cX, lookAtPoint.cY, lookAtPoint.cZ,
              upVec.cX, upVec.cY, upVec.cZ);

    // denormalize
    // scale for normalizations
    glScaled(xOrthoSpan / normSpan.cX, yOrthoSpan / normSpan.cY, zOrthoSpan / normSpan.cZ);

    // translate again for normalizations
    glTranslated(-normMin.cX, -normMin.cY, -normMin.cZ);
}
예제 #2
0
bool PC_TransparencySpec::TransparencySetup()
{
    int nobj = plotDef.plotObjList.Size();
    objectIsTransparent.AllocAndFill(nobj, false);

    int nanno = plotDef.annoObjList.Size();
    annoIsTransparent.AllocAndFill(nanno, false);
    if (!useTransparency)
        return false;

    // get initial counts & objects
    int tranCount = 0;
    for (int i = 0; i < nobj; i++)
    {
        const PlotObjC& nextObj = plotDef.plotObjList.GetRef(i);

        if (nextObj.doPlot && nextObj.StatusOK() && nextObj.SupportsTransparency())
        {
            int objCount = nextObj.GetnTransObjects();
            if ((objCount > 0) &&
                    (transparencyGroups[nextObj.GetTransGroup()].groupIsTransparent))
            {
                objectIsTransparent[i] = true;
                tranCount += objCount;
            }
        }
    }

    int annoTranCount = 0;
    for (int i = 0; i < nanno; i++)
    {
        const AnnoObjC& nextObj = plotDef.annoObjList.GetRef(i);

        if (nextObj.doPlot && nextObj.StatusOK() && nextObj.SupportsTransparency())
        {
            if (transparencyGroups[nextObj.GetTransGroup()].groupIsTransparent)
            {
                annoIsTransparent[i] = true;
                annoTranCount++;
            }
        }
    }

    annoOnly = (tranCount == 0);
    if (annoOnly)
        return (annoTranCount > 0);

    PC_View currView = plotDef.GetCurrentView();

    Coord3D zeroOffset(0.0, 0.0, 0.0);
    Coord3D minCoord = plotDef.GetNormalizedCoord(currView.viewLimits.minLim, zeroOffset);
    Coord3D maxCoord = plotDef.GetNormalizedCoord(currView.viewLimits.maxLim, zeroOffset);;

    Line3D tempLine(minCoord, maxCoord);
    double maxLength = tempLine.Length() * 2.0;
    Coord3D lookAtPoint = tempLine.PointOnLine(0.5);

    double elevAngle = Radians(currView.elevation);
    double rotAngle = Radians(currView.azimuth);

    double dz = maxLength * sin(elevAngle);
    double xylen = maxLength * cos(elevAngle);

    double dx = - xylen * sin(rotAngle);
    double dy = - xylen * cos(rotAngle);

    eyeCoord = lookAtPoint;
    eyeCoord.cX += dx;
    eyeCoord.cY += dy;
    eyeCoord.cZ += dz;

    tranObjectList.Alloc(tranCount);
    tranCount = 0;
    Coord3D objCoord;
    double minDist, maxDist;
    for (int i = 0; i < nobj; i++)
        if (objectIsTransparent[i])
        {
            PlotObjC& nextObj = plotDef.plotObjList.GetRef(i);
            nextObj.SetupForGetCoord();
            int objCount = nextObj.GetnTransObjects();
            for (int j = 0; j < objCount; j++)
            {
                ObjectTransDesc& nextDesc = tranObjectList[tranCount];
                objCoord = nextObj.GetTransObjectCoord(j);
                if (objCoord.CoordIsNull())
                    continue;

                objCoord = plotDef.GetNormalizedCoord(objCoord, nextObj.offsetCoord);
                if (objCoord.CoordIsNull())
                    continue;

                double nextDist = objCoord.Distance(eyeCoord);
                if (tranCount == 0)
                {
                    minDist = nextDist;
                    maxDist = nextDist;
                }
                else
                {
                    if (nextDist < minDist)
                        minDist = nextDist;
                    else if (nextDist > maxDist)
                        maxDist = nextDist;
                }

                nextDesc.objDist = nextDist;
                nextDesc.objRef = &nextObj;
                nextDesc.objIndex = j;
                nextDesc.objGroup = nextObj.GetTransGroup();
                tranCount++;
            }
        }

    if (tranCount == 0)
    {
        annoOnly = (annoTranCount > 0);
        objectIsTransparent.FillToAlloc(false);
        return annoOnly;
    }

    int ndistanceGroups = tranCount / 500;

    // now place in buckets for sorting
    if (ndistanceGroups < 2)
    {
        ndistanceGroups = 1;
        // easy just use 1 bucket
        objectSortArray.AllocAndSetSize(1);
        objectSortArray[0].Alloc(tranCount);
        for (int i = 0; i < tranCount; i++)
            objectSortArray[0] += &(tranObjectList[i]);
    }
    else
    {
        if (ndistanceGroups > 5000)
            ndistanceGroups = 5000;
        if (ndistanceGroups < 100)
            ndistanceGroups = 100;

        objectSortArray.AllocAndSetSize(ndistanceGroups);
        for (int i = 0; i < ndistanceGroups; i++)
            objectSortArray[i].SetResizable(tranCount / ndistanceGroups * 5);

        double deltaDist = (maxDist - minDist) / double(ndistanceGroups);
        for (int i = 0; i < tranCount; i++)
        {
            ObjectTransDesc& nextDesc = tranObjectList[i];
            int currGroup = int((nextDesc.objDist - minDist) / deltaDist);
            if (currGroup >= ndistanceGroups)
                currGroup = ndistanceGroups - 1;
            if (currGroup < 0)
                currGroup = 0;
            objectSortArray[currGroup] += &nextDesc;
        }
    }

    // now sort each
    for (int k = 0; k < objectSortArray.Size(); k++)
    {
        ObjPtrList& currList = objectSortArray[k];
        QSort(currList, 0, currList.UpperBound());
    }

    return true;
}