/**************************************************************************
 *{@C
 *      Copyright:      1988-2023 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         Utilities
 *      Filename:       UT_Vector.h
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    Declaration of the functions in the vector and
 *                      matrix math library.
 *
 *      Additional documentation:
 *                      None.
 *
 **************************************************************************/

#ifndef __UT_VECTOR_H__
#define __UT_VECTOR_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "UT_Compat.h"

/* The precision (delta) used when calculating line-triangle intersections
   with function UT_VecIsectLineTria3D.
*/

#define UT_LineTriaPrec 1.0E-4

typedef enum {
    UT_VecCompX = 0,
    UT_VecCompY = 1,
    UT_VecCompZ = 2
} UT_VecComp;

/* Point or vector in two dimensional space */

typedef Float32         UT_Vec2D[2];
typedef Float64         UT_DVec2D[2];


/* Point or vector in three dimensional space */

typedef Float32         UT_Vec3D[3];
typedef Float64         UT_DVec3D[3];


/* Transformation in two dimensions */

typedef Float32         UT_Tfm2D[3][2];
typedef Float64         UT_DTfm2D[3][2];


/* Transformation in three dimensions */

typedef Float32         UT_Tfm3D[4][3];
typedef Float64         UT_DTfm3D[4][3];


/* Two dimensional coordinate system. Note that ori must be a set of
   orthogonal unit vectors! */

typedef struct {
    UT_Vec2D off,       /* Offset from Origin */
          ori[2];       /* Orientation */
} UT_CoSys2D;


/* Three dimensional coordinate system. Note that ori must be a set of
   orthogonal unit vectors! */

typedef struct {
    UT_Vec3D off,       /* Offset from Origin */
          ori[3];       /* Orientation */
} UT_CoSys3D;

/* Two dimensional bounding box, i.e. a rectangle. */

typedef struct {
    UT_Vec2D min;       /* Minimum (lower-left)  corner of box. */
    UT_Vec2D max;       /* Maximum (upper-right) corner of box. */
} UT_Box2D;

typedef struct {
    UT_DVec2D min;      /* Minimum (lower-left)  corner of box. */
    UT_DVec2D max;      /* Maximum (upper-right) corner of box. */
} UT_DBox2D;

/* Three dimensional bounding box. */

typedef struct {
    UT_Vec3D min;       /* Minimum (lower-left)  corner of box. */
    UT_Vec3D max;       /* Maximum (upper-right) corner of box. */
} UT_Box3D;

typedef struct {
    UT_DVec3D min;      /* Minimum (lower-left)  corner of box. */
    UT_DVec3D max;      /* Maximum (upper-right) corner of box. */
} UT_DBox3D;

/* An equation describing a plane in three-dimensional space. */

typedef struct {
    UT_Vec3D nrm;       /* Normal vector */
    Float32  dist;      /* Distance from the coordinate origin */
} UT_Plane3D;

typedef struct {
    UT_DVec3D nrm;      /* Normal vector */
    Float64   dist;     /* Distance from the coordinate origin */
} UT_DPlane3D;

/* Macros for debugging: Print vectors and transformations */

#define UT_VecPrint2D(name,vec) \
    {printf ("UT_Vec2D %s: %f %f\n", name, (vec)[0], (vec)[1]);}

#define UT_VecPrint3D(name,vec) \
    {printf ("UT_Vec3D %s: %f %f %f\n", name, (vec)[0], (vec)[1], (vec)[2]);}

#define UT_DVecPrint2D(name,vec) \
    {printf ("UT_DVec2D %s: %f %f\n", name, (vec)[0], (vec)[1]);}

#define UT_DVecPrint3D(name,vec) \
    {printf ("UT_DVec3D %s: %f %f %f\n", name, (vec)[0], (vec)[1], (vec)[2]);}

#define UT_TfmPrint2D(name,trans)               \
    {                                           \
        Int32 i, j;                             \
        printf ("UT_Tfm2D %s:\n", name);        \
        for (i = 0; i < 3; ++i)                 \
        {                                       \
            printf ("\t");                      \
            for (j = 0; j < 2; ++j)             \
                printf ("%f ", (trans)[i][j]);  \
            printf ("\n");                      \
        }                                       \
    }

#define UT_TfmPrint3D(name,trans)               \
    {                                           \
        Int32 i, j;                             \
        printf ("UT_Tfm3D %s:\n", name);        \
        for (i = 0; i < 4; ++i)                 \
        {                                       \
            printf ("\t");                      \
            for (j = 0; j < 3; ++j)             \
                printf ("%f ", (trans)[i][j]);  \
            printf ("\n");                      \
        }                                       \
    }

#define UT_DTfmPrint3D(name,trans)              \
    {                                           \
        Int32 i, j;                             \
        printf ("UT_DTfm3D %s:\n", name);       \
        for (i = 0; i < 4; ++i)                 \
        {                                       \
            printf ("\t");                      \
            for (j = 0; j < 3; ++j)             \
                printf ("%lf ", (trans)[i][j]); \
            printf ("\n");                      \
        }                                       \
    }

#define UT_BoxPrint2D(name,box)                 \
    {                                           \
        printf ("UT_Box2D %s:\n", name);        \
        printf ("\t");                          \
        UT_VecPrint2D ("min", (box.min);        \
        printf ("\t");                          \
        UT_VecPrint2D ("max", (box.min);        \
    }

#define UT_DBoxPrint2D(name,box)                \
    {                                           \
        printf ("UT_DBox2D %s:\n", name);       \
        printf ("\t");                          \
        UT_VecPrint2D ("min", (box.min);        \
        printf ("\t");                          \
        UT_VecPrint2D ("max", (box.min);        \
    }

#define UT_DBoxPrint3D(name,box)                \
    {                                           \
        printf ("UT_DBox3D %s:\n", name);       \
        printf ("\t");                          \
        UT_VecPrint3D ("min", (box.min);        \
        printf ("\t");                          \
        UT_VecPrint3D ("max", (box.min);        \
    }

#define UT_BoxPrint3D(name,box)                 \
    {                                           \
        printf ("UT_Box3D %s:\n", name);        \
        printf ("\t");                          \
        UT_VecPrint3D ("min", (box.min);        \
        printf ("\t");                          \
        UT_VecPrint3D ("max", (box.min);        \
    }

#define UT_PlanePrint3D(name,pln)                               \
    {                                                           \
        printf ("UT_Plane3D %s: (%f, %f, %f) %f\n",             \
                name,                                           \
                (pln).nrm[0], (pln).nrm[1], (pln).nrm[2],       \
                (pln).dist);                                    \
    }

#define UT_DPlanePrint3D(name,pln)                              \
    {                                                           \
        printf ("UT_DPlane3D %s: (%f, %f, %f) %f\n",            \
                name,                                           \
                (pln).nrm[0], (pln).nrm[1], (pln).nrm[2],       \
                (pln).dist);                                    \
    }

/* Two and three dimensional constant vectors */

extern POIMG_IMPORT_EXPORT const UT_Vec2D   UT_VecNull2D;
extern POIMG_IMPORT_EXPORT const UT_DVec2D  UT_DVecNull2D;
extern POIMG_IMPORT_EXPORT const UT_Vec3D   UT_VecNull3D;
extern POIMG_IMPORT_EXPORT const UT_DVec3D  UT_DVecNull3D;
extern POIMG_IMPORT_EXPORT const UT_Vec2D   UT_VecOne2D;
extern POIMG_IMPORT_EXPORT const UT_DVec2D  UT_DVecOne2D;
extern POIMG_IMPORT_EXPORT const UT_Vec3D   UT_VecOne3D;
extern POIMG_IMPORT_EXPORT const UT_DVec3D  UT_DVecOne3D;


/* The identical transformation in two and three dimensions */

extern POIMG_IMPORT_EXPORT const UT_Tfm2D   UT_TfmId2D;
extern POIMG_IMPORT_EXPORT const UT_Tfm3D   UT_TfmId3D;


/* Two and three dimensional "world" coordinate systems */

extern POIMG_IMPORT_EXPORT const UT_CoSys2D UT_TfmWorldCoSys2D;
extern POIMG_IMPORT_EXPORT const UT_CoSys3D UT_TfmWorldCoSys3D;

/* Functions defined in UT_VecMacros.c */


extern POIMG_IMPORT_EXPORT void UT_VecCopy2D  (const UT_Vec2D a,  UT_Vec2D b);
extern POIMG_IMPORT_EXPORT void UT_DVecCopy2D (const UT_DVec2D a, UT_DVec2D b);

extern POIMG_IMPORT_EXPORT void UT_VecCopy3D  (const UT_Vec3D a,  UT_Vec3D b);
extern POIMG_IMPORT_EXPORT void UT_DVecCopy3D (const UT_DVec3D a, UT_DVec3D b);

extern POIMG_IMPORT_EXPORT void UT_VecSwap2D  (UT_Vec2D a, UT_Vec2D b);
extern POIMG_IMPORT_EXPORT void UT_DVecSwap2D (UT_DVec2D a, UT_DVec2D b);

extern POIMG_IMPORT_EXPORT void UT_VecSwap3D  (UT_Vec3D a, UT_Vec3D b);
extern POIMG_IMPORT_EXPORT void UT_DVecSwap3D (UT_DVec3D a, UT_DVec3D b);

extern POIMG_IMPORT_EXPORT void UT_VecAdd2D  (const UT_Vec2D a, const UT_Vec2D b, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecAdd2D (const UT_DVec2D a, const UT_DVec2D b, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecAdd3D  (const UT_Vec3D a, const UT_Vec3D b, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecAdd3D (const UT_DVec3D a, const UT_DVec3D b, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT void UT_VecSub2D  (const UT_Vec2D a, const UT_Vec2D b, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecSub2D (const UT_DVec2D a, const UT_DVec2D b, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecSub3D  (const UT_Vec3D a, const UT_Vec3D b, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecSub3D (const UT_DVec3D a, const UT_DVec3D b, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT void UT_VecScale2D  (Float32 m, const UT_Vec2D a, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecScale2D (Float64 m, const UT_DVec2D a, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecScale3D  (Float32 m, const UT_Vec3D a, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecScale3D (Float64 m, const UT_DVec3D a, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT Float32 UT_VecCrossProd2D  (const UT_Vec2D a, const UT_Vec2D b);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecCrossProd2D (const UT_DVec2D a, const UT_DVec2D b);

extern POIMG_IMPORT_EXPORT void UT_VecCrossProd3D  (const UT_Vec3D a, const UT_Vec3D b, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecCrossProd3D (const UT_DVec3D a, const UT_DVec3D b, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT Float32 UT_VecDotProd2D  (const UT_Vec2D a, const UT_Vec2D b);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecDotProd2D (const UT_DVec2D a, const UT_DVec2D b);

extern POIMG_IMPORT_EXPORT Float32 UT_VecDotProd3D  (const UT_Vec3D a, const UT_Vec3D b);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecDotProd3D (const UT_DVec3D a, const UT_DVec3D b);

extern POIMG_IMPORT_EXPORT Float32 UT_VecLength2D  (const UT_Vec2D a);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecLength2D (const UT_DVec2D a);

extern POIMG_IMPORT_EXPORT Float32 UT_VecLength3D  (const UT_Vec3D a);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecLength3D (const UT_DVec3D a);

extern POIMG_IMPORT_EXPORT void UT_VecAddScaled2D  (const UT_Vec2D v1, const UT_Vec2D v2, Float32 a, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecAddScaled2D (const UT_DVec2D v1, const UT_DVec2D v2, Float64 a, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecAddScaled3D  (const UT_Vec3D v1, const UT_Vec3D v2, Float32 a, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecAddScaled3D (const UT_DVec3D v1, const UT_DVec3D v2, Float64 a, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT void UT_VecLinComb2D  (const UT_Vec2D v1, const UT_Vec2D v2, Float32 a, Float32 b, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecLinComb2D (const UT_DVec2D v1, const UT_DVec2D v2, Float64 a, Float64 b, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecLinComb3D  (const UT_Vec3D v1, const UT_Vec3D v2, Float32 a, Float32 b, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecLinComb3D (const UT_DVec3D v1, const UT_DVec3D v2, Float64 a, Float64 b, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT void UT_VecReflect2D  (const UT_Vec2D v, const UT_Vec2D n, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecReflect2D (const UT_DVec2D v, const UT_DVec2D n, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecReflect3D  (const UT_Vec3D v, const UT_Vec3D n, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecReflect3D (const UT_DVec3D v, const UT_DVec3D n, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT void UT_TfmCopy2D  (const UT_Tfm2D  S, UT_Tfm2D  T);
extern POIMG_IMPORT_EXPORT void UT_DTfmCopy2D (const UT_DTfm2D S, UT_DTfm2D T);

extern POIMG_IMPORT_EXPORT void UT_TfmCopy3D  (const UT_Tfm3D  S, UT_Tfm3D  T);
extern POIMG_IMPORT_EXPORT void UT_DTfmCopy3D (const UT_DTfm3D S, UT_DTfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmApply3D   (const UT_Vec3D  v, const UT_Tfm3D  T, UT_Vec3D  r);
extern POIMG_IMPORT_EXPORT void UT_TfmDApply3D  (const UT_DVec3D v, const UT_Tfm3D  T, UT_DVec3D r);
extern POIMG_IMPORT_EXPORT void UT_DTfmApply3D  (const UT_Vec3D  v, const UT_DTfm3D T, UT_Vec3D  r);
extern POIMG_IMPORT_EXPORT void UT_DTfmDApply3D (const UT_DVec3D v, const UT_DTfm3D T, UT_DVec3D r);

/* Functions defined in UT_VecBasic.c */

extern POIMG_IMPORT_EXPORT Float32 UT_VecDist2D  (const UT_Vec2D a, const UT_Vec2D b);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecDist2D (const UT_DVec2D a, const UT_DVec2D b);

extern POIMG_IMPORT_EXPORT Float32 UT_VecDist3D  (const UT_Vec3D a, const UT_Vec3D b);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecDist3D (const UT_DVec3D a, const UT_DVec3D b);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecRefract2D  (const UT_Vec2D v, const UT_Vec2D n,
                                 Float32 i1, Float32 i2, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecRefract2D (const UT_DVec2D v, const UT_DVec2D n,
                                 Float64 i1, Float64 i2, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecRefract3D  (const UT_Vec3D v, const UT_Vec3D n, 
                                 Float32 i1, Float32 i2, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecRefract3D (const UT_DVec3D v, const UT_DVec3D n,
                                 Float64 i1, Float64 i2, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT void UT_VecDecompose2D  (const UT_Vec2D v, const UT_Vec2D n,
                                UT_Vec2D m, UT_Vec2D p);
extern POIMG_IMPORT_EXPORT void UT_DVecDecompose2D (const UT_DVec2D v, const UT_DVec2D n,
                                UT_DVec2D m, UT_DVec2D p);

extern POIMG_IMPORT_EXPORT void UT_VecDecompose3D  (const UT_Vec3D v, const UT_Vec3D n,
                                UT_Vec3D m, UT_Vec3D p);
extern POIMG_IMPORT_EXPORT void UT_DVecDecompose3D (const UT_DVec3D v, const UT_DVec3D n,
                                UT_DVec3D m, UT_DVec3D p);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecUnit2D  (UT_Vec2D v);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecUnit2D (UT_DVec2D v);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecUnit3D  (UT_Vec3D v);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecUnit3D (UT_DVec3D v);

/* Functions defined in UT_VecIsect.c */

extern POIMG_IMPORT_EXPORT void UT_VecDistPointLine2D  (const UT_Vec2D a, const UT_Vec2D b,
                                    const UT_Vec2D d, Float32 *f, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DVecDistPointLine2D (const UT_DVec2D a, const UT_DVec2D b,
                                    const UT_DVec2D d, Float64 *f, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_VecDistPointLine3D  (const UT_Vec3D a, const UT_Vec3D b,
                                    const UT_Vec3D d, Float32 *f, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DVecDistPointLine3D (const UT_DVec3D a, const UT_DVec3D b,
                                    const UT_DVec3D d, Float64 *f, UT_DVec3D r);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecPointInTria2D  (const UT_Vec2D t1, const UT_Vec2D t2,
                                     const UT_Vec2D t3, const UT_Vec2D p);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecPointInTria2D (const UT_DVec2D t1, const UT_DVec2D t2,
                                     const UT_DVec2D t3, const UT_DVec2D p);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecPointInTria3D  (const UT_Vec3D t1, const UT_Vec3D t2,
                                     const UT_Vec3D t3, const UT_Vec3D p);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecPointInTria3D (const UT_DVec3D t1, const UT_DVec3D t2,
                                     const UT_DVec3D t3, const UT_DVec3D p);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecIsectPlaneLine2D  (const UT_Vec2D a, const UT_Vec2D n,
                                        const UT_Vec2D b, const UT_Vec2D d,
                                        Float32 *f);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecIsectPlaneLine2D (const UT_DVec2D a, const UT_DVec2D n,
                                        const UT_DVec2D b, const UT_DVec2D d,
                                        Float64 *f);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecIsectPlaneLine3D  (const UT_Vec3D a, const UT_Vec3D n,
                                        const UT_Vec3D b, const UT_Vec3D d,
                                        Float32 *f);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecIsectPlaneLine3D (const UT_DVec3D a, const UT_DVec3D n,
                                        const UT_DVec3D b, const UT_DVec3D d,
                                        Float64 *f);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecDistLineLine3D  (const UT_Vec3D a1, const UT_Vec3D b1,
                                      const UT_Vec3D a2, const UT_Vec3D b2,
                                      Float32 *d, Float32 *s1, Float32 *s2);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecDistLineLine3D (const UT_DVec3D a1, const UT_DVec3D b1,
                                      const UT_DVec3D a2, const UT_DVec3D b2,
                                      Float64 *d, Float64 *s1, Float64 *s2);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecIsectPlanePlane3D  (const UT_Vec3D n1, Float32 d1,
                                         const UT_Vec3D n2, Float32 d2,
                                         UT_Vec3D dir, UT_Vec3D a);
extern POIMG_IMPORT_EXPORT UT_Bool UT_DVecIsectPlanePlane3D (const UT_DVec3D n1, Float64 d1,
                                         const UT_DVec3D n2, Float64 d2,
                                         UT_DVec3D dir, UT_DVec3D a);

extern POIMG_IMPORT_EXPORT UT_Bool UT_VecTriaToPlane3D (const UT_DVec3D pos0, const UT_DVec3D pos1,
                                    const UT_DVec3D pos2, UT_Plane3D *plane);
extern POIMG_IMPORT_EXPORT UT_Bool UT_VecIsectToPlane3D (const UT_DVec3D pos0, const UT_DVec3D pos1,
                                     const UT_DVec3D pos2, UT_Plane3D *pl);
extern POIMG_IMPORT_EXPORT UT_Bool UT_VecIsectLineTria3D (const UT_Vec3D lineStart, 
                                      const UT_Vec3D lineDir,
                                      const UT_DVec3D pos0, 
                                      const UT_DVec3D pos1,
                                      const UT_DVec3D pos2,
                                      UT_Vec3D isectPos,
                                      UT_Vec3D isectNrm,
                                      Float32 *distance);

/* Functions defined in UT_VecAngle.c */

extern POIMG_IMPORT_EXPORT Float32 UT_VecAngle2D  (const UT_Vec2D v1, const UT_Vec2D v2);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecAngle2D (const UT_DVec2D v1, const UT_DVec2D v2);

extern POIMG_IMPORT_EXPORT Float32 UT_VecAngle3D  (const UT_Vec3D v1, const UT_Vec3D v2, 
                               const UT_Vec3D nrm);
extern POIMG_IMPORT_EXPORT Float64 UT_DVecAngle3D (const UT_DVec3D v1, const UT_DVec3D v2,
                               const UT_DVec3D nrm);

extern POIMG_IMPORT_EXPORT Int32 UT_VecSignAngle2D  (const UT_Vec2D v1, const UT_Vec2D v2);
extern POIMG_IMPORT_EXPORT Int32 UT_DVecSignAngle2D (const UT_DVec2D v1, const UT_DVec2D v2);

extern POIMG_IMPORT_EXPORT Int32 UT_VecSignAngle3D  (const UT_Vec3D v1, const UT_Vec3D v2,
                                 const UT_Vec3D nrm);
extern POIMG_IMPORT_EXPORT Int32 UT_DVecSignAngle3D (const UT_DVec3D v1, const UT_DVec3D v2,
                                 const UT_DVec3D nrm);

/* Functions defined in UT_VecTfm.c */

extern POIMG_IMPORT_EXPORT void UT_TfmBuildTrans2D (const UT_Vec2D v, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmBuildTrans3D (const UT_Vec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_DTfmBuildTrans3D (const UT_DVec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_DTfmBuildDTrans3D (const UT_DVec3D v, UT_DTfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmBuildRot2D (Float32 ang, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmBuildRot3D (const UT_Vec3D v, UT_Tfm3D t);
extern POIMG_IMPORT_EXPORT void UT_DTfmBuildRot3D (const UT_DVec3D v, UT_Tfm3D t);
extern POIMG_IMPORT_EXPORT void UT_DTfmBuildDRot3D (const UT_DVec3D v, UT_DTfm3D t);

extern POIMG_IMPORT_EXPORT void UT_TfmBuildRotArb3D (const UT_Vec3D v,
                                 Float32 ang, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_TfmBuildRotArbLos3D (const UT_Vec3D o, const UT_Vec3D v,
                                    Float32 ang, UT_Tfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmBuildScale2D (const UT_Vec2D v, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmBuildScale3D (const UT_Vec3D v, UT_Tfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmBuildLookAtVec3D (const UT_Vec3D eyePos, const UT_Vec3D atVec, 
                                    const UT_Vec3D upVec, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_TfmBuildLookAt3D (const UT_Vec3D eyePos, const UT_Vec3D atPos, 
                                 const UT_Vec3D upVec, UT_Tfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmConcat2D (UT_Tfm2D A, UT_Tfm2D B, UT_Tfm2D R);
extern POIMG_IMPORT_EXPORT void UT_TfmConcat3D (UT_Tfm3D A, UT_Tfm3D B, UT_Tfm3D R);
extern POIMG_IMPORT_EXPORT void UT_DTfmConcat3D (UT_DTfm3D A, UT_DTfm3D B, UT_DTfm3D R);

extern POIMG_IMPORT_EXPORT void UT_TfmConcatTrans2D (const UT_Vec2D v, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmConcatTrans3D (const UT_Vec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_DTfmConcatTrans3D (const UT_DVec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_DTfmConcatDTrans3D (const UT_DVec3D v, UT_DTfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmConcatRot2D (Float32 ang, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmConcatRot3D (const UT_Vec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_DTfmConcatRot3D (const UT_DVec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_DTfmConcatDRot3D (const UT_DVec3D v, UT_DTfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmConcatScale2D (const UT_Vec2D v, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmConcatScale3D (const UT_Vec3D v, UT_Tfm3D T);

extern void UT_TfmMultRot3D   (const UT_Vec3D v, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT void UT_TfmMultTrans3D (const UT_Vec3D v, UT_Tfm3D T);

extern POIMG_IMPORT_EXPORT UT_Bool UT_TfmInvert2D (const UT_Tfm2D A, UT_Tfm2D R);
extern POIMG_IMPORT_EXPORT UT_Bool UT_TfmInvert3D (const UT_Tfm3D A, UT_Tfm3D R);

extern POIMG_IMPORT_EXPORT void UT_TfmTranspose3D (const UT_Tfm3D T, UT_Tfm3D R);

extern POIMG_IMPORT_EXPORT void UT_TfmCoord2D (const UT_CoSys2D *A, const UT_CoSys2D *B, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT void UT_TfmCoord3D (const UT_CoSys3D *A, const UT_CoSys3D *B, UT_Tfm3D T);

extern POIMG_IMPORT_EXPORT void UT_TfmInitCoord2D (UT_CoSys2D *A);
extern POIMG_IMPORT_EXPORT void UT_TfmInitCoord3D (UT_CoSys3D *A);

extern POIMG_IMPORT_EXPORT void UT_TfmApply2D (const UT_Vec2D v, const UT_Tfm2D T, UT_Vec2D r);
extern POIMG_IMPORT_EXPORT void UT_DTfmApply2D (const UT_DVec2D v, const UT_Tfm2D T, UT_DVec2D r);

extern POIMG_IMPORT_EXPORT void UT_TfmApplyNormal3D  (const UT_Vec3D n, const UT_Tfm3D T, UT_Vec3D r);
extern POIMG_IMPORT_EXPORT void UT_DTfmApplyNormal3D (const UT_DVec3D n, const UT_Tfm3D T, UT_DVec3D r);

#ifdef __cplusplus
}
#endif

#endif /* __UT_VECTOR_H__ */
