%module PTM %include "workaround.i" %{ #include "Base/TQuaternion.h" #include "Base/Affine.h" using namespace PTM; using namespace Spr; %} // const T* を渡すコンストラクタのためのtypemap %define INPUT_ARRAY_TYPEMAP(type, argname, ndim) %typemap(typecheck) type const * argname %{ Check_Type($input, T_ARRAY); $1 = RARRAY($input)->len == ndim; %} %typemap(in) type const * argname(type temp[ndim]) %{ for(int i = 0; i < ndim; i++) temp[i] = (type)(RARRAY($input)->ptr[i]); $1 = temp; %} %enddef INPUT_ARRAY_TYPEMAP(float, _2f, 2) //Vec2f INPUT_ARRAY_TYPEMAP(float, _3f, 3) //Vec3f INPUT_ARRAY_TYPEMAP(float, _4f, 4) //Vec4f INPUT_ARRAY_TYPEMAP(double, _2d, 2) //Vec2d INPUT_ARRAY_TYPEMAP(double, _3d, 3) //Vec3d INPUT_ARRAY_TYPEMAP(double, _4d, 4) //Vec4d, Quaterniond INPUT_ARRAY_TYPEMAP(double, _7d, 7) //Posed %define VEC_MEMBER(type) void clear(); double norm(); double square(); void resize(size_t sz); size_t size(); type unit(); void unitize(); %enddef %define VEC_CONSTRUCTOR(vec, elem, argname) vec(); vec(const vec&); vec(const elem* argname); %enddef %define VEC_EXTEND(vec, elem) elem __getitem__(size_t index){ return $self->operator[](index); } void __setitem__(size_t index, elem val){ $self->operator[](index) = val; } vec __add__(vec v){ return *$self + v; } vec __sub__(vec v){ return *$self - v; } vec __mul__(elem k){ return *$self * k; } elem __mul__(vec v){ return *$self * v; } %enddef %define MAT_MEMBER(mat, vec) void clear(); vec col(size_t i); vec row(size_t i); double det(); size_t height(); size_t width(); void resize(size_t nrow, size_t ncol); mat trans(); mat inv(); %enddef %define MAT_CONSTRUCTOR(mat) mat(); mat(const mat&); %enddef %define MAT_EXTEND(mat, vec, elem) elem __getitem__(size_t r, size_t c){ return (*$self)[r][c]; } void __setitem__(size_t r, size_t c, elem val){ (*$self)[r][c] = val; } mat __add__(mat m){ return *$self + m; } mat __sub__(mat m){ return *$self - m; } mat __mul__(mat m){ return *$self * m; } vec __mul__(vec v){ return *$self * v; } mat __mul__(elem k){ return *$self * k; } %enddef double Deg(double rad); double Rad(double deg); class Vec2f{ public: float x, y; VEC_MEMBER(Vec2f) static Vec2f Zero(); VEC_CONSTRUCTOR(Vec2f, float, _2f) Vec2f(float xi, float yi); }; %extend Vec2f{ VEC_EXTEND(Vec2f, float) } class Vec2d{ public: double x, y; VEC_MEMBER(Vec2d) static Vec2d Zero(); VEC_CONSTRUCTOR(Vec2d, double, _2d) Vec2d(double xi, double yi); }; %extend Vec2d{ VEC_EXTEND(Vec2d, double) } class Vec3f{ public: float x, y, z; VEC_MEMBER(Vec3f) static Vec3f Zero(); VEC_CONSTRUCTOR(Vec3f, float, _3f) Vec3f(float xi, float yi, float zi); }; %extend Vec3f{ VEC_EXTEND(Vec3f, float) } class Vec3d{ public: double x, y, z; VEC_MEMBER(Vec3d) static Vec3d Zero(); VEC_CONSTRUCTOR(Vec3d, double, _3d) Vec3d(double xi, double yi, double zi); }; %extend Vec3d{ VEC_EXTEND(Vec3d, double) } class Vec4f{ public: float x, y, z, w; VEC_MEMBER(Vec4f) static Vec4f Zero(); VEC_CONSTRUCTOR(Vec4f, float, _4f) Vec4f(float xi, float yi, float zi, float wi); }; %extend Vec4f{ VEC_EXTEND(Vec4f, float) } class Vec4d{ public: double x, y, z, w; VEC_MEMBER(Vec4d) static Vec4d Zero(); VEC_CONSTRUCTOR(Vec4d, double, _4d) Vec4d(double xi, double yi, double zi, double wi); }; %extend Vec4d{ VEC_EXTEND(Vec4d, double) } class Matrix2f{ public: float xx, xy, yx, yy; MAT_MEMBER(Matrix2f, Vec2f) Matrix2f(); Matrix2f(const Vec2f& exi, const Vec2f& eyi); Matrix2f(float m11, float m12, float m21, float m22); static Matrix2f Zero(); static Matrix2f Unit(); static Matrix2f Diag(float x, float y); static Matrix2f Rot(float rad); static Matrix2f Rot(const Vec2f& a, char axis); float angle() const; }; %extend Matrix2f{ MAT_EXTEND(Matrix2f, Vec2f, float) } class Matrix2d{ public: double xx, xy, yx, yy; MAT_MEMBER(Matrix2d, Vec2d) Matrix2d(); Matrix2d(const Vec2d& exi, const Vec2d& eyi); Matrix2d(double m11, double m12, double m21, double m22); static Matrix2d Zero(); static Matrix2d Unit(); static Matrix2d Diag(double x, double y); static Matrix2d Rot(double rad); static Matrix2d Rot(const Vec2d& a, char axis); double angle() const; }; %extend Matrix2d{ MAT_EXTEND(Matrix2d, Vec2d, double) } class Matrix3f{ public: float xx, xy, xz; float yx, yy, yz; float zx, zy, zz; MAT_MEMBER(Matrix3f, Vec3f) Matrix3f(); Matrix3f(const Vec3f& exi, const Vec3f& eyi, const Vec3f& ezi); Matrix3f(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33); static Matrix3f Zero(); static Matrix3f Unit(); static Matrix3f Diag(float x, float y, float z); static Matrix3f Rot(const Vec3f& a, const Vec3f& b, char axis = 'x'); static Matrix3f Rot(float th, char axis); static Matrix3f Rot(float th, const Vec3f& axis); static Matrix3f Rot(const Vec4f& q); static Matrix3f Cross(const Vec3f& v); }; %extend Matrix3f{ MAT_EXTEND(Matrix3f, Vec3f, float) } bool IsUnitary(Matrix3f r); class Matrix3d{ public: double xx, xy, xz; double yx, yy, yz; double zx, zy, zz; MAT_MEMBER(Matrix3d, Vec3d) Matrix3d(); Matrix3d(const Vec3d& exi, const Vec3d& eyi, const Vec3d& ezi); Matrix3d(double m11, double m12, double m13, double m21, double m22, double m23, double m31, double m32, double m33); static Matrix3d Zero(); static Matrix3d Unit(); static Matrix3d Diag(double x, double y, double z); static Matrix3d Rot(const Vec3d& a, const Vec3d& b, char axis = 'x'); static Matrix3d Rot(double th, char axis); static Matrix3d Rot(double th, const Vec3d& axis); static Matrix3d Rot(const Vec4d& q); static Matrix3d Cross(const Vec3d& v); }; %extend Matrix3d{ MAT_EXTEND(Matrix3d, Vec3d, double) } bool IsUnitary(Matrix3d r); // TAffineだけはグラフィクス系との親和性を考慮してfloat, double両方の具現化をポートする %rename("trn") Affine2f::getTrn; %rename("trn=") Affine2f::setTrn; %rename("pos") Affine2f::getPos; %rename("pos=") Affine2f::setPos; %rename("rot") Affine2f::getRot; %rename("rot=") Affine2f::setRot; %extend Affine2f{ MAT_EXTEND(Affine2f, Vec2f, float) void setTrn(const Vec2f& v){ $self->Trn() = v; } Vec2f getTrn(){ return $self->Trn(); } void setPos(const Vec2f& v){ $self->Pos() = v; } Vec2f getPos(){ return $self->Pos(); } void setRot(const Matrix2f& m){ $self->Rot() = m; } Matrix2f getRot(){ return $self->Rot(); } } class Affine2f{ public: float xx, xy, xz; float yx, yy, yz; float px, py, pz; MAT_MEMBER(Affine2f, Vec3d) static Affine2f Unit(); static Affine2f Trn(float px, float py); static Affine2f Rot(float th); static Affine2f Scale(float sx, float sy); Affine2f(); }; %rename("trn") Affinef::getTrn; %rename("trn=") Affinef::setTrn; %rename("pos") Affinef::getPos; %rename("pos=") Affinef::setPos; %rename("rot") Affinef::getRot; %rename("rot=") Affinef::setRot; %extend Affinef{ MAT_EXTEND(Affinef, Vec3f, float) void setTrn(const Vec3f& v){ $self->Trn() = v; } Vec3f getTrn(){ return $self->Trn(); } void setPos(const Vec3f& v){ $self->Pos() = v; } Vec3f getPos(){ return $self->Pos(); } void setRot(const Matrix3f& m){ $self->Rot() = m; } Matrix3f getRot(){ return $self->Rot(); } } class Affinef{ public: float xx, xy, xz, xw; float yx, yy, yz, yw; float zx, zy, zz, zw; float px, py, pz, pw; MAT_MEMBER(Affinef, Vec4f) static Affinef Unit(); static Affinef Trn(float px, float py, float pz); static Affinef Rot(float th, char axis); static Affinef Rot(float th, const Vec3d& axis); static Affinef Scale(float sx, float sy, float sz); static Affinef ProjectionGL( const Vec3f& screen, const Vec2f& size, float front=1.0f, float back=10000.0f); static Affinef ProjectionD3D( const Vec3f& screen, const Vec2f& size, float front=1.0f, float back=10000.0f); void LookAt(const Vec3f& posi); void LookAt(const Vec3f& posz, const Vec3f& posy); void LookAtGL(const Vec3f& posi); void LookAtGL(const Vec3f& posz, const Vec3f& posy); Affinef(); }; %rename("trn") Affine2d::getTrn; %rename("trn=") Affine2d::setTrn; %rename("pos") Affine2d::getPos; %rename("pos=") Affine2d::setPos; %rename("rot") Affine2d::getRot; %rename("rot=") Affine2d::setRot; %extend Affine2d{ MAT_EXTEND(Affine2d, Vec2d, double) void setTrn(const Vec2d& v){ $self->Trn() = v; } Vec2d getTrn(){ return $self->Trn(); } void setPos(const Vec2d& v){ $self->Pos() = v; } Vec2d getPos(){ return $self->Pos(); } void setRot(const Matrix2d& m){ $self->Rot() = m; } Matrix2d getRot(){ return $self->Rot(); } } class Affine2d{ public: double xx, xy, xz; double yx, yy, yz; double px, py, pz; MAT_MEMBER(Affine2d, Vec3d) static Affine2d Unit(); static Affine2d Trn(double px, double py); static Affine2d Rot(double th); static Affine2d Scale(double sx, double sy); Affine2d(); }; %rename("trn") Affined::getTrn; %rename("trn=") Affined::setTrn; %rename("pos") Affined::getPos; %rename("pos=") Affined::setPos; %rename("rot") Affined::getRot; %rename("rot=") Affined::setRot; %extend Affined{ MAT_EXTEND(Affined, Vec3d, double) void setTrn(const Vec3d& v){ $self->Trn() = v; } Vec3d getTrn(){ return $self->Trn(); } void setPos(const Vec3d& v){ $self->Pos() = v; } Vec3d getPos(){ return $self->Pos(); } void setRot(const Matrix3d& m){ $self->Rot() = m; } Matrix3d getRot(){ return $self->Rot(); } } class Affined{ public: double xx, xy, xz, xw; double yx, yy, yz, yw; double zx, zy, zz, zw; double px, py, pz, pw; MAT_MEMBER(Affined, Vec4d) static Affined Unit(); static Affined Trn(double px, double py, double pz); static Affined Rot(double th, char axis); static Affined Rot(double th, const Vec3d& axis); static Affined Scale(double sx, double sy, double sz); static Affined ProjectionGL( const Vec3d& screen, const Vec2d& size, double front=1.0f, double back=10000.0f); static Affined ProjectionD3D( const Vec3d& screen, const Vec2d& size, double front=1.0f, double back=10000.0f); void LookAt(const Vec3d& posi); void LookAt(const Vec3d& posz, const Vec3d& posy); void LookAtGL(const Vec3d& posi); void LookAtGL(const Vec3d& posz, const Vec3d& posy); Affined(); }; %rename("v") Quaterniond::getV; %rename("v=") Quaterniond::setV; %extend Quaterniond{ double __getitem__(size_t index){ return $self->operator[](index); } void __setitem__(size_t index, double val){ $self->operator[](index) = val; } Quaterniond __add__(Quaterniond q){ return *$self + q; } Quaterniond __sub__(Quaterniond q){ return *$self - q; } Quaterniond __mul__(Quaterniond q){ return *$self * q; } Vec3d transform(Vec3d v){ return *$self * v; } void setV(const Vec3d& v){ $self->V() = v; } Vec3d getV(){ return $self->V(); } } class Quaterniond{ public: double w,x,y,z; VEC_MEMBER(Quaterniond) Vec3d RotationHalf(); Vec3d Rotation(); Vec3d Axis(); double Theta(); VEC_CONSTRUCTOR(Quaterniond, double, _4d) Quaterniond(double wi, double xi, double yi, double zi); static Quaterniond Rot(double angle, const Vec3d& axis); static Quaterniond Rot(double angle, char axis); static Quaterniond Rot(const Vec3d& rot); void Conjugate(); Quaterniond Conjugated() const; Quaterniond Inv() const; void FromMatrix(const Matrix3d& m); void ToMatrix(Matrix3d& mat) const; void ToEular(Vec3d& v); void FromEular(const Vec3d& v); void RotationArc(const Vec3d& lhs, const Vec3d& rhs); void Euler(double yaw, double pitch, double roll); Quaterniond Derivative(const Vec3d& w); Vec3d AngularVelocity(const Quaterniond& qd); }; double dot(const Quaterniond& q1, const Quaterniond& q2); Quaterniond interpolate(double t, const Quaterniond& q1, const Quaterniond& q2); %rename("pos") Posed::getPos; %rename("pos=") Posed::setPos; %rename("ori") Posed::getOri; %rename("ori=") Posed::setOri; %extend Posed{ Vec3d transform(Vec3d v){ return *$self * v; } Posed __mul__(Posed p){ return *$self * p; } void setPos(const Vec3d& v){ $self->Pos() = v; } Vec3d getPos(){ return $self->Pos(); } void setOri(const Quaterniond& q){ $self->Ori() = q; } Quaterniond getOri(){ return $self->Ori(); } } class Posed{ public: double w,x,y,z; double px, py, pz; VEC_MEMBER(Posed) Posed Inv() const; static Posed Unit(); static Posed Unit(const Vec3d& v); static Posed Unit(const Quaterniond &q); static Posed Trn(double px, double py, double pz); static Posed Trn(const Vec3d &v); static Posed Rot(double wi, double xi, double yi, double zi); static Posed Rot(double angle, const Vec3d& axis); static Posed Rot(double angle, char axis); static Posed Rot(const Vec3d& rot); void FromAffine(const Affined& f); void ToAffine(Affined& af) const; VEC_CONSTRUCTOR(Posed, double, _7d) };