/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                   Copyright (c) 2002 Zanoza Software.                   *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler's native 3d point
 *--------------------------------------------------------------------------
 * @histroy: 08.03.2003. Created
 */
#ifndef zpoint3d_h_included
#define zpoint3d_h_included

#ifndef zsequence_h_included
# include "zsequence.h"
#endif
#include <core/coreTypes.h>

//------------------------------------------------------
//  ZPoint3D - ZModeler's native 3D Point
//------------------------------------------------------
class DLL_LINKAGE ZPoint3D
{
public:
  //
  // constructors/destructors
  //
  ZPoint3D();
  ZPoint3D(const float _x, const float _y, const float _z, const float _w = 1.0f);
  ZPoint3D(const ZPoint3D& point);
  ZPoint3D(const float* initdata); //uses only three floats
  ~ZPoint3D();

public:
  //
  // access grants
  //
  float& operator [] ( core::eAxis component);
  float  operator [] ( core::eAxis component) const;

public:
  //
  // casting operators
  //
  operator float* ();
  operator const float* () const;

public:
  //
  // assignment operators
  //
  ZPoint3D& operator =  ( const ZPoint3D& p);
  ZPoint3D& operator += ( const ZPoint3D& p);
  ZPoint3D& operator -= ( const ZPoint3D& p);
  ZPoint3D& operator *= ( float v);
  ZPoint3D& operator /= ( float v);

public:
  //
  // unary operators
  //
  ZPoint3D operator + () const;
  ZPoint3D operator - () const;

public:
  //
  // binary operators
  //
  ZPoint3D operator + ( const ZPoint3D& p) const;
  ZPoint3D operator - ( const ZPoint3D& p) const;
  ZPoint3D operator * ( const ZPoint3D& p) const; //cross product
  ZPoint3D operator * ( float v) const;
  ZPoint3D operator / ( float v) const;
  float    operator ^ ( const ZPoint3D& p) const; //dot product

public:
  //
  // friend operators
  //
  friend DLL_LINKAGE ZPoint3D operator * ( const float v, const ZPoint3D& p);

public:
  //
  // compare operators
  //
  bool operator == ( const ZPoint3D& p) const;
  bool operator != ( const ZPoint3D& p) const;
  bool operator < ( const ZPoint3D& p) const;
  bool operator <= ( const ZPoint3D& p) const;

public:
  //
  // operations
  //
  float     length() const;
  float     length2() const;
  inline float lengthInv() const { return INV_SQRTF(x*x+y*y+z*z); }
  float     distance( const ZPoint3D& p) const;
  inline float distance2( const ZPoint3D& p) const 
    { return (p.x-x)*(p.x-x) + (p.y-y)*(p.y-y) + (p.z-z)*(p.z-z); }
  ZAngle    angle( const ZPoint3D& p) const;
  bool      normalize();
  bool      isInsideTriangle(const ZPoint3D& ptV0, const ZPoint3D& ptV1, const ZPoint3D& ptV2) const;
  bool      getWeightCoefficients(const ZPoint3D& pt1, const ZPoint3D& pt2, const ZPoint3D& pt3, float *p1, float *p2, float *p3) const;
  void      minimum(const ZPoint3D& pt);
  void      maximum(const ZPoint3D& pt);
public:
  //
  // data members
  //
  float x, y, z, w;
};

//
// adjacent typedefs:
typedef ZSequence<ZPoint3D>   ZPoint3DSeq;
typedef ZPoint3D              ZVector;
typedef ZPoint3DSeq           ZVectorSeq;


#endif //zpoint3d_h_included

