#include <celmath/mathlib.h>#include <celmath/vecmath.h>#include <celmath/intersect.h>#include <celutil/utf8.h>#include <cassert>#include "astro.h"#include "3dsmesh.h"#include "meshmanager.h"#include "universe.h"Include dependency graph for universe.cpp:

Go to the source code of this file.
Defines | |
| #define | ANGULAR_RES 3.5e-6 |
Functions | |
| static bool | ApproxPlanetPickTraversal (Body *body, void *info) |
| static bool | ExactPlanetPickTraversal (Body *body, void *info) |
|
|
Definition at line 22 of file universe.cpp. Referenced by ApproxPlanetPickTraversal(), CloseStarPicker::CloseStarPicker(), DSOPicker::DSOPicker(), Universe::pickDeepSkyObject(), Universe::pickPlanet(), Universe::pickStar(), DSOPicker::process(), CloseStarPicker::process(), StarPicker::process(), and StarPicker::StarPicker(). |
|
||||||||||||
|
Definition at line 303 of file universe.cpp. References ANGULAR_RES, PlanetPickInfo::atanTolerance, PlanetPickInfo::closestApproxDistance, PlanetPickInfo::closestBody, Ray3< T >::direction, distance(), PlanetPickInfo::jd, Vector3< T >::length(), Vector3< T >::normalize(), Ray3< T >::origin, PlanetPickInfo::pickRay, PlanetPickInfo::sinAngle2Closest, and sqrt(). Referenced by Universe::pickPlanet(). 00304 {
00305 PlanetPickInfo* pickInfo = (PlanetPickInfo*) info;
00306
00307 // Reject invisible bodies and bodies that don't exist at the current time
00308 if (body->getClassification() == Body::Invisible || !body->extant(pickInfo->jd))
00309 return true;
00310
00311 Point3d bpos = body->getHeliocentricPosition(pickInfo->jd);
00312 Vec3d bodyDir = bpos - pickInfo->pickRay.origin;
00313 double distance = bodyDir.length();
00314
00315 // Check the apparent radius of the orbit against our tolerance factor.
00316 // This check exists to make sure than when picking a distant, we select
00317 // the planet rather than one of its satellites.
00318 float appOrbitRadius = (float) (body->getOrbit()->getBoundingRadius() /
00319 distance);
00320
00321 if ((pickInfo->atanTolerance > ANGULAR_RES ? pickInfo->atanTolerance:
00322 ANGULAR_RES) > appOrbitRadius)
00323 {
00324 return true;
00325 }
00326
00327 bodyDir.normalize();
00328 Vec3d bodyMiss = bodyDir - pickInfo->pickRay.direction;
00329 double sinAngle2 = sqrt(bodyMiss * bodyMiss)/2.0;
00330
00331 if (sinAngle2 <= pickInfo->sinAngle2Closest)
00332 {
00333 pickInfo->sinAngle2Closest = sinAngle2 > ANGULAR_RES ? sinAngle2 :
00334 ANGULAR_RES;
00335 pickInfo->closestBody = body;
00336 pickInfo->closestApproxDistance = distance;
00337 }
00338
00339 return true;
00340 }
|
|
||||||||||||
|
Definition at line 344 of file universe.cpp. References PlanetPickInfo::closestBody, PlanetPickInfo::closestDistance, conjugate(), Ray3< T >::direction, distance(), ResourceManager< T >::find(), GetModelManager(), InvalidResource, PlanetPickInfo::jd, Vector3< T >::normalize(), Ray3< T >::origin, Model::pick(), PlanetPickInfo::pickRay, sqrt(), testIntersection(), Quaternion< T >::w, Quaternion< T >::x, Quaternion< T >::y, and Quaternion< T >::z. Referenced by Universe::pickPlanet(). 00345 {
00346 PlanetPickInfo* pickInfo = reinterpret_cast<PlanetPickInfo*>(info);
00347 Point3d bpos = body->getHeliocentricPosition(pickInfo->jd);
00348 float radius = body->getRadius();
00349 double distance = -1.0;
00350
00351 // Test for intersection with the bounding sphere
00352 if (body->getClassification() != Body::Invisible &&
00353 body->extant(pickInfo->jd) &&
00354 testIntersection(pickInfo->pickRay, Sphered(bpos, radius), distance))
00355 {
00356 if (body->getModel() == InvalidResource)
00357 {
00358 // There's no mesh, so the object is an ellipsoid. If it's
00359 // oblate, do a ray intersection test to see if the object was
00360 // picked. Otherwise, the object is spherical and we've already
00361 // done all the work we need to.
00362 if (body->getOblateness() != 0.0f)
00363 {
00364 // Oblate sphere; use ray ellipsoid intersection calculation
00365 Vec3d ellipsoidAxes(radius,
00366 radius * (1.0 - body->getOblateness()),
00367 radius);
00368 // Transform rotate the pick ray into object coordinates
00369 Mat3d m = conjugate(body->getEclipticalToEquatorial(pickInfo->jd)).toMatrix3();
00370 Ray3d r(Point3d(0, 0, 0) + (pickInfo->pickRay.origin - bpos),
00371 pickInfo->pickRay.direction);
00372 r = r * m;
00373 if (!testIntersection(r, Ellipsoidd(ellipsoidAxes), distance))
00374 distance = -1.0;
00375 }
00376 }
00377 else
00378 {
00379 // Transform rotate the pick ray into object coordinates
00380 Quatf qf = body->getOrientation();
00381 Quatd qd(qf.w, qf.x, qf.y, qf.z);
00382 Mat3d m = conjugate(qd * body->getEclipticalToGeographic(pickInfo->jd)).toMatrix3();
00383 Ray3d r(Point3d(0, 0, 0) + (pickInfo->pickRay.origin - bpos),
00384 pickInfo->pickRay.direction);
00385 r = r * m;
00386
00387 // The mesh vertices are normalized, then multiplied by a scale
00388 // factor. Thus, the ray needs to be multiplied by the inverse of
00389 // the mesh scale factor.
00390 double s = 1.0 / radius;
00391 r.origin.x *= s;
00392 r.origin.y *= s;
00393 r.origin.z *= s;
00394 r.direction *= s;
00395
00396 Model* model = GetModelManager()->find(body->getModel());
00397 if (model != NULL)
00398 {
00399 if (!model->pick(r, distance))
00400 distance = -1.0;
00401 }
00402 }
00403 // Make also sure that the pickRay does not intersect the body in the
00404 // opposite hemisphere! Hence, need again the "bodyMiss" angle
00405
00406 Vec3d bodyDir = bpos - pickInfo->pickRay.origin;
00407 bodyDir.normalize();
00408 Vec3d bodyMiss = bodyDir - pickInfo->pickRay.direction;
00409 double sinAngle2 = sqrt(bodyMiss * bodyMiss)/2.0;
00410
00411
00412 if (sinAngle2 < sin(PI/4.0) && distance > 0.0 &&
00413 distance <= pickInfo->closestDistance)
00414 {
00415 pickInfo->closestDistance = distance;
00416 pickInfo->closestBody = body;
00417 }
00418 }
00419
00420 return true;
00421 }
|
1.4.1