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); }
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; }