/* 3DMath.h - the 3D math family of classes - vectors, rays, quat, matrices for MAXScript * * Copyright (c) John Wainwright, 1996 * * */ #ifndef _H_3DMATH #define _H_3DMATH #include "Max.h" extern ScripterExport void _QuatToEuler(Quat &q, float *ang); extern ScripterExport void _EulerToQuat(float *ang, Quat &q); /* ------------------------ Point3Value ------------------------------ */ applyable_class (Point3Value) class Point3Value : public Value { public: Point3 p; ENABLE_STACK_ALLOCATE(Point3Value); ScripterExport Point3Value(Point3 init_point); ScripterExport Point3Value(float x, float y, float z); ScripterExport Point3Value(Value* x, Value* y, Value* z); classof_methods(Point3Value, Value); void collect() { delete this; } ScripterExport void sprin1(CharStream* s); # define is_point3(p) ((p)->tag == class_tag(Point3Value)) static Value* make(Value**arg_list, int count); /* operations */ #include "defimpfn.h" # include "vectpro.h" use_generic ( coerce, "coerce"); use_generic ( copy, "copy"); use_generic ( get, "get"); use_generic ( put, "put"); /* built-in property accessors */ def_property ( x ); def_property ( y ); def_property ( z ); Point3 to_point3() { return p; } AColor to_acolor() { return AColor (p.x / 255.0f, p.y / 255.0f, p.z / 255.0f); } Point2 to_point2() { return Point2 (p.x, p.y); } void to_fpvalue(FPValue& v) { v.p = new Point3 (p); v.type = (ParamType2)TYPE_POINT3; } COLORREF to_colorref() { return RGB((int)p.x, (int)p.y, (int)p.z); } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; class ConstPoint3Value : public Point3Value { public: ScripterExport ConstPoint3Value(float x, float y, float z) : Point3Value (x, y, z) { } void collect() { delete this; } BOOL is_const() { return TRUE; } Value* set_x(Value** arg_list, int count) { throw RuntimeError (_T("Constant vector, not settable")); return NULL; } // Win64 Cleanup: Shuler Value* set_y(Value** arg_list, int count) { throw RuntimeError (_T("Constant vector, not settable")); return NULL; } // Win64 Cleanup: Shuler Value* set_z(Value** arg_list, int count) { throw RuntimeError (_T("Constant vector, not settable")); return NULL; } // Win64 Cleanup: Shuler }; // The following function has been added // in 3ds max 4.2. If your plugin utilizes this new // mechanism, be sure that your clients are aware that they // must run your plugin with 3ds max version 4.2 or higher. inline IPoint3 to_ipoint3(Value* val) { Point3 p = val->to_point3(); return IPoint3((int)p.x, (int)p.y, (int)p.z); } // End of 3ds max 4.2 Extension /* ------------------------ RayValue ------------------------------ */ applyable_class (RayValue) class RayValue : public Value { public: Ray r; ENABLE_STACK_ALLOCATE(RayValue); ScripterExport RayValue(Point3 init_origin, Point3 init_dir); ScripterExport RayValue(Ray init_ray); classof_methods (RayValue, Value); void collect() { delete this; } ScripterExport void sprin1(CharStream* s); /* operations */ use_generic ( copy, "copy"); /* built-in property accessors */ def_property ( pos ); def_property_alias ( position, pos ); def_property ( dir ); Ray to_ray() { return r; } void to_fpvalue(FPValue& v) { v.ray = new Ray (r); v.type = TYPE_RAY; } # define is_ray(r) ((r)->tag == class_tag(RayValue)) // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; /* ------------------------ QuatValue ------------------------------ */ applyable_class (QuatValue) class QuatValue : public Value { public: Quat q; ENABLE_STACK_ALLOCATE(QuatValue); ScripterExport QuatValue(const Quat& init_quat); ScripterExport QuatValue(float w, float x, float y, float z); ScripterExport QuatValue(Value* w, Value* x, Value* y, Value* z); ScripterExport QuatValue(Value* val); ScripterExport QuatValue(AngAxis& aa); ScripterExport QuatValue(float* angles); ScripterExport QuatValue(Matrix3& m); classof_methods (QuatValue, Value); # define is_quat(o) ((o)->tag == class_tag(QuatValue)) void collect() { delete this; } ScripterExport void sprin1(CharStream* s); /* operations */ #include "defimpfn.h" # include "quatpro.h" use_generic ( copy, "copy"); /* built-in property accessors */ def_property ( w ); def_property ( x ); def_property ( y ); def_property ( z ); def_property ( angle ); def_property ( axis ); Quat to_quat() { return q; } AngAxis to_angaxis() { return AngAxis(q); } void to_fpvalue(FPValue& v) { v.q = new Quat (q); v.type = TYPE_QUAT; } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; /* ------------------------ AngleAxis ------------------------------ */ applyable_class (AngAxisValue) class AngAxisValue : public Value { public: AngAxis aa; ENABLE_STACK_ALLOCATE(AngAxisValue); ScripterExport AngAxisValue(const AngAxis& iaa); ScripterExport AngAxisValue(const Quat& q); ScripterExport AngAxisValue(const Matrix3& m); ScripterExport AngAxisValue(float* angles); ScripterExport AngAxisValue(float angle, Point3 axis); ScripterExport AngAxisValue(Value*); ScripterExport AngAxisValue(Value* angle, Value* axis); classof_methods (AngAxisValue, Value); # define is_angaxis(o) ((o)->tag == class_tag(AngAxisValue)) void collect() { delete this; } ScripterExport void sprin1(CharStream* s); /* operations */ #include "defimpfn.h" use_generic( coerce, "coerce" ); use_generic( eq, "="); use_generic( ne, "!="); use_generic( random, "random"); use_generic( copy, "copy"); /* built-in property accessors */ def_property ( angle ); def_property ( axis ); def_property ( numrevs ); AngAxis to_angaxis() { return aa; } Quat to_quat() { return Quat (aa); } void to_fpvalue(FPValue& v) { v.aa = new AngAxis (aa); v.type = TYPE_ANGAXIS; } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; /* ------------------------ EulerAngles ------------------------------ */ applyable_class (EulerAnglesValue) class EulerAnglesValue : public Value { public: float angles[3]; ENABLE_STACK_ALLOCATE(EulerAnglesValue); ScripterExport EulerAnglesValue(float ax, float ay, float az); ScripterExport EulerAnglesValue(const Quat&); ScripterExport EulerAnglesValue(const Matrix3&); ScripterExport EulerAnglesValue(const AngAxis&); classof_methods (EulerAnglesValue, Value); # define is_eulerangles(o) ((o)->tag == class_tag(EulerAnglesValue)) void collect() { delete this; } ScripterExport void sprin1(CharStream* s); /* operations */ #include "defimpfn.h" use_generic( coerce, "coerce" ); use_generic( eq, "="); use_generic( ne, "!="); use_generic( random, "random"); use_generic( copy, "copy"); /* built-in property accessors */ def_property ( x ); def_property ( y ); def_property ( z ); def_property ( x_rotation ); def_property ( y_rotation ); def_property ( z_rotation ); AngAxis to_angaxis() { return AngAxis (to_quat()); } Quat to_quat() { Quat q; _EulerToQuat(angles, q); return Quat (q); } void to_fpvalue(FPValue& v) { Quat q; _EulerToQuat(angles, q); v.q = new Quat (q); v.type = TYPE_QUAT; } float* to_eulerangles() { return angles; } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; /* ------------------------ Matrix ------------------------------ */ applyable_class (Matrix3Value) class Matrix3Value : public Value { public: Matrix3 m; ENABLE_STACK_ALLOCATE(Matrix3Value); ScripterExport Matrix3Value(int i); ScripterExport Matrix3Value(const Matrix3& im); ScripterExport Matrix3Value(const Quat& q); ScripterExport Matrix3Value(const AngAxis& aa); ScripterExport Matrix3Value(float* angles); ScripterExport Matrix3Value(const Point3& row0, const Point3& row1, const Point3& row2, const Point3& row3); classof_methods (Matrix3Value, Value); void collect() { delete this; } ScripterExport void sprin1(CharStream* s); # define is_matrix3(p) ((p)->tag == class_tag(Matrix3Value)) /* operations */ #include "defimpfn.h" # include "matpro.h" use_generic( copy, "copy"); /* built-in property accessors */ def_property ( row1 ); def_property ( row2 ); def_property ( row3 ); def_property ( row4 ); def_property ( translation ); def_property ( pos ); def_property ( rotation ); def_property ( scale ); use_generic( get, "get"); use_generic( put, "put"); Value* get_property(Value** arg_list, int count); Value* set_property(Value** arg_list, int count); Matrix3& to_matrix3() { return m; } Quat to_quat() { return Quat (m); } void to_fpvalue(FPValue& v) { v.m = new Matrix3; *v.m = m; v.type = TYPE_MATRIX3; } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; /* ------------------------ Point2Value ------------------------------ */ applyable_class (Point2Value) class Point2Value : public Value { public: Point2 p; ENABLE_STACK_ALLOCATE(Point2Value); ScripterExport Point2Value(Point2 ipoint); ScripterExport Point2Value(POINT ipoint); ScripterExport Point2Value(float x, float y); ScripterExport Point2Value(Value* x, Value* y); classof_methods(Point2Value, Value); void collect() { delete this; } ScripterExport void sprin1(CharStream* s); # define is_point2(p) ((p)->tag == class_tag(Point2Value)) static Value* make(Value**arg_list, int count); /* operations */ #include "defimpfn.h" use_generic( plus, "+" ); use_generic( minus, "-" ); use_generic( times, "*" ); use_generic( div, "/" ); use_generic( uminus, "u-"); use_generic( eq, "="); use_generic( ne, "!="); use_generic( random, "random"); use_generic( length, "length"); use_generic( distance, "distance"); use_generic( normalize, "normalize"); use_generic( copy, "copy"); use_generic( get, "get"); use_generic( put, "put"); /* built-in property accessors */ def_property ( x ); def_property ( y ); Point2 to_point2() { return p; } void to_fpvalue(FPValue& v) { v.p2 = new Point2(p); v.type = TYPE_POINT2; } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; // The following function has been added // in 3ds max 4.2. If your plugin utilizes this new // mechanism, be sure that your clients are aware that they // must run your plugin with 3ds max version 4.2 or higher. inline IPoint2 to_ipoint2(Value* val) { Point2 p = val->to_point2(); return IPoint2((int)p.x, (int)p.y); } // End of 3ds max 4.2 Extension /* ------------------------ Point4Value ------------------------------ */ applyable_class (Point4Value) class Point4Value : public Value { public: Point4 p; ENABLE_STACK_ALLOCATE(Point4Value); ScripterExport Point4Value(Point4 init_point); ScripterExport Point4Value(float x, float y, float z, float w); ScripterExport Point4Value(Value* x, Value* y, Value* z, Value* w); classof_methods(Point4Value, Value); void collect() { delete this; } ScripterExport void sprin1(CharStream* s); # define is_point4(p) ((p)->tag == class_tag(Point4Value)) static Value* make(Value**arg_list, int count); /* operations */ #include "defimpfn.h" # include "vectpro.h" use_generic ( coerce, "coerce"); use_generic ( copy, "copy"); use_generic ( get, "get"); use_generic ( put, "put"); /* built-in property accessors */ def_property ( x ); def_property ( y ); def_property ( z ); def_property ( w ); Point4 to_point4() { return p; } Point3 to_point3() { return Point3 (p.x, p.y, p.z); } AColor to_acolor() { return AColor (p.x, p.y, p.z, p.w); } Point2 to_point2() { return Point2 (p.x, p.y); } void to_fpvalue(FPValue& v) { v.p4 = new Point4 (p); v.type = (ParamType2)TYPE_POINT4; } COLORREF to_colorref() { return RGB((int)(p.x*255.f), (int)(p.y*255.f), (int)(p.z*255.f)); } // scene I/O IOResult Save(ISave* isave); static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload); }; // The following class has been added // in 3ds max 4.2. If your plugin utilizes this new // mechanism, be sure that your clients are aware that they // must run your plugin with 3ds max version 4.2 or higher. // Wraps Box2 in SDK which is a sub-class of the RECT structure in windows applyable_class (Box2Value) class Box2Value : public Value { public: Box2 b; ScripterExport Box2Value(); ScripterExport Box2Value(Box2 box); ScripterExport Box2Value(RECT rect); ScripterExport Box2Value(IPoint2 ul, IPoint2 lr); ScripterExport Box2Value(int x, int y, int w, int h); ScripterExport Box2Value(Value* x, Value* y, Value* w, Value* h); classof_methods(Box2Value, Value); void collect() { delete this; } ScripterExport void sprin1(CharStream* s); # define is_box2(p) ((p)->tag == class_tag(Box2Value)) static Value* make(Value**arg_list, int count); /* operations */ #include "defimpfn.h" # include "boxpro.h" /* built-in property accessors */ def_property ( x ); def_property ( y ); def_property ( w ); def_property ( h ); def_property ( left ); def_property ( top ); def_property ( right ); def_property ( bottom ); def_property ( center ); Box2& to_box2() { return b; } }; // End of 3ds max 4.2 Extension #endif