// Copyright (C) 2002-2006 Nikolaus Gebhardt // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h #pragma once #include "irrMath.h" namespace Irrlicht { namespace Core { /// /// 3d vector class with lots of operators and methods. /// This class has been ported directly from the native C++ Irrlicht Engine, so it may not /// be 100% complete yet and the design may not be 100% .NET like. /// public __value class Vector3D { public: Vector3D(): X(0), Y(0), Z(0) {}; Vector3D(float nx, float ny, float nz) : X(nx), Y(ny), Z(nz) {}; static bool op_Equality(Vector3D o1, Vector3D o2) { return (o1.X == o2.X && o1.Y == o2.Y && o1.Z == o2.Z); } static Vector3D op_Addition(Vector3D o1, Vector3D o2) { return Vector3D(o1.X + o2.X, o1.Y + o2.Y, o1.Z + o2.Z); } static Vector3D op_Subtraction(Vector3D o1, Vector3D o2) { return Vector3D(o1.X - o2.X, o1.Y - o2.Y, o1.Z - o2.Z); } static Vector3D op_Multiply(Vector3D o, float scal) { return Vector3D(o.X * scal, o.Y * scal, o.Z * scal); } static Vector3D op_Multiply(float scal, const Vector3D& o) { return Vector3D(o.X * scal, o.Y * scal, o.Z * scal); } static Vector3D op_Division(Vector3D o, float scal) { return Vector3D(o.X / scal, o.Y / scal, o.Z / scal); } void Set( float nx, float ny, float nz) {X=nx; Y=ny; Z=nz; } void Set( Vector3D p) { X=p.X; Y=p.Y; Z=p.Z;} /// /// Returns length of the vector. /// double GetLength() { return get_Length(); } /// /// Returns length of the vector. /// __property double get_Length() { return System::Math::Sqrt(X*X + Y*Y + Z*Z); } /// /// Returns squared length of the vector. /// This is useful because it is much faster then /// GetLength(). /// double GetLengthSQ() { return get_LengthSQ(); } /// /// Returns squared length of the vector. /// This is useful because it is much faster then /// GetLength(). /// __property double get_LengthSQ() { return X*X + Y*Y + Z*Z; } /// /// Returns the dot product with another vector. /// float DotProduct( Vector3D other) { return X*other.X + Y*other.Y + Z*other.Z; } /// /// Returns distance from an other point. Here, the vector is interpreted as /// point in 3 dimensional space. /// double GetDistanceFrom( Vector3D other) { double vx = X - other.X; double vy = Y - other.Y; double vz = Z - other.Z; return Math::Sqrt(vx*vx + vy*vy + vz*vz); } /// /// Returns squared distance from an other point. /// Here, the vector is interpreted as point in 3 dimensional space. /// float GetDistanceFromSQ( Vector3D other) { float vx = X - other.X; float vy = Y - other.Y; float vz = Z - other.Z; return (vx*vx + vy*vy + vz*vz); } /// /// Returns cross product with an other vector /// /// other vector ///cross product Vector3D CrossProduct( Vector3D p) { return Vector3D(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X); } /// /// Returns if the point represented by this vector is between to points /// ///Start point of line ///End point of line /// True if between points, false if not. bool IsBetweenPoints( Vector3D begin, Vector3D end) { float f = (float)(end - begin).GetLengthSQ(); return (float)GetDistanceFromSQ(begin) < f && (float)GetDistanceFromSQ(end) < f; } /// /// Normalizes the vector. /// Vector3D Normalize() { float inv = (float)GetLength(); if ( inv == 0 ) return *this; inv = 1.0f / inv; X *= inv; Y *= inv; Z *= inv; return *this; } /// /// Sets the lenght of the vector to a new value /// void SetLength(float newlength) { Normalize(); (*this) = (*this)*newlength; } /// /// Inverts the vector. /// void Invert() { X *= -1.0f; Y *= -1.0f; Z *= -1.0f; } /// /// Rotates the vector around one axis /// /// Degrees to rotate vector /// Center of rotation void RotateXZBy(double degrees, Vector3D center) { degrees *=GRAD_PI2; float cs = (float)Math::Cos(degrees); float sn = (float)Math::Sin(degrees); X -= center.X; Z -= center.Z; Set(X*cs - Z*sn, Y, X*sn + Z*cs); X += center.X; Z += center.Z; } /// /// Rotates the vector around one axis /// /// Degrees to rotate vector /// Center of rotation void RotateXYBy(double degrees, Vector3D center) { degrees *=GRAD_PI2; float cs = (float)Math::Cos(degrees); float sn = (float)Math::Sin(degrees); X -= center.X; Y -= center.Y; Set(X*cs - Y*sn, X*sn + Y*cs, Z); X += center.X; Y += center.Y; } /// /// Rotates the vector around one axis /// /// Degrees to rotate vector /// Center of rotation void RotateYZBy(double degrees, Vector3D center) { degrees *=GRAD_PI2; float cs = (float)Math::Cos(degrees); float sn = (float)Math::Sin(degrees); Z -= center.Z; Y -= center.Y; Set(X, Y*cs - Z*sn, Y*sn + Z*cs); Z += center.Z; Y += center.Y; } /// /// returns interpolated vector /// /// other vector to interpolate between /// value between 0.0f and 1.0f. Vector3D GetInterpolated( Vector3D other, float d) { float inv = 1.0f - d; return Vector3D(other.X*inv + X*d, other.Y*inv + Y*d, other.Z*inv + Z*d); } /// /// Compares the vector to another vector. /// bool Equals(Object* rhs) { Vector3D* c = dynamic_cast(rhs); if(!c) return false; return c->X == X && c->Y == Y && c->Z == Z; } virtual System::String __gc * ToString() { return System::String::Concat( System::String::Concat( "(", X.ToString(), ", ", Y.ToString()), ", ", Z.ToString(), ")" ); } // member variables float X, Y, Z; }; } }