Matrix44f AnimChannel::getPosition( float time ) { if(numPKeys < 1) return Matrix44f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); else if (numPKeys == 1) return Matrix44f(1, 0, 0, positionKeys[0]->getEntry(0), 0, 1, 0, positionKeys[0]->getEntry(1), 0, 0, 1, positionKeys[0]->getEntry(2), 0, 0, 0, 1); float x,y,z; int i = 0; for(; i < numPKeys && pKeyTimes[i] < time; i++){} if(i == 0 || i == numPKeys) //after the last key, loop to first key { //a half-baked guess at the time-interval to get back to the first key (we have no access to total animation duration!) x = Mathf::lerp(time,pKeyTimes[numPKeys-2],pKeyTimes[numPKeys-1],positionKeys[numPKeys-1]->getEntry(0),positionKeys[0]->getEntry(0)); y = Mathf::lerp(time,pKeyTimes[numPKeys-2],pKeyTimes[numPKeys-1],positionKeys[numPKeys-1]->getEntry(1),positionKeys[0]->getEntry(1)); z = Mathf::lerp(time,pKeyTimes[numPKeys-2],pKeyTimes[numPKeys-1],positionKeys[numPKeys-1]->getEntry(2),positionKeys[0]->getEntry(2)); } else { x = Mathf::lerp(time,pKeyTimes[i-1],pKeyTimes[i],positionKeys[i-1]->getEntry(0),positionKeys[i]->getEntry(0)); y = Mathf::lerp(time,pKeyTimes[i-1],pKeyTimes[i],positionKeys[i-1]->getEntry(1),positionKeys[i]->getEntry(1)); z = Mathf::lerp(time,pKeyTimes[i-1],pKeyTimes[i],positionKeys[i-1]->getEntry(2),positionKeys[i]->getEntry(2)); } return Matrix44f(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); }
// ///< returns a matrix which defines a non-uniform scale // Matrix44f Matrix44f::ScaleMatrix( const math::Vec3f &s ) { return Matrix44f( s.x, 0.0f, 0.0f, 0.0f, 0.0f, s.y, 0.0f, 0.0f, 0.0f, 0.0f, s.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
// // returns a matrix which defines a uniform scale // Matrix44f Matrix44f::ScaleMatrix( const float &uniformScale ) { return Matrix44f( uniformScale, 0.0f, 0.0f, 0.0f, 0.0f, uniformScale, 0.0f, 0.0f, 0.0f, 0.0f, uniformScale, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
// // returns a matrix which defines a non-uniform scale // Matrix44f Matrix44f::ScaleMatrix( const float &x, const float &y, const float &z ) { return Matrix44f( x, 0.0f, 0.0f, 0.0f, 0.0f, y, 0.0f, 0.0f, 0.0f, 0.0f, z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
// // returns a matrix which defines a translation of the specified translation vector // Matrix44f Matrix44f::TranslationMatrix( const float &x, const float &y, const float &z ) { return Matrix44f( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, x, y, z, 1.0f); }
// // returns a matrix which defines a translation of the specified translation vector // Matrix44f Matrix44f::TranslationMatrix( const Vec3f &translation ) { return Matrix44f( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, translation.x, translation.y, translation.z, 1.0f); }
Matrix44f AnimChannel::getRotation( float time ) { if(numRKeys < 1) { return Matrix44f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } else if (numRKeys == 1) { return rotationKeys[0]->toMatrix(); } //else interpolate float w,x,y,z,w0,x0,y0,z0,w1,x1,y1,z1,t0,t1; int i = 0; for(; i < numRKeys && rKeyTimes[i] < time; i++){} if(i == 0 || i == numRKeys)//after last point { w0 = rotationKeys[numRKeys - 1]->getW(); x0 = rotationKeys[numRKeys - 1]->getX(); y0 = rotationKeys[numRKeys - 1]->getY(); z0 = rotationKeys[numRKeys - 1]->getZ(); w1 = rotationKeys[0]->getW(); x1 = rotationKeys[0]->getX(); y1 = rotationKeys[0]->getY(); z1 = rotationKeys[0]->getZ(); t0 = rKeyTimes[numRKeys-2]; t1 = rKeyTimes[numRKeys-1]; } else { w0 = rotationKeys[i-1]->getW(); x0 = rotationKeys[i-1]->getX(); y0 = rotationKeys[i-1]->getY(); z0 = rotationKeys[i-1]->getZ(); w1 = rotationKeys[i]->getW(); x1 = rotationKeys[i]->getX(); y1 = rotationKeys[i]->getY(); z1 = rotationKeys[i]->getZ(); t0 = rKeyTimes[i-1]; t1 = rKeyTimes[i]; } Quaternionf rotQuat(Mathf::lerp(time,t0,t1,w0,w1), Mathf::lerp(time,t0,t1,x0,x1), Mathf::lerp(time,t0,t1,y0,y1), Mathf::lerp(time,t0,t1,z0,z1)); return rotQuat.toMatrix(); }
Matrix44f Matrix44f::getTransposed( void ) { return Matrix44f( _11, _21, _31, _41, _12, _22, _32, _42, _13, _23, _33, _43, _14, _24, _34, _44 ); }
Matrix44f Matrix44f::getOrientation( void ) { return Matrix44f( _11, _12, _13, 0.0f, _21, _22, _23, 0.0f, _31, _32, _33, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); }
// // returns the identitymatrix // Matrix44f Matrix44f::Identity( void ) { return Matrix44f( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
void Pipeline::SetCameraLookAt(Vector3f vPosition, Vector3f vTarget, Vector3f vUp) { Matrix44f mCameraTra, mCameraRot; mCameraTra = Matrix44f( 1, 0, 0, vPosition.x, 0, 1, 0, vPosition.y, 0, 0, 1, vPosition.z, 0, 0, 0, 1); Vector3f N = Math::Normalize(vTarget); Vector3f U = Math::Normalize(vUp); U = Math::Cross(U, N); Vector3f V = Math::Cross(N, U); mCameraRot[0] = U.x; mCameraRot[1] = U.y; mCameraRot[2] = U.z; mCameraRot[3] = 0.0f; mCameraRot[4] = V.x; mCameraRot[5] = V.y; mCameraRot[6] = V.z; mCameraRot[7] = 0.0f; mCameraRot[8] = N.x; mCameraRot[9] = N.y; mCameraRot[10] = N.z; mCameraRot[11] = 0.0f; mCameraRot[12] = 0.0f; mCameraRot[13] = 0.0f; mCameraRot[14] = 0.0f; mCameraRot[15] = 1.0f; //mCameraLookAt = mCameraTra; //Math::Identity(mCameraTra); //Math::Translation(mCameraTra, -vPosition); //mCameraRot = Math::CameraTranslation(vTarget, vUp); //mCameraLookAt = Math::Transpose(mCameraRot) * mCameraTra; mCameraLookAt = mCameraRot * mCameraTra; }
// // returns the zeromatrix // Matrix44f Matrix44f::Zero( void ) { return Matrix44f( 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); }
Matrix44f Matrix44f::Identity() { return Matrix44f( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); }
// // returns a matrix which defines a rotation about the z axis with the float-specified amount // Matrix44f Matrix44f::RotationMatrixZ( const float &angle ) { float fSin = sinf( angle ); float fCos = cosf( angle ); return Matrix44f( fCos, -fSin, 0.0f, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
namespace gmtl { const Matrix22f MAT_IDENTITY22F = Matrix22f(); const Matrix22d MAT_IDENTITY22D = Matrix22d(); const Matrix23f MAT_IDENTITY23F = Matrix23f(); const Matrix23d MAT_IDENTITY23D = Matrix23d(); const Matrix33f MAT_IDENTITY33F = Matrix33f(); const Matrix33d MAT_IDENTITY33D = Matrix33d(); const Matrix34f MAT_IDENTITY34F = Matrix34f(); const Matrix34d MAT_IDENTITY34D = Matrix34d(); const Matrix44f MAT_IDENTITY44F = Matrix44f(); const Matrix44d MAT_IDENTITY44D = Matrix44d(); }
//------------------------------------------------------------------- void ICamera::CreatePerspectiveProjection(float radian, float aspect, float nearClip, float farClip) { m_isNearFarChange = true; m_Fov = radian; m_Aspect = aspect; m_Near = nearClip; m_Far = farClip; m_Middle = m_Near + ( m_Far - m_Near ) * 0.5; m_NearQ_Q.m_y = m_Far / ( m_Far - m_Near ); m_NearQ_Q.m_x = m_Near * m_NearQ_Q.m_y; m_LineDepthParam.m_x = m_Near; m_LineDepthParam.m_y = 1.0 / ( m_Far - m_Near ); m_LineDepthParam.m_z = m_Far - m_Near; m_LineDepthParamBias.m_x = m_Near; m_LineDepthParamBias.m_y = 1.0 / ( m_Far*BAIS - m_Near ); m_LineDepthParamBias.m_z = m_Far*BAIS - m_Near; //float SinFov = sin( 0.5f * radian ); //float CosFov = cos( 0.5f * radian ); //float h = CosFov / SinFov; float h = 1.0f / Math::Tan( radian * 0.5f ); float w = h / aspect; float p1 = -( farClip ) / ( farClip - nearClip ); float p2 = -( farClip * nearClip ) / ( farClip - nearClip ); //farClip += 0.01f * ( farClip - nearClip ) * nearClip / farClip ; farClip *= BAIS; float p1b = -( farClip ) / ( farClip - nearClip ); float p2b = -( farClip * nearClip ) / ( farClip - nearClip ); m_Project = Matrix44f( w, 0.0, 0.0, 0.0, 0.0, h, 0.0, 0.0, 0.0, 0.0, p1, -1.0f, 0.0, 0.0, p2, 0.0); m_ProjectBias = Matrix44f( w, 0.0, 0.0, 0.0, 0.0, h, 0.0, 0.0, 0.0, 0.0, p1b, -1.0f, 0.0, 0.0, p2b, 0.0); m_isChange = true; }
Matrix44f Matrix44f::getNormalizedOrientation( void ) { static Vec3f g_vRight; static Vec3f g_vUp; static Vec3f g_vDir; g_vRight = getRight(); g_vUp = getUp(); g_vDir = getDir(); return Matrix44f( g_vRight.x, g_vRight.y, g_vRight.z, 0.0f, g_vUp.x, g_vUp.y, g_vUp.z, 0.0f, g_vDir.x, g_vDir.y, g_vDir.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f ); }
void Camera::FocusOnPoint(Position aFocusPoint) { Vector3<float> forwardVector = aFocusPoint - myOrientation.GetTranslation(); Normalize(forwardVector); Position position = myOrientation.GetTranslation(); myOrientation = Matrix44f(); myOrientation = myOrientation.CreateRotateAroundX(forwardVector.myX * PI) * myOrientation; myOrientation = myOrientation.CreateRotateAroundY(forwardVector.myY * PI) * myOrientation; myOrientation = myOrientation.CreateRotateAroundZ(forwardVector.myZ * PI) * myOrientation; myOrientation.SetTranslation(position); }
// // returns a matrix with a transformation that rotates around // a certain axis which starts at the origin // Matrix44f Matrix44f::RotationMatrix( const Vec3f &axis, const float &angle ) { // code from Graphics Gems (Glassner, Academic Press, 1990) float c = cos( angle ); float t = 1.0f - c; float s = sin( angle ); float txy = t*axis.x*axis.y; float txz = t*axis.x*axis.z; float tyz = t*axis.y*axis.z; float sx = s*axis.x; float sy = s*axis.y; float sz = s*axis.z; return Matrix44f( t*axis.x*axis.x+c, txy+sz, txz-sy, 0.0f, txy-sz, t*axis.y*axis.y+c, tyz+sx, 0.0f, txz+sy, tyz-sx, t*axis.z*axis.z+c, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }
////------------------------------------------------------------------- //void Camera::CreateView(vector3f& position, vector3f& dir, vector3f& up) //{ // vector3f ZAxis = dir; // vector3f XAxis = Cross( up, ZAxis ); // vector3f YAxis = Cross( ZAxis, XAxis ); // XAxis.NormalizeSelf(); // YAxis.NormalizeSelf(); // ZAxis.NormalizeSelf(); // // m_View = Matrix44f( -XAxis.m_x, +YAxis.m_x, -ZAxis.m_x, 0.0f, // -XAxis.m_y, +YAxis.m_y, -ZAxis.m_y, 0.0f, // -XAxis.m_z, +YAxis.m_z, -ZAxis.m_z, 0.0f, // +Dot( XAxis, position ), -Dot( YAxis, position ), +Dot( ZAxis, position ), 1.0f); // m_isChange = true; //} //------------------------------------------------------------------- void ICamera::Update () { //*m_pView = Matrix44f::CreateRotateMatrix(vector3f(0,1,0),0.01) * *m_pView; //m_isChange = true; if( m_isChange ) { m_EventOnCameraUpdate.Multicast( *this ); m_isChange = false; //计算新的view矩阵 vector3f ZAxis = m_Position - m_LookAt; vector3f XAxis = m_Up.Cross( ZAxis ); vector3f YAxis = ZAxis.Cross( XAxis ); XAxis.NormalizeSelf(); YAxis.NormalizeSelf(); ZAxis.NormalizeSelf(); m_View = Matrix44f( XAxis.m_x, YAxis.m_x, ZAxis.m_x, 0.0f, XAxis.m_y, YAxis.m_y, ZAxis.m_y, 0.0f, XAxis.m_z, YAxis.m_z, ZAxis.m_z, 0.0f, -XAxis.Dot( m_Position ), -YAxis.Dot( m_Position ), -ZAxis.Dot( m_Position ), 1.0f); m_ViewProject = (m_View) * (m_Project); //计算其他矩阵 m_isDirtyRotation = true; m_isDirtyTransform = true; m_isDirtyViewProjectBias = true; m_isDirtyUnView = true; m_isDirtyUnProject = true; m_isDirtyUnViewProject = true; //m_Transform = vector3f( m_View.a41, m_View.a42, m_View.a43 ); //m_Rotation = Matrix33f(m_View); //m_ViewProjectBias = (m_View) * (m_ProjectBias); //m_View.GetInverse(m_UnView, false); //m_Project.GetInverse(m_UnProject); //m_UnViewProject = m_UnProject * m_UnView; } }
#include <iostream> #include <fstream> #include <cmath> #include <sstream> #include <chrono> #include <vector> #include <cstring> #include <string> #include "geometry.h" #define M_PI 3.14159 static const float kInfinity = std::numeric_limits<float>::max(); static const float kEpsilon = 1e-8; static const Vec3f kDefaultBackgroundColor = Vec3f(1); template <> const Matrix44f Matrix44f::kIdentity = Matrix44f(); const int MAX_LINE_LENGTH = 100; inline float clamp(const float &lo, const float &hi, const float &v) { return std::max(lo, std::min(hi, v)); } inline float deg2rad(const float °) { return deg * M_PI / 180; } inline Vec3f mix(const Vec3f &a, const Vec3f& b, const float &mixValue) { return a * (1 - mixValue) + b * mixValue; } struct Options {
void CanvasContext::transform(float m11, float m12, float m21, float m22, float dx, float dy) { MatrixAffine2f m(m11, m12, m21, m22, dx, dy); state->transform *= m; gl::multModelView(Matrix44f(m)); }
//------------------------------------------------------------------- void ICamera::CreateOrthographiProjection(float w, float h, float n, float f) { //详细请见 //http://en.wikipedia.org/wiki/Orthographic_projection_(geometry) //http://www.songho.ca/opengl/gl_projectionmatrix.html //连接中的矩阵为列主序,我的引擎中使用的是行主徐 m_isNearFarChange = true; m_Near = n; m_Far = f; m_Middle = m_Near + ( m_Far - m_Near ) * 0.5; m_NearQ_Q.m_y = m_Far / ( m_Far - m_Near ); m_NearQ_Q.m_x = m_Near * m_NearQ_Q.m_y; m_LineDepthParam.m_x = m_Near; m_LineDepthParam.m_y = 1.0 / ( m_Far - m_Near ); m_LineDepthParam.m_z = m_Far - m_Near; m_LineDepthParamBias.m_x = m_Near; m_LineDepthParamBias.m_y = 1.0 / ( m_Far*BAIS - m_Near ); m_LineDepthParamBias.m_z = m_Far*BAIS - m_Near; //float r = 2.0f / w; //float t = 2.0f / h; //float p1 = -2 / ( f - n ); //float p2 = - ( f + n ) / ( f - n ); //f += 0.01f * ( f - n ) * n / f ; //float p1b = -2 / ( f - n ); //float p2b = - ( f + n ) / ( f - n ); //m_Project = Matrix44f( r, 0.0, 0.0, 0.0, // 0.0, t, 0.0, 0.0, // 0.0, 0.0, p1, 0.0, // 0.0, 0.0, p2, 1.0); //m_ProjectBias = Matrix44f( r, 0.0, 0.0, 0.0, // 0.0, t, 0.0, 0.0, // 0.0, 0.0, p1b, 0.0, // 0.0, 0.0, p2b, 1.0); float const left = -w / 2.0f; float const right = w / 2.0f; float const top = h / 2.0f; float const bottom = -h / 2.0f; float const q = 1.0f / (f - n); float const invWidth = 1.0f / (right - left); float const invHeight = 1.0f / (top - bottom); m_Project = Matrix44f( invWidth + invWidth, 0, 0, 0, 0, invHeight + invHeight, 0, 0, 0, 0, -q, 0,//这个q应该是-q,还是左右手坐标系的问题,如果是q的话会导致问题 -(left + right) * invWidth, -(top + bottom) * invHeight, -n * q, 1); f *= BAIS; float const qb = 1.0f / (f - n); m_ProjectBias = Matrix44f( invWidth + invWidth, 0, 0, 0, 0, invHeight + invHeight, 0, 0, 0, 0, -qb, 0, -(left + right) * invWidth, -(top + bottom) * invHeight, -n * qb, 1); m_isChange = true; }
void CanvasContext::setTransform(float m11, float m12, float m21, float m22, float dx, float dy) { gl::multModelView(Matrix44f(state->transform.invertCopy())); state->transform.set(m11, m12, m21, m22, dx, dy); gl::multModelView(Matrix44f(state->transform)); }