void StarDatabase::findVisibleStars(StarHandler& starHandler, const Point3f& position, const Quatf& orientation, float fovY, float aspectRatio, float limitingMag) const { // Compute the bounding planes of an infinite view frustum Planef frustumPlanes[5]; Vec3f planeNormals[5]; Mat3f rot = orientation.toMatrix3(); float h = (float) tan(fovY / 2); float w = h * aspectRatio; planeNormals[0] = Vec3f(0, 1, -h); planeNormals[1] = Vec3f(0, -1, -h); planeNormals[2] = Vec3f(1, 0, -w); planeNormals[3] = Vec3f(-1, 0, -w); planeNormals[4] = Vec3f(0, 0, -1); for (int i = 0; i < 5; i++) { planeNormals[i].normalize(); planeNormals[i] = planeNormals[i] * rot; frustumPlanes[i] = Planef(planeNormals[i], position); } octreeRoot->processVisibleObjects(starHandler, position, frustumPlanes, limitingMag, STAR_OCTREE_ROOT_SIZE); }
void Galaxy::renderGalaxyPointSprites(const GLContext&, const Vec3f& offset, const Quatf& viewerOrientation, float brightness, float pixelSize) { if (form == NULL) return; /* We'll first see if the galaxy's apparent size is big enough to be noticeable on screen; if it's not we'll break right here, avoiding all the overhead of the matrix transformations and GL state changes: */ float distanceToDSO = offset.length() - getRadius(); if (distanceToDSO < 0) distanceToDSO = 0; float minimumFeatureSize = pixelSize * distanceToDSO; float size = 2 * getRadius(); if (size < minimumFeatureSize) return; if (galaxyTex == NULL) { galaxyTex = CreateProceduralTexture(width, height, GL_RGBA, GalaxyTextureEval); } assert(galaxyTex != NULL); glEnable(GL_TEXTURE_2D); galaxyTex->bind(); Mat3f viewMat = viewerOrientation.toMatrix3(); Vec3f v0 = Vec3f(-1, -1, 0) * viewMat; Vec3f v1 = Vec3f( 1, -1, 0) * viewMat; Vec3f v2 = Vec3f( 1, 1, 0) * viewMat; Vec3f v3 = Vec3f(-1, 1, 0) * viewMat; //Mat4f m = (getOrientation().toMatrix4() * // Mat4f::scaling(form->scale) * // Mat4f::scaling(getRadius())); Mat3f m = Mat3f::scaling(form->scale)*getOrientation().toMatrix3()*Mat3f::scaling(size); // Note: fixed missing factor of 2 in getRadius() scaling of galaxy diameter! // Note: fixed correct ordering of (non-commuting) operations! int pow2 = 1; vector<Blob>* points = form->blobs; unsigned int nPoints = (unsigned int) (points->size() * clamp(getDetail())); // corrections to avoid excessive brightening if viewed e.g. edge-on float brightness_corr = 1.0f; float cosi; if (type < E0 || type > E3) //all galaxies, except ~round elliptics { cosi = Vec3f(0,1,0) * getOrientation().toMatrix3() * offset/offset.length(); brightness_corr = (float) sqrt(abs(cosi)); if (brightness_corr < 0.2f) brightness_corr = 0.2f; } if (type > E3) // only elliptics with higher ellipticities { cosi = Vec3f(1,0,0) * getOrientation().toMatrix3() * offset/offset.length(); brightness_corr = brightness_corr * (float) abs((cosi)); if (brightness_corr < 0.45f) brightness_corr = 0.45f; } glBegin(GL_QUADS); for (unsigned int i = 0; i < nPoints; ++i) { if ((i & pow2) != 0) { pow2 <<= 1; size /= 1.55f; if (size < minimumFeatureSize) break; } Blob b = (*points)[i]; Point3f p = b.position * m; float br = b.brightness / 255.0f; Color c = colorTable[b.colorIndex]; // lookup static color table Point3f relPos = p + offset; float screenFrac = size / relPos.distanceFromOrigin(); if (screenFrac < 0.1f) { float btot = ((type > SBc) && (type < Irr))? 2.5f: 5.0f; float a = btot * (0.1f - screenFrac) * brightness_corr * brightness * br; glColor4f(c.red(), c.green(), c.blue(), (4.0f*lightGain + 1.0f)*a); glTexCoord2f(0, 0); glVertex(p + (v0 * size)); glTexCoord2f(1, 0); glVertex(p + (v1 * size)); glTexCoord2f(1, 1); glVertex(p + (v2 * size)); glTexCoord2f(0, 1); glVertex(p + (v3 * size)); } } glEnd(); }