问题
I want to try and make a game that utilises movement through 4D cross sections. I have looked repeatedly, but cannot find any answers that present complete and clear code - the closest i found was [how should i handle (morphing) 4D objects in opengl? which contains what I need, however, upon trying to utilise the code, not all of the architecture was described clearly, such as the file containing the 5x5 matrix.
回答1:
4D Reper
I did not post it before as it would not fit into 30KByte limit along with the rest of my answers... And also its just basic use of matrices which should be obvious to anyone who make 3D or higher dimensionality vector gfx ...
It uses nd_math.h internaly. And basically reflects my 3D reper class based on all the knowledge of 4x4 homogenous transform matrices I gain over the years. The reper
itself is class
that stores single cumulative homogenuous matrix along with its inverted counterpart and self repairs itself to maintain ortho-normality of basis vectors.
//---------------------------------------------------------------------------
//--- Reper 4D: ver 1.000 ---------------------------------------------------
//---------------------------------------------------------------------------
#ifndef _reper4D_h
#define _reper4D_h
//---------------------------------------------------------------------------
#include "nd_math.h"
//---------------------------------------------------------------------------
const double pi = M_PI;
const double pi2 =2.0*M_PI;
const double pipol=0.5*M_PI;
const double deg=M_PI/180.0;
const double rad=180.0/M_PI;
const int _reper_max_cnt=16;
//---------------------------------------------------------------------------
class reper4D
{
/* xx yx zx wx x0
xy yy zy wy y0
xz yz zz wz z0
xw yw zw ww w0
0 0 0 0 1 */
public:
matrix<5> rep,inv; // 4D uniform 5x5 transform matrix direct, inverse
int _rep,_inv; // is actual ?
int cnt; // dir operation counter
reper4D() { reset(); }
reper4D(reper4D& a) { *this=a; }
~reper4D() {}
reper4D* operator = (const reper4D *a) { *this=*a; return this; }
//reper4D* operator = (const reper4D &a) { ...copy... return this; }
void reset() { rep.unit(); inv.unit(); _rep=1; _inv=1; cnt=0; orto(1); }
void use_rep();
void use_inv();
void use_all();
void orto(int test=0); // kolmost ak treba (podla cnt,alebo hned ak test!=0)
void g2l (vector<4> &l,vector<4> &g); // global xyzw -> local xyzw
void l2g (vector<4> &g,vector<4> &l); // global xyzw <- local xyzw
void g2l_dir(vector<4> &l,vector<4> &g); // global xyzw -> local xyzw , only direction change
void l2g_dir(vector<4> &g,vector<4> &l); // global xyzw <- local xyzw , only direction change
void g2l_rep(reper4D &l,reper4D g);
void l2g_rep(reper4D &g,reper4D l);
void axisx_get(vector<4> &p);
void axisx_set(vector<4> &p);
void axisy_get(vector<4> &p);
void axisy_set(vector<4> &p);
void axisz_get(vector<4> &p);
void axisz_set(vector<4> &p);
void axisw_get(vector<4> &p);
void axisw_set(vector<4> &p);
void lpos_get (vector<4> &p); // get origin in local xyzw (vzdy 0,0,0)
void lpos_set (vector<4> &p); // set origin in local xyzw
void gpos_get (vector<4> &p); // get origin in global xyzw
void gpos_set (vector<4> &p); // set origin in global xyzw
void gpos_add (vector<4> &p); // move origin in global xyzw
void gpos_sub (vector<4> &p); // move origin in global xyzw
void rot_rnd(); // random orientation
// local rotations paralel to hyper plane
void lrot_xy(double ang);
void lrot_yz(double ang);
void lrot_zx(double ang);
void lrot_xw(double ang);
void lrot_yw(double ang);
void lrot_zw(double ang);
// global rotations paralel to hyper plane
void grot_xy(double ang);
void grot_yz(double ang);
void grot_zx(double ang);
void grot_xw(double ang);
void grot_yw(double ang);
void grot_zw(double ang);
void rep2rep(reper4D r0,reper4D r1); // this=r1<<r0
void rep_rep(reper4D r0,reper4D r1); // this=r1>>r0
void repset(matrix<5> &m);
void invset(matrix<5> &m);
void repget(matrix<5> &m);
void invget(matrix<5> &m);
void mul_rep_mat(matrix<5> &m) { use_rep(); rep=rep*m; _inv=0; cnt++; orto(); }
void mul_inv_mat(matrix<5> &m) { use_inv(); inv=inv*m; _rep=0; cnt++; orto(); }
void mul_mat_rep(matrix<5> &m) { use_rep(); rep=m*rep; _inv=0; cnt++; orto(); }
void mul_mat_inv(matrix<5> &m) { use_inv(); inv=m*inv; _rep=0; cnt++; orto(); }
vector<4> mul_mat_vec (matrix<5> &m,vector<4> &v);
vector<4> mul_mat_vec_dir(matrix<5> &m,vector<4> &v);
};
//---------------------------------------------------------------------------
void reper4D::use_rep() { if (!_rep) { rep=inv.inverse(); _rep=1; _inv=1; cnt++; orto(); }
if (!_rep) { rep=inv.inverse(); _rep=1; _inv=1; } }
void reper4D::use_inv() { if (!_inv) { inv=rep.inverse(); _rep=1; _inv=1; cnt++; orto(); }
if (!_inv) { inv=rep.inverse(); _rep=1; _inv=1; } }
void reper4D::use_all() { use_rep(); use_inv(); }
//---------------------------------------------------------------------------
void reper4D::orto(int test)
{
if ((cnt>=_reper_max_cnt)||(test))
{
use_rep();
rep.orthonormal();
_rep=1; _inv=0; cnt=0;
}
}
//---------------------------------------------------------------------------
void reper4D::g2l (vector<4> &l,vector<4> &g) { use_inv(); l=mul_mat_vec(inv,g); }
void reper4D::l2g (vector<4> &g,vector<4> &l) { use_rep(); g=mul_mat_vec(rep,l); }
void reper4D::g2l_dir(vector<4> &l,vector<4> &g) { use_inv(); l=mul_mat_vec_dir(inv,g); }
void reper4D::l2g_dir(vector<4> &g,vector<4> &l) { use_rep(); g=mul_mat_vec_dir(rep,l); }
//---------------------------------------------------------------------------
void reper4D::g2l_rep(reper4D &l,reper4D g)
{
vector<4> p;
g.gpos_get(p); g2l(p,p); l.gpos_set(p);
g.axisx_get(p); g2l_dir(p,p); l.axisx_set(p);
g.axisy_get(p); g2l_dir(p,p); l.axisy_set(p);
g.axisz_get(p); g2l_dir(p,p); l.axisz_set(p);
g.axisw_get(p); g2l_dir(p,p); l.axisw_set(p);
}
//---------------------------------------------------------------------------
void reper4D::l2g_rep(reper4D &g,reper4D l)
{
vector<4> p;
l.gpos_get(p); l2g(p,p); g.gpos_set(p);
l.axisx_get(p); l2g_dir(p,p); g.axisx_set(p);
l.axisy_get(p); l2g_dir(p,p); g.axisy_set(p);
l.axisz_get(p); l2g_dir(p,p); g.axisz_set(p);
l.axisw_get(p); l2g_dir(p,p); g.axisw_set(p);
}
//---------------------------------------------------------------------------
void reper4D::axisx_get(vector<4> &p)
{
use_rep();
p[0]=rep[0][0];
p[1]=rep[1][0];
p[2]=rep[2][0];
p[3]=rep[3][0];
}
//---------------------------------------------------------------------------
void reper4D::axisx_set(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][0]=p[0];
rep[1][0]=p[1];
rep[2][0]=p[2];
rep[3][0]=p[3];
cnt=_reper_max_cnt;
}
//---------------------------------------------------------------------------
void reper4D::axisy_get(vector<4> &p)
{
use_rep();
p[0]=rep[0][1];
p[1]=rep[1][1];
p[2]=rep[2][1];
p[3]=rep[3][1];
}
//---------------------------------------------------------------------------
void reper4D::axisy_set(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][1]=p[0];
rep[1][1]=p[1];
rep[2][1]=p[2];
rep[3][1]=p[3];
cnt=_reper_max_cnt;
}
//---------------------------------------------------------------------------
void reper4D::axisz_get(vector<4> &p)
{
use_rep();
p[0]=rep[0][2];
p[1]=rep[1][2];
p[2]=rep[2][2];
p[3]=rep[3][2];
}
//---------------------------------------------------------------------------
void reper4D::axisz_set(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][2]=p[0];
rep[1][2]=p[1];
rep[2][2]=p[2];
rep[3][2]=p[3];
cnt=_reper_max_cnt;
}
//---------------------------------------------------------------------------
void reper4D::axisw_get(vector<4> &p)
{
use_rep();
p[0]=rep[0][3];
p[1]=rep[1][3];
p[2]=rep[2][3];
p[3]=rep[3][3];
}
//---------------------------------------------------------------------------
void reper4D::axisw_set(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][3]=p[0];
rep[1][3]=p[1];
rep[2][3]=p[2];
rep[3][3]=p[3];
cnt=_reper_max_cnt;
}
//---------------------------------------------------------------------------
void reper4D::lpos_get(vector<4> &p)
{
p[0]=0;
p[1]=0;
p[2]=0;
p[3]=0;
}
//---------------------------------------------------------------------------
void reper4D::lpos_set(vector<4> &p)
{
vector<4> q;
l2g(q,p);
gpos_set(q);
}
//---------------------------------------------------------------------------
void reper4D::gpos_get(vector<4> &p)
{
use_rep();
p[0]=rep[0][4];
p[1]=rep[1][4];
p[2]=rep[2][4];
p[3]=rep[3][4];
orto();
}
//---------------------------------------------------------------------------
void reper4D::gpos_set(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][4]=p[0];
rep[1][4]=p[1];
rep[2][4]=p[2];
rep[3][4]=p[3];
orto();
}
//---------------------------------------------------------------------------
void reper4D::gpos_add(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][4]+=p[0];
rep[1][4]+=p[1];
rep[2][4]+=p[2];
rep[3][4]+=p[3];
orto();
}
//---------------------------------------------------------------------------
void reper4D::gpos_sub(vector<4> &p)
{
use_rep();
_rep=1; _inv=0;
rep[0][4]-=p[0];
rep[1][4]-=p[1];
rep[2][4]-=p[2];
rep[3][4]-=p[3];
orto();
}
//---------------------------------------------------------------------------
void reper4D::rot_rnd()
{
int i,j;
matrix<4> a;
a.rnd();
a.orthonormal();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::lrot_xy(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_rep();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=rep[i][j];
b[0].ld( c , s ,0.0,0.0);
b[1].ld(-s , c ,0.0,0.0);
b[2].ld(0.0,0.0,1.0,0.0);
b[3].ld(0.0,0.0,0.0,1.0);
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::lrot_yz(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_rep();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=rep[i][j];
b[0].ld(1.0,0.0,0.0,0.0);
b[1].ld(0.0, c , s ,0.0);
b[2].ld(0.0,-s , c ,0.0);
b[3].ld(0.0,0.0,0.0,1.0);
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::lrot_zx(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_rep();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=rep[i][j];
b[0].ld( c ,0.0,-s ,0.0);
b[1].ld(0.0,1.0,0.0,0.0);
b[2].ld( s ,0.0, c ,0.0);
b[3].ld(0.0,0.0,0.0,1.0);
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::lrot_xw(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_rep();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=rep[i][j];
b[0].ld( c ,0.0,0.0, s );
b[1].ld(0.0,1.0,0.0,0.0);
b[2].ld(0.0,0.0,1.0,0.0);
b[3].ld(-s ,0.0,0.0, c );
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::lrot_yw(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_rep();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=rep[i][j];
b[0].ld(1.0,0.0,0.0,0.0);
b[1].ld(0.0, c ,0.0,-s );
b[2].ld(0.0,0.0,1.0,0.0);
b[3].ld(0.0, s ,0.0, c );
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::lrot_zw(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_rep();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=rep[i][j];
b[0].ld(1.0,0.0,0.0,0.0);
b[1].ld(0.0,1.0,0.0,0.0);
b[2].ld(0.0,0.0, c ,-s );
b[3].ld(0.0,0.0, s , c );
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
rep[i][j]=a[i][j];
_rep=1; _inv=0; orto();
}
//---------------------------------------------------------------------------
void reper4D::grot_xy(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_inv();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=inv[i][j];
b[0].ld( c , s ,0.0,0.0);
b[1].ld(-s , c ,0.0,0.0);
b[2].ld(0.0,0.0,1.0,0.0);
b[3].ld(0.0,0.0,0.0,1.0);
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
inv[i][j]=a[i][j];
_rep=0; _inv=1; orto();
}
//---------------------------------------------------------------------------
void reper4D::grot_yz(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_inv();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=inv[i][j];
b[0].ld(1.0,0.0,0.0,0.0);
b[1].ld(0.0, c , s ,0.0);
b[2].ld(0.0,-s , c ,0.0);
b[3].ld(0.0,0.0,0.0,1.0);
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
inv[i][j]=a[i][j];
_rep=0; _inv=1; orto();
}
//---------------------------------------------------------------------------
void reper4D::grot_zx(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_inv();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=inv[i][j];
b[0].ld( c ,0.0,-s ,0.0);
b[1].ld(0.0,1.0,0.0,0.0);
b[2].ld( s ,0.0, c ,0.0);
b[3].ld(0.0,0.0,0.0,1.0);
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
inv[i][j]=a[i][j];
_rep=0; _inv=1; orto();
}
//---------------------------------------------------------------------------
void reper4D::grot_xw(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_inv();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=inv[i][j];
b[0].ld( c ,0.0,0.0, s );
b[1].ld(0.0,1.0,0.0,0.0);
b[2].ld(0.0,0.0,1.0,0.0);
b[3].ld(-s ,0.0,0.0, c );
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
inv[i][j]=a[i][j];
_rep=0; _inv=1; orto();
}
//---------------------------------------------------------------------------
void reper4D::grot_yw(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_inv();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=inv[i][j];
b[0].ld(1.0,0.0,0.0,0.0);
b[1].ld(0.0, c ,0.0,-s );
b[2].ld(0.0,0.0,1.0,0.0);
b[3].ld(0.0, s ,0.0, c );
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
inv[i][j]=a[i][j];
_rep=0; _inv=1; orto();
}
//---------------------------------------------------------------------------
void reper4D::grot_zw(double ang)
{
int i,j;
matrix<4> a,b;
double c=cos(ang),s=sin(ang);
use_inv();
for (i=0;i<4;i++)
for (j=0;j<4;j++)
a[i][j]=inv[i][j];
b[0].ld(1.0,0.0,0.0,0.0);
b[1].ld(0.0,1.0,0.0,0.0);
b[2].ld(0.0,0.0, c ,-s );
b[3].ld(0.0,0.0, s , c );
a*=b;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
inv[i][j]=a[i][j];
_rep=0; _inv=1; orto();
}
//---------------------------------------------------------------------------
void reper4D::rep2rep(reper4D r0,reper4D r1)
{
reset();
r0.use_inv();
r1.use_inv();
inv=r0.inv*r1.inv;
rep=inv.inverse();
_rep=1; _inv=1; orto(1);
}
//---------------------------------------------------------------------------
void reper4D::rep_rep(reper4D r0,reper4D r1)
{
reset();
r0.use_rep();
r1.use_inv();
inv=r0.rep*r1.inv;
rep=inv.inverse();
_rep=1; _inv=1; orto(1);
}
//---------------------------------------------------------------------------
void reper4D::repset(matrix<5> &m) { rep=m; _rep=1; _inv=0; }
void reper4D::invset(matrix<5> &m) { inv=m; _rep=0; _inv=1; }
void reper4D::repget(matrix<5> &m) { use_rep(); m=rep; }
void reper4D::invget(matrix<5> &m) { use_inv(); m=inv; }
//---------------------------------------------------------------------------
vector<4> reper4D::mul_mat_vec(matrix<5> &m,vector<4> &v)
{
vector<4> p;
p[0]=(m[0][0]*v[0])+(m[0][1]*v[1])+(m[0][2]*v[2])+(m[0][3]*v[3])+(m[0][4]);
p[1]=(m[1][0]*v[0])+(m[1][1]*v[1])+(m[1][2]*v[2])+(m[1][3]*v[3])+(m[1][4]);
p[2]=(m[2][0]*v[0])+(m[2][1]*v[1])+(m[2][2]*v[2])+(m[2][3]*v[3])+(m[2][4]);
p[3]=(m[3][0]*v[0])+(m[3][1]*v[1])+(m[3][2]*v[2])+(m[3][3]*v[3])+(m[3][4]);
return p;
}
//---------------------------------------------------------------------------
vector<4> reper4D::mul_mat_vec_dir(matrix<5> &m,vector<4> &v)
{
vector<4> p;
p[0]=(m[0][0]*v[0])+(m[0][1]*v[1])+(m[0][2]*v[2])+(m[0][3]*v[3]);
p[1]=(m[1][0]*v[0])+(m[1][1]*v[1])+(m[1][2]*v[2])+(m[1][3]*v[3]);
p[2]=(m[2][0]*v[0])+(m[2][1]*v[1])+(m[2][2]*v[2])+(m[2][3]*v[3]);
p[3]=(m[3][0]*v[0])+(m[3][1]*v[1])+(m[3][2]*v[2])+(m[3][3]*v[2]);
return p;
}
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
List<> template
Its just a linear array container template with self allocating properties specially developed for multithreading and fast list operations. I can not share its source code however because its part of corporate code ...
Instead Here a static template that mimics the API so you can recode it using any linear storage you got at your disposal like std::vector<>
or whatever or just use this with static allocation as is instead...
//---------------------------------------------------------------------------
//--- static list template class ver 3.00 ----------------------------------
//---------------------------------------------------------------------------
#ifndef _list_static_h
#define _list_static_h
/*---------------------------------------------------------------------------
Template class/struct must contain these operators/functions to work properly:
// all inline
T(){}; T(T& a){ *this=a; }; ~T(){}; T* operator = (const T *a) { *this=*a; return this; }; /*T* operator = (const T &a) { ...copy... return this; };*/
/*
// inline
T() {}
T(T& a) { *this=a; }
~T() {}
T* operator = (const T *a) { *this=*a; return this; }
//T* operator = (const T &a) { ...copy... return this; }
// header
T();
T(T& a);
~T();
T* operator = (const T *a);
//T* operator = (const T &a);
// body
T::T() {}
T::T(T& a) { *this=a; }
T::~T() {}
T* T::operator = (const T *a) { *this=*a; return this; }
//T* T::operator = (const T &a) { ..copy... return this; }
//-------------------------------------------------------------------------*/
template <class T,int N=16> class List_static
{
public: T dat[N]; // items array
int num,siz; // items count,allocated size
int minsiz; // minimal array size
int element_size; // initiate in constructor
bool enable_auto_shrink; // automatic shrink after delete operation ?
void (__closure *onrealloc)(); // realloc event
List_static(int _allocate=N);
~List_static() { free(); }
void operator = (const List_static<T> &a);
T& operator[] (int i);
void free();
int allocate(int _allocate);
int reallocate(int _allocate);
int shrink(); // down alloc if possible
int ins(int ix);
int ins(int ix,T &a);
int ins(int ix,const T &a);
int del(int ix);
int qdel(int ix);
int ins_block(int ix,int sz);
int del_block(int ix,int sz);
void shl(int d=1);
void shr(int d=1);
int add() { return ins(num); }
int add(T &a) { return ins(num,a); }
int add(const T &a) { return ins(num,a); }
int add(List_static<T> &a);
void reset();
int save_size();
void save(int hnd);
void load(int hnd);
};
//---------------------------------------------------------------------------
template <class T,int N> List_static<T>::List_static(int _allocate)
{
onrealloc=NULL;
element_size=sizeof(T);
enable_auto_shrink=false;
num=0;
siz=N;
minsiz=siz;
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::operator = (const List_static<T> &a)
{
int i;
reset();
element_size =a.element_size;
enable_auto_shrink =a.enable_auto_shrink;
minsiz =a.minsiz;
for (i=0;i<a.num;i++) add(a.dat[i]);
}
//---------------------------------------------------------------------------
template <class T,int N> T& List_static<T>::operator[] (int i)
{
static T empty;
if (i< 0) return empty;
if (i>=num) return empty;
return dat[i];
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::free()
{
num=0;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::allocate(int _allocate)
{
if (_allocate<=siz) return 1; else return 0;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::reallocate(int _allocate)
{
if (_allocate<=siz) return 1;
else return 0;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::shrink()
{
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix)
{
int i;
if (num<0) num=0;
if (ix<0) return 0;
if (ix>num) return 0;
if (num>=siz) return 0;
if (ix<num)
for (i=num;i>ix;i--)
dat[i]=dat[i-1];
// dat[ix]=;
num++;
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix,T &a)
{
int i;
if (num<0) num=0;
if (ix<0) return 0;
if (ix>num) return 0;
if (num>=siz) return 0;
if (ix<num)
for (i=num;i>ix;i--)
dat[i]=dat[i-1];
dat[ix]=a;
num++;
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins(int ix,const T &a)
{
int i;
if (num<0) num=0;
if (ix<0) return 0;
if (ix>num) return 0;
if (num>=siz) return 0;
if (ix<num)
for (i=num;i>ix;i--)
dat[i]=dat[i-1];
dat[ix]=a;
num++;
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::del(int ix)
{
int i;
if (num<=0) { num=0; return 0; }
if (ix<0) return 0;
if (ix>=num) return 0;
num--;
for (i=ix;i<num;i++)
dat[i]=dat[i+1];
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::qdel(int ix)
{
int i;
if (num<=0) { num=0; return 0; }
if (ix<0) return 0;
if (ix>=num) return 0;
if (ix<num-1)
dat[ix]=dat[num-1];
num--;
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::ins_block(int ix,int sz)
{
int i;
if (num<0) num=0;
if (sz<=0) return 0;
if (ix<0) return 0;
if (ix>num) return 0;
if (num+sz>=siz) return 0;
if (ix<num)
for (i=num;i>ix;i--)
dat[i+sz-1]=dat[i-1];
num+=sz;
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::del_block(int ix,int sz)
{
int i;
if (num<=0) { num=0; return 0; }
if (sz<=0) return 0;
if (ix<0) return 0;
if (ix+sz>num) return 0;
num-=sz;
for (i=ix;i<num;i++)
dat[i]=dat[i+sz];
return 1;
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::shl(int d)
{
int i;
if (num<0) num=0;
if (num<=d) return;
if (siz<=d) return;
for (i=0;i<num-d;i++)
dat[i]=dat[i+d];
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::shr(int d)
{
int i;
if (num<0) num=0;
if (num<=d) return;
if (siz<=d) return;
for (i=num-d-1;i>=0;i--)
dat[i+d]=dat[i];
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>::reset()
{
num=0;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>::add(List_static<T> &a)
{
int i,n,q;
q=num;
n=a.num;
for (i=0;i<n;i++) add(a.dat[i]);
if (num==n+q) return 1;
return 0;
}
//---------------------------------------------------------------------------
template <class T,int N> int List_static<T>:: save_size()
{
return 4+(num*element_size);
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>:: save(int hnd)
{
if (hnd<0) return;
FileWrite(hnd,&num,4);
FileWrite(hnd,dat,num*element_size);
}
//---------------------------------------------------------------------------
template <class T,int N> void List_static<T>:: load(int hnd)
{
int i,n;
if (hnd<0) return;
FileRead(hnd,&n,4); if (n<0) n=0;
allocate(n); num=n; if (num>siz) num=siz; if (num<0) num=0;
FileRead(hnd,dat,num*element_size);
n=n-num;
if (n>0) FileSeek(hnd,n*element_size,1);
}
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
Not all stuff from that is used so either ignore what you do not need or port the VCL related stuff (file access) to your environment.
来源:https://stackoverflow.com/questions/62460757/how-do-i-render-a-4d-object-in-opengl-utilizing-homogenous-transforms