在你的图形工程中添加轨迹球的功能,可以更好的对模型进行查看。
之前写过一个.ply模型的读取程序,加入了下面轨迹球的功能。
下面是一个比较经典的轨迹球实现程序。
ArcBall.h
#pragma once
///ArcBall.h///
#ifndef _ArcBall_h
#define _ArcBall_h
// 仅在Debug模式下,启用断言
#ifdef _DEBUG
# include "assert.h"
#else
# define assert(x) { }
#endif
//2维点
typedef union Tuple2f_t
{
struct
{
GLfloat X, Y;
} s;
GLfloat T[2];
} Tuple2fT;
//3维点
typedef union Tuple3f_t
{
struct
{
GLfloat X, Y, Z;
} s;
GLfloat T[3];
} Tuple3fT;
//4维点
typedef union Tuple4f_t
{
struct
{
GLfloat X, Y, Z, W;
} s;
GLfloat T[4];
} Tuple4fT;
//3x3矩阵
typedef union Matrix3f_t
{
struct
{
//column major
union { GLfloat M00; GLfloat XX; GLfloat SX; };
union { GLfloat M10; GLfloat XY; };
union { GLfloat M20; GLfloat XZ; };
union { GLfloat M01; GLfloat YX; };
union { GLfloat M11; GLfloat YY; GLfloat SY; };
union { GLfloat M21; GLfloat YZ; };
union { GLfloat M02; GLfloat ZX; };
union { GLfloat M12; GLfloat ZY; };
union { GLfloat M22; GLfloat ZZ; GLfloat SZ; };
} s;
GLfloat M[9];
} Matrix3fT;
//4x4矩阵
typedef union Matrix4f_t
{
struct
{
//column major
union { GLfloat M00; GLfloat XX; GLfloat SX; };
union { GLfloat M10; GLfloat XY; };
union { GLfloat M20; GLfloat XZ; };
union { GLfloat M30; GLfloat XW; };
union { GLfloat M01; GLfloat YX; };
union { GLfloat M11; GLfloat YY; GLfloat SY; };
union { GLfloat M21; GLfloat YZ; };
union { GLfloat M31; GLfloat YW; };
union { GLfloat M02; GLfloat ZX; };
union { GLfloat M12; GLfloat ZY; };
union { GLfloat M22; GLfloat ZZ; GLfloat SZ; };
union { GLfloat M32; GLfloat ZW; };
union { GLfloat M03; GLfloat TX; };
union { GLfloat M13; GLfloat TY; };
union { GLfloat M23; GLfloat TZ; };
union { GLfloat M33; GLfloat TW; GLfloat SW; };
} s;
GLfloat M[16];
} Matrix4fT;
//定义类型的别名
#define Point2fT Tuple2fT
#define Quat4fT Tuple4fT
#define Vector2fT Tuple2fT
#define Vector3fT Tuple3fT
#define FuncSqrt sqrtf
# define Epsilon 1.0e-5
//2维点相加
inline
static void Point2fAdd(Point2fT* NewObj, const Tuple2fT* t1)
{
assert(NewObj && t1);
NewObj->s.X += t1->s.X;
NewObj->s.Y += t1->s.Y;
}
//2维点相减
inline
static void Point2fSub(Point2fT* NewObj, const Tuple2fT* t1)
{
assert(NewObj && t1);
NewObj->s.X -= t1->s.X;
NewObj->s.Y -= t1->s.Y;
}
//3维点矢积
inline
static void Vector3fCross(Vector3fT* NewObj, const Vector3fT* v1, const Vector3fT* v2)
{
Vector3fT Result;
assert(NewObj && v1 && v2);
Result.s.X = (v1->s.Y * v2->s.Z) - (v1->s.Z * v2->s.Y);
Result.s.Y = (v1->s.Z * v2->s.X) - (v1->s.X * v2->s.Z);
Result.s.Z = (v1->s.X * v2->s.Y) - (v1->s.Y * v2->s.X);
*NewObj = Result;
}
//3维点点积
inline
static GLfloat Vector3fDot(const Vector3fT* NewObj, const Vector3fT* v1)
{
assert(NewObj && v1);
return (NewObj->s.X * v1->s.X) +
(NewObj->s.Y * v1->s.Y) +
(NewObj->s.Z * v1->s.Z);
}
//3维点的长度的平方
inline
static GLfloat Vector3fLengthSquared(const Vector3fT* NewObj)
{
assert(NewObj);
return (NewObj->s.X * NewObj->s.X) +
(NewObj->s.Y * NewObj->s.Y) +
(NewObj->s.Z * NewObj->s.Z);
}
//3维点的长度
inline
static GLfloat Vector3fLength(const Vector3fT* NewObj)
{
assert(NewObj);
return FuncSqrt(Vector3fLengthSquared(NewObj));
}
//设置3x3矩阵为0矩阵
inline
static void Matrix3fSetZero(Matrix3fT* NewObj)
{
New