123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729 |
- /**
- * @file llcoordframe.cpp
- * @brief LLCoordFrame class implementation.
- *
- * $LicenseInfo:firstyear=2000&license=viewergpl$
- *
- * Copyright (c) 2000-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llcoordframe.h"
- #include "llmatrix3.h"
- #include "llmatrix4.h"
- #include "llquaternion.h"
- LLCoordFrame::LLCoordFrame(const LLVector3& origin) noexcept
- : mOrigin(origin),
- mXAxis(1.f, 0.f, 0.f),
- mYAxis(0.f, 1.f, 0.f),
- mZAxis(0.f, 0.f, 1.f)
- {
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLVector3& origin,
- const LLVector3& direction) noexcept
- : mOrigin(origin)
- {
- lookDir(direction);
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLVector3& x_axis,
- const LLVector3& y_axis,
- const LLVector3& z_axis) noexcept
- : mXAxis(x_axis),
- mYAxis(y_axis),
- mZAxis(z_axis)
- {
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLVector3& origin,
- const LLVector3& x_axis,
- const LLVector3& y_axis,
- const LLVector3& z_axis) noexcept
- : mOrigin(origin),
- mXAxis(x_axis),
- mYAxis(y_axis),
- mZAxis(z_axis)
- {
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (4). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLVector3& origin,
- const LLMatrix3& rotation) noexcept
- : mOrigin(origin),
- mXAxis(rotation.mMatrix[VX]),
- mYAxis(rotation.mMatrix[VY]),
- mZAxis(rotation.mMatrix[VZ])
- {
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (5). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLQuaternion& q) noexcept
- {
- LLMatrix3 rotation_matrix(q);
- mXAxis.set(rotation_matrix.mMatrix[VX]);
- mYAxis.set(rotation_matrix.mMatrix[VY]);
- mZAxis.set(rotation_matrix.mMatrix[VZ]);
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (6). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLVector3& origin,
- const LLQuaternion& q) noexcept
- : mOrigin(origin)
- {
- LLMatrix3 rotation_matrix(q);
- mXAxis.set(rotation_matrix.mMatrix[VX]);
- mYAxis.set(rotation_matrix.mMatrix[VY]);
- mZAxis.set(rotation_matrix.mMatrix[VZ]);
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite. Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const LLMatrix4& mat) noexcept
- : mOrigin(mat.mMatrix[VW]),
- mXAxis(mat.mMatrix[VX]),
- mYAxis(mat.mMatrix[VY]),
- mZAxis(mat.mMatrix[VZ])
- {
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (7). Coordinates reset." << llendl;
- }
- }
- #if 0 // The folowing two constructors are dangerous due to implicit casting
- // and have been disabled - SJB
- LLCoordFrame::LLCoordFrame(const F32* origin, const F32* rotation) noexcept
- : mOrigin(origin),
- mXAxis(rotation + 3 * VX),
- mYAxis(rotation + 3 * VY),
- mZAxis(rotation + 3 * VZ)
- {
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (8). Coordinates reset." << llendl;
- }
- }
- LLCoordFrame::LLCoordFrame(const F32* origin_and_rotation) noexcept
- : mOrigin(origin_and_rotation),
- mXAxis(origin_and_rotation + 3 * (VX + 1)),
- mYAxis(origin_and_rotation + 3 * (VY + 1)),
- mZAxis(origin_and_rotation + 3 * (VZ + 1))
- {
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (9). Coordinates reset." << llendl;
- }
- }
- #endif
- void LLCoordFrame::reset()
- {
- mOrigin.clear();
- resetAxes();
- }
- void LLCoordFrame::resetAxes()
- {
- mXAxis.set(1.f, 0.f, 0.f);
- mYAxis.set(0.f, 1.f, 0.f);
- mZAxis.set(0.f, 0.f, 1.f);
- }
- // setOrigin() methods set mOrigin
- void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)
- {
- mOrigin.set(x, y, z);
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setOrigin(const LLVector3& new_origin)
- {
- mOrigin = new_origin;
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setOrigin(const F32* origin)
- {
- mOrigin.mV[VX] = *(origin + VX);
- mOrigin.mV[VY] = *(origin + VY);
- mOrigin.mV[VZ] = *(origin + VZ);
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setOrigin(const LLCoordFrame& frame)
- {
- mOrigin = frame.getOrigin();
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (4). Coordinates reset." << llendl;
- }
- }
- // The setAxes() methods set the axes, and assume that the arguments are
- // orthogonal and normalized.
- void LLCoordFrame::setAxes(const LLVector3& x_axis,
- const LLVector3& y_axis,
- const LLVector3& z_axis)
- {
- mXAxis = x_axis;
- mYAxis = y_axis;
- mZAxis = z_axis;
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setAxes(const LLMatrix3& rotation_matrix)
- {
- mXAxis.set(rotation_matrix.mMatrix[VX]);
- mYAxis.set(rotation_matrix.mMatrix[VY]);
- mZAxis.set(rotation_matrix.mMatrix[VZ]);
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setAxes(const LLQuaternion& q)
- {
- LLMatrix3 rotation_matrix(q);
- setAxes(rotation_matrix);
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setAxes(const F32* rotation_matrix)
- {
- mXAxis.mV[VX] = *(rotation_matrix + (3 * VX + VX));
- mXAxis.mV[VY] = *(rotation_matrix + (3 * VX + VY));
- mXAxis.mV[VZ] = *(rotation_matrix + (3 * VX + VZ));
- mYAxis.mV[VX] = *(rotation_matrix + (3 * VY + VX));
- mYAxis.mV[VY] = *(rotation_matrix + (3 * VY + VY));
- mYAxis.mV[VZ] = *(rotation_matrix + (3 * VY + VZ));
- mZAxis.mV[VX] = *(rotation_matrix + (3 * VZ + VX));
- mZAxis.mV[VY] = *(rotation_matrix + (3 * VZ + VY));
- mZAxis.mV[VZ] = *(rotation_matrix + (3 * VZ + VZ));
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (4). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::setAxes(const LLCoordFrame& frame)
- {
- mXAxis = frame.getXAxis();
- mYAxis = frame.getYAxis();
- mZAxis = frame.getZAxis();
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (5). Coordinates reset." << llendl;
- }
- }
- // The translate() methods move mOrigin to a relative position
- void LLCoordFrame::translate(F32 x, F32 y, F32 z)
- {
- mOrigin.mV[VX] += x;
- mOrigin.mV[VY] += y;
- mOrigin.mV[VZ] += z;
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (1). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::translate(const LLVector3& v)
- {
- mOrigin += v;
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (2). Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::translate(const F32* origin)
- {
- mOrigin.mV[VX] += *(origin + VX);
- mOrigin.mV[VY] += *(origin + VY);
- mOrigin.mV[VZ] += *(origin + VZ);
- if (!mOrigin.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite (3). Coordinates reset." << llendl;
- }
- }
- // Rotate methods move the axes to a relative rotation
- void LLCoordFrame::rotate(F32 angle, F32 x, F32 y, F32 z)
- {
- LLQuaternion q(angle, LLVector3(x,y,z));
- rotate(q);
- }
- void LLCoordFrame::rotate(F32 angle, const LLVector3& rotation_axis)
- {
- LLQuaternion q(angle, rotation_axis);
- rotate(q);
- }
- void LLCoordFrame::rotate(const LLQuaternion& q)
- {
- LLMatrix3 rotation_matrix(q);
- rotate(rotation_matrix);
- }
- void LLCoordFrame::rotate(const LLMatrix3& rotation_matrix)
- {
- mXAxis.rotVec(rotation_matrix);
- mYAxis.rotVec(rotation_matrix);
- orthonormalize();
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite. Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::roll(F32 angle)
- {
- LLQuaternion q(angle, mXAxis);
- LLMatrix3 rotation_matrix(q);
- rotate(rotation_matrix);
- if (!mYAxis.isFinite() || !mZAxis.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite. Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::pitch(F32 angle)
- {
- LLQuaternion q(angle, mYAxis);
- LLMatrix3 rotation_matrix(q);
- rotate(rotation_matrix);
- if (!mXAxis.isFinite() || !mZAxis.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite. Coordinates reset." << llendl;
- }
- }
- void LLCoordFrame::yaw(F32 angle)
- {
- LLQuaternion q(angle, mZAxis);
- LLMatrix3 rotation_matrix(q);
- rotate(rotation_matrix);
- if (!mXAxis.isFinite() || !mYAxis.isFinite())
- {
- reset();
- llwarns_sparse << "Non finite. Coordinates reset." << llendl;
- }
- }
- LLQuaternion LLCoordFrame::getQuaternion() const
- {
- LLQuaternion quat(mXAxis, mYAxis, mZAxis);
- return quat;
- }
- void LLCoordFrame::getMatrixToLocal(LLMatrix4& mat) const
- {
- mat.setFwdCol(mXAxis);
- mat.setLeftCol(mYAxis);
- mat.setUpCol(mZAxis);
- mat.mMatrix[3][0] = -(mOrigin * LLVector3(mat.mMatrix[0][0],
- mat.mMatrix[1][0],
- mat.mMatrix[2][0]));
- mat.mMatrix[3][1] = -(mOrigin * LLVector3(mat.mMatrix[0][1],
- mat.mMatrix[1][1],
- mat.mMatrix[2][1]));
- mat.mMatrix[3][2] = -(mOrigin * LLVector3(mat.mMatrix[0][2],
- mat.mMatrix[1][2],
- mat.mMatrix[2][2]));
- }
- void LLCoordFrame::getRotMatrixToParent(LLMatrix4& mat) const
- {
- // Note: moves into CFR
- mat.setFwdRow(-mYAxis);
- mat.setLeftRow(mZAxis);
- mat.setUpRow(-mXAxis);
- }
- size_t LLCoordFrame::writeOrientation(char* buffer) const
- {
- memcpy(buffer, mOrigin.mV, 3 * sizeof(F32));
- buffer += 3 * sizeof(F32);
- memcpy(buffer, mXAxis.mV, 3 * sizeof(F32));
- buffer += 3 * sizeof(F32);
- memcpy(buffer, mYAxis.mV, 3 * sizeof(F32));
- buffer += 3 * sizeof(F32);
- memcpy(buffer, mZAxis.mV, 3 * sizeof(F32));
- return 12 * sizeof(F32);
- }
- size_t LLCoordFrame::readOrientation(const char* buffer)
- {
- memcpy(mOrigin.mV, buffer, 3 * sizeof(F32));
- buffer += 3 * sizeof(F32);
- memcpy(mXAxis.mV, buffer, 3 * sizeof(F32));
- buffer += 3 * sizeof(F32);
- memcpy(mYAxis.mV, buffer, 3 * sizeof(F32));
- buffer += 3 * sizeof(F32);
- memcpy(mZAxis.mV, buffer, 3 * sizeof(F32));
- if (!isFinite())
- {
- reset();
- llwarns_sparse << "Non finite. Coordinates reset." << llendl;
- }
- return 12 * sizeof(F32);
- }
- // Rotation and transform vectors between reference frames
- LLVector3 LLCoordFrame::rotateToLocal(const LLVector3& absolute_vector) const
- {
- LLVector3 local_vector(mXAxis * absolute_vector,
- mYAxis * absolute_vector,
- mZAxis * absolute_vector);
- return local_vector;
- }
- LLVector4 LLCoordFrame::rotateToLocal(const LLVector4& absolute_vector) const
- {
- LLVector4 local_vector;
- local_vector.mV[VX] = mXAxis.mV[VX] * absolute_vector.mV[VX] +
- mXAxis.mV[VY] * absolute_vector.mV[VY] +
- mXAxis.mV[VZ] * absolute_vector.mV[VZ];
- local_vector.mV[VY] = mYAxis.mV[VX] * absolute_vector.mV[VX] +
- mYAxis.mV[VY] * absolute_vector.mV[VY] +
- mYAxis.mV[VZ] * absolute_vector.mV[VZ];
- local_vector.mV[VZ] = mZAxis.mV[VX] * absolute_vector.mV[VX] +
- mZAxis.mV[VY] * absolute_vector.mV[VY] +
- mZAxis.mV[VZ] * absolute_vector.mV[VZ];
- local_vector.mV[VW] = absolute_vector.mV[VW];
- return local_vector;
- }
- LLVector3 LLCoordFrame::rotateToAbsolute(const LLVector3& local_vector) const
- {
- LLVector3 absolute_vector;
- absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] +
- mYAxis.mV[VX] * local_vector.mV[VY] +
- mZAxis.mV[VX] * local_vector.mV[VZ];
- absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] +
- mYAxis.mV[VY] * local_vector.mV[VY] +
- mZAxis.mV[VY] * local_vector.mV[VZ];
- absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] +
- mYAxis.mV[VZ] * local_vector.mV[VY] +
- mZAxis.mV[VZ] * local_vector.mV[VZ];
- return absolute_vector;
- }
- LLVector4 LLCoordFrame::rotateToAbsolute(const LLVector4& local_vector) const
- {
- LLVector4 absolute_vector;
- absolute_vector.mV[VX] = mXAxis.mV[VX] * local_vector.mV[VX] +
- mYAxis.mV[VX] * local_vector.mV[VY] +
- mZAxis.mV[VX] * local_vector.mV[VZ];
- absolute_vector.mV[VY] = mXAxis.mV[VY] * local_vector.mV[VX] +
- mYAxis.mV[VY] * local_vector.mV[VY] +
- mZAxis.mV[VY] * local_vector.mV[VZ];
- absolute_vector.mV[VZ] = mXAxis.mV[VZ] * local_vector.mV[VX] +
- mYAxis.mV[VZ] * local_vector.mV[VY] +
- mZAxis.mV[VZ] * local_vector.mV[VZ];
- absolute_vector.mV[VW] = local_vector[VW];
- return absolute_vector;
- }
- void LLCoordFrame::orthonormalize()
- {
- // Makes sure the axes are orthogonal and normalized.
- mXAxis.normalize(); // X is renormalized
- mYAxis -= mXAxis * (mXAxis * mYAxis); // Y remains in X-Y plane
- mYAxis.normalize(); // Y is normalized
- mZAxis = mXAxis % mYAxis; // Z = X cross Y
- }
- LLVector3 LLCoordFrame::transformToLocal(const LLVector3& absolute_vector) const
- {
- return rotateToLocal(absolute_vector - mOrigin);
- }
- LLVector4 LLCoordFrame::transformToLocal(const LLVector4& absolute_vector) const
- {
- LLVector4 local_vector(absolute_vector);
- local_vector.mV[VX] -= mOrigin.mV[VX];
- local_vector.mV[VY] -= mOrigin.mV[VY];
- local_vector.mV[VZ] -= mOrigin.mV[VZ];
- return rotateToLocal(local_vector);
- }
- LLVector3 LLCoordFrame::transformToAbsolute(const LLVector3& local_vector) const
- {
- return (rotateToAbsolute(local_vector) + mOrigin);
- }
- LLVector4 LLCoordFrame::transformToAbsolute(const LLVector4& local_vector) const
- {
- LLVector4 absolute_vector;
- absolute_vector = rotateToAbsolute(local_vector);
- absolute_vector.mV[VX] += mOrigin.mV[VX];
- absolute_vector.mV[VY] += mOrigin.mV[VY];
- absolute_vector.mV[VZ] += mOrigin.mV[VZ];
- return absolute_vector;
- }
- // This is how you combine a translation and rotation of a
- // coordinate frame to get an OpenGL transformation matrix:
- //
- // translation * rotation = transformation matrix
- //
- // (i)->
- // (j)| 1 0 0 0 | | a d g 0 | | a d g 0 |
- // | | 0 1 0 0 | * | b e h 0 | = | b e h 0 |
- // V | 0 0 1 0 | | c f i 0 | | c f i 0 |
- // |-x -y -z 1 | | 0 0 0 1 | |-(ax+by+cz) -(dx+ey+fz) -(gx+hy+iz) 1 |
- //
- // where {a,b,c} = x-axis
- // {d,e,f} = y-axis
- // {g,h,i} = z-axis
- // {x,y,z} = origin
- void LLCoordFrame::getOpenGLTranslation(F32* ogl_matrix) const
- {
- *(ogl_matrix + 0) = 1.f;
- *(ogl_matrix + 1) = 0.f;
- *(ogl_matrix + 2) = 0.f;
- *(ogl_matrix + 3) = 0.f;
- *(ogl_matrix + 4) = 0.f;
- *(ogl_matrix + 5) = 1.f;
- *(ogl_matrix + 6) = 0.f;
- *(ogl_matrix + 7) = 0.f;
- *(ogl_matrix + 8) = 0.f;
- *(ogl_matrix + 9) = 0.f;
- *(ogl_matrix + 10) = 1.f;
- *(ogl_matrix + 11) = 0.f;
- *(ogl_matrix + 12) = -mOrigin.mV[VX];
- *(ogl_matrix + 13) = -mOrigin.mV[VY];
- *(ogl_matrix + 14) = -mOrigin.mV[VZ];
- *(ogl_matrix + 15) = 1.f;
- }
- void LLCoordFrame::getOpenGLRotation(F32* ogl_matrix) const
- {
- *(ogl_matrix + 0) = mXAxis.mV[VX];
- *(ogl_matrix + 4) = mXAxis.mV[VY];
- *(ogl_matrix + 8) = mXAxis.mV[VZ];
- *(ogl_matrix + 1) = mYAxis.mV[VX];
- *(ogl_matrix + 5) = mYAxis.mV[VY];
- *(ogl_matrix + 9) = mYAxis.mV[VZ];
- *(ogl_matrix + 2) = mZAxis.mV[VX];
- *(ogl_matrix + 6) = mZAxis.mV[VY];
- *(ogl_matrix + 10) = mZAxis.mV[VZ];
- *(ogl_matrix + 3) = 0.f;
- *(ogl_matrix + 7) = 0.f;
- *(ogl_matrix + 11) = 0.f;
- *(ogl_matrix + 12) = 0.f;
- *(ogl_matrix + 13) = 0.f;
- *(ogl_matrix + 14) = 0.f;
- *(ogl_matrix + 15) = 1.f;
- }
- void LLCoordFrame::getOpenGLTransform(F32* ogl_matrix) const
- {
- *(ogl_matrix + 0) = mXAxis.mV[VX];
- *(ogl_matrix + 4) = mXAxis.mV[VY];
- *(ogl_matrix + 8) = mXAxis.mV[VZ];
- *(ogl_matrix + 12) = -mOrigin * mXAxis;
- *(ogl_matrix + 1) = mYAxis.mV[VX];
- *(ogl_matrix + 5) = mYAxis.mV[VY];
- *(ogl_matrix + 9) = mYAxis.mV[VZ];
- *(ogl_matrix + 13) = -mOrigin * mYAxis;
- *(ogl_matrix + 2) = mZAxis.mV[VX];
- *(ogl_matrix + 6) = mZAxis.mV[VY];
- *(ogl_matrix + 10) = mZAxis.mV[VZ];
- *(ogl_matrix + 14) = -mOrigin * mZAxis;
- *(ogl_matrix + 3) = 0.f;
- *(ogl_matrix + 7) = 0.f;
- *(ogl_matrix + 11) = 0.f;
- *(ogl_matrix + 15) = 1.f;
- }
- // at and up_direction are presumed to be normalized
- void LLCoordFrame::lookDir(const LLVector3& at, const LLVector3& up_direction)
- {
- // Make sure 'at' and 'up_direction' are not parallel
- // and that neither are zero-length vectors
- LLVector3 left(up_direction % at);
- if (left.isNull())
- {
- // tweak lookat pos so we don't get a degenerate matrix
- LLVector3 tempat(at[VX] + 0.01f, at[VY], at[VZ]);
- tempat.normalize();
- left = (up_direction % tempat);
- }
- left.normalize();
- LLVector3 up = at % left;
- if (at.isFinite() && left.isFinite() && up.isFinite())
- {
- setAxes(at, left, up);
- }
- }
- void LLCoordFrame::lookDir(const LLVector3& xuv)
- {
- lookDir(xuv, LLVector3::z_axis);
- }
- void LLCoordFrame::lookAt(const LLVector3& origin,
- const LLVector3& point_of_interest,
- const LLVector3& up_direction)
- {
- setOrigin(origin);
- LLVector3 at(point_of_interest - origin);
- at.normalize();
- lookDir(at, up_direction);
- }
- void LLCoordFrame::lookAt(const LLVector3& origin,
- const LLVector3& point_of_interest)
- {
- setOrigin(origin);
- LLVector3 at(point_of_interest - origin);
- at.normalize();
- lookDir(at, LLVector3::z_axis);
- }
- // Operators and friends
- std::ostream& operator<<(std::ostream& s, const LLCoordFrame& c)
- {
- s << "{ "
- << " origin = " << c.mOrigin
- << " x_axis = " << c.mXAxis
- << " y_axis = " << c.mYAxis
- << " z_axis = " << c.mZAxis
- << " }";
- return s;
- }
|