Add Camera::LookAt
This is identical to the POV-Ray look_at keyword for cameras. In fact, I stole the code almost directly from them… It's super handy for panning and tilting the camera towards a particular point, and saves me having to do dubiously accurate direction vector calculations by hand. I still need to figure out what exactly this math is doing.
This commit is contained in:
parent
e64b9403ac
commit
7297bc5c17
4 changed files with 52 additions and 0 deletions
|
@ -93,6 +93,31 @@ Camera::SetUp(const Vector3& up)
|
||||||
mUp = up;
|
mUp = up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Camera::LookAt(const Vector3& pt)
|
||||||
|
{
|
||||||
|
const Double directionLength = mDirection.length();
|
||||||
|
const Double rightLength = mRight.length();
|
||||||
|
const Double upLength = mUp.length();
|
||||||
|
/* TODO: What does this actually do? */
|
||||||
|
const Double handedness = mUp.cross(mDirection).dot(mRight);
|
||||||
|
|
||||||
|
mDirection = (pt - mOrigin).normalize();
|
||||||
|
/* TODO: Check for zero length direction vector. */
|
||||||
|
|
||||||
|
mRight = Vector3::Y.cross(mDirection).normalize();
|
||||||
|
mUp = mDirection.cross(mRight);
|
||||||
|
mDirection *= directionLength;
|
||||||
|
|
||||||
|
if (handedness > 0.0) {
|
||||||
|
mRight *= rightLength;
|
||||||
|
} else {
|
||||||
|
mRight *= -rightLength;
|
||||||
|
}
|
||||||
|
mUp *= upLength;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Perspective Camera
|
#pragma mark - Perspective Camera
|
||||||
|
|
||||||
PerspectiveCamera::PerspectiveCamera()
|
PerspectiveCamera::PerspectiveCamera()
|
||||||
|
|
|
@ -35,6 +35,8 @@ struct Camera
|
||||||
const Vector3& GetUp() const;
|
const Vector3& GetUp() const;
|
||||||
void SetUp(const Vector3& up);
|
void SetUp(const Vector3& up);
|
||||||
|
|
||||||
|
void LookAt(const Vector3& pt);
|
||||||
|
|
||||||
virtual Ray compute_primary_ray(const int x, const int width,
|
virtual Ray compute_primary_ray(const int x, const int width,
|
||||||
const int y, const int height) const = 0;
|
const int y, const int height) const = 0;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ CameraParser::HandleKeyEvent(const std::string& key)
|
||||||
{
|
{
|
||||||
static const std::map<std::string, Section> sSections = {
|
static const std::map<std::string, Section> sSections = {
|
||||||
{"direction", DirectionSection},
|
{"direction", DirectionSection},
|
||||||
|
{"lookAt", LookAtSection},
|
||||||
{"origin", OriginSection},
|
{"origin", OriginSection},
|
||||||
{"right", RightSection},
|
{"right", RightSection},
|
||||||
{"type", TypeSection},
|
{"type", TypeSection},
|
||||||
|
@ -54,6 +55,9 @@ CameraParser::HandleValueEvent(yaml_event_t& event)
|
||||||
case DirectionSection:
|
case DirectionSection:
|
||||||
HandleDirectionEvent(event);
|
HandleDirectionEvent(event);
|
||||||
break;
|
break;
|
||||||
|
case LookAtSection:
|
||||||
|
HandleLookAtEvent(event);
|
||||||
|
break;
|
||||||
case OriginSection:
|
case OriginSection:
|
||||||
HandleOriginEvent(event);
|
HandleOriginEvent(event);
|
||||||
break;
|
break;
|
||||||
|
@ -92,6 +96,25 @@ CameraParser::HandleDirectionEvent(yaml_event_t& event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CameraParser::HandleLookAtEvent(yaml_event_t& event)
|
||||||
|
{
|
||||||
|
if (event.type != YAML_SEQUENCE_START_EVENT) {
|
||||||
|
/* TODO: Clean this up. */
|
||||||
|
assert(event.type != YAML_SEQUENCE_START_EVENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto onDone = [this](Vector3 lookAt) {
|
||||||
|
mCamera->LookAt(lookAt);
|
||||||
|
mSection = NoSection;
|
||||||
|
SetShouldExpectKey(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
GetParsers().push(new Vector3Parser(GetScene(), GetParsers(), onDone));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CameraParser::HandleOriginEvent(yaml_event_t& event)
|
CameraParser::HandleOriginEvent(yaml_event_t& event)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@ private:
|
||||||
enum Section {
|
enum Section {
|
||||||
NoSection,
|
NoSection,
|
||||||
DirectionSection,
|
DirectionSection,
|
||||||
|
LookAtSection,
|
||||||
OriginSection,
|
OriginSection,
|
||||||
RightSection,
|
RightSection,
|
||||||
TypeSection,
|
TypeSection,
|
||||||
|
@ -40,6 +41,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void HandleDirectionEvent(yaml_event_t& event);
|
void HandleDirectionEvent(yaml_event_t& event);
|
||||||
|
void HandleLookAtEvent(yaml_event_t& event);
|
||||||
void HandleOriginEvent(yaml_event_t& event);
|
void HandleOriginEvent(yaml_event_t& event);
|
||||||
void HandleRightEvent(yaml_event_t& event);
|
void HandleRightEvent(yaml_event_t& event);
|
||||||
void HandleTypeEvent(yaml_event_t& event);
|
void HandleTypeEvent(yaml_event_t& event);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue