diff --git a/CHANGES.md b/CHANGES.md
index e8c4feea..45a9a8b9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,6 +11,7 @@
- Added IntersectsWithBox(), IntersectsWithLine() and IsValid; renamed Empty to IsEmpty in AABBox.
- Added zClipFromZero flag to BuildProjectionMatrix*() methods in Matrix.
- Added Size in Rect*.
+- Updated Interpolate(), Invert(), Normalize() and RotateBy() in Vector2D*/3D* to return self vector (was new vector).
- Updated GetIntersectionWithLine(), GetIntersectionWithLimitedLine() and GetIntersectionWithPlanes() to return Vector3Df of the intersection and null if none in Plane3Df. Instead of returning bool and having out arg.
- Added TextureCubemapSeamless to VideoDriverFeature.
- Added RotateLeft and RotateRight to KeyAction.
diff --git a/examples/10.Shaders/Program.cs b/examples/10.Shaders/Program.cs
index 58d49fdc..68dbdfd7 100644
--- a/examples/10.Shaders/Program.cs
+++ b/examples/10.Shaders/Program.cs
@@ -256,9 +256,9 @@ static void gpu_OnSetConstants(MaterialRendererServices services, int userData)
Vector3Df pos = device.SceneManager.ActiveCamera.AbsolutePosition;
if (useHighLevelShaders)
- services.SetVertexShaderConstant(shaderLightPosId, pos.ToArray());
+ services.SetVertexShaderConstant(shaderLightPosId, pos.ToArrayOf4());
else
- services.SetVertexShaderConstantList(8, pos.ToArray());
+ services.SetVertexShaderConstantList(8, pos.ToArrayOf4());
// set light color
diff --git a/source/Vector.h b/source/Vector.h
index 5ae87c0a..76746867 100644
--- a/source/Vector.h
+++ b/source/Vector.h
@@ -61,4 +61,4 @@ namespace Core {
#undef _REFCLASS_
} // end namespace Core
-} // end namespace IrrlichtLime
\ No newline at end of file
+} // end namespace IrrlichtLime
diff --git a/source/Vector2D_template.h b/source/Vector2D_template.h
index 791ab674..b689e96a 100644
--- a/source/Vector2D_template.h
+++ b/source/Vector2D_template.h
@@ -2,50 +2,85 @@
#error _REFCLASS_, _WRAPCLASS_ and _WRAPTYPE_ must be defined for this file to process.
#endif
+///
+/// 2d vector class with lots of operators and methods.
+///
public ref class _REFCLASS_ : Lime::NativeValue<_WRAPCLASS_>
{
#include "Vector_common_template.h"
public:
+ ///
+ /// Constructor with two scalars.
+ ///
_REFCLASS_(_WRAPTYPE_ x, _WRAPTYPE_ y)
: Lime::NativeValue<_WRAPCLASS_>(true)
{
m_NativeValue = new _WRAPCLASS_(x, y);
}
+ ///
+ /// Set this vector by two scalars.
+ ///
void Set(_WRAPTYPE_ x, _WRAPTYPE_ y)
{
m_NativeValue->set(x, y);
}
+ ///
+ /// Calculates the angle between this vector and another one in degree.
+ ///
double GetAngleWith(_REFCLASS_^ other)
{
LIME_ASSERT(other != nullptr);
return m_NativeValue->getAngleWith(*other->m_NativeValue);
}
+ ///
+ /// Rotates the point anticlockwise around a center by an amount of degrees.
+ ///
+ /// The center of the rotation. Default is (0,0).
+ /// This vector after transformation.
_REFCLASS_^ RotateBy(double degrees, _REFCLASS_^ center)
{
LIME_ASSERT(center != nullptr);
- return gcnew _REFCLASS_(m_NativeValue->rotateBy(degrees, *center->m_NativeValue));
+
+ m_NativeValue->rotateBy(degrees, *center->m_NativeValue);
+ return this;
}
+ ///
+ /// Rotates the point anticlockwise around a center by an amount of degrees.
+ ///
+ /// This vector after transformation.
_REFCLASS_^ RotateBy(double degrees)
{
- return gcnew _REFCLASS_(m_NativeValue->rotateBy(degrees));
+ m_NativeValue->rotateBy(degrees);
+ return this;
}
+ ///
+ /// The angle of this vector in degrees in the counter trigonometric sense.
+ /// 0 is to the right (3 o'clock), values increase clockwise.
+ ///
property double Angle
{
double get() { return m_NativeValue->getAngle(); }
}
+ ///
+ /// The angle of this vector in degrees in the trigonometric sense.
+ /// 0 is to the right (3 o'clock), values increase counter-clockwise.
+ ///
property double AngleTrig
{
double get() { return m_NativeValue->getAngleTrig(); }
}
+ ///
+ /// The length of the vector.
+ ///
property _WRAPTYPE_ Length
{
_WRAPTYPE_ get() { return m_NativeValue->getLength(); }
@@ -55,4 +90,4 @@ public ref class _REFCLASS_ : Lime::NativeValue<_WRAPCLASS_>
{
return String::Format("{0}, {1}", X, Y);
}
-};
\ No newline at end of file
+};
diff --git a/source/Vector3D_template.h b/source/Vector3D_template.h
index b447d890..f0723cd2 100644
--- a/source/Vector3D_template.h
+++ b/source/Vector3D_template.h
@@ -2,36 +2,75 @@
#error _REFCLASS_, _WRAPCLASS_ and _WRAPTYPE_ must be defined for this file to process.
#endif
+///
+/// 3d vector class with lots of operators and methods.
+/// This class is used in Irrlicht for three main purposes:
+/// 1) As a direction vector (most of the methods assume this).
+/// 2) As a position in 3d space (which is synonymous with a direction vector from the origin to this position).
+/// 3) To hold three Euler rotations, where X is pitch, Y is yaw and Z is roll.
+///
public ref class _REFCLASS_ : Lime::NativeValue<_WRAPCLASS_>
{
#include "Vector_common_template.h"
public:
+ ///
+ /// Constructor with three scalars.
+ ///
_REFCLASS_(_WRAPTYPE_ x, _WRAPTYPE_ y, _WRAPTYPE_ z)
: Lime::NativeValue<_WRAPCLASS_>(true)
{
m_NativeValue = new _WRAPCLASS_(x, y, z);
}
+ ///
+ /// Set this vector by three scalars.
+ ///
void Set(_WRAPTYPE_ x, _WRAPTYPE_ y, _WRAPTYPE_ z)
{
m_NativeValue->set(x, y, z);
}
+ ///
+ /// Calculates the cross product with another vector.
+ ///
_REFCLASS_^ CrossProduct(_REFCLASS_^ other)
{
LIME_ASSERT(other != nullptr);
return gcnew _REFCLASS_(m_NativeValue->crossProduct(*other->m_NativeValue));
}
+ ///
+ /// Check if this vector equals the other one, taking floating point rounding errors into account.
+ ///
bool EqualsTo(_REFCLASS_^ other, _WRAPTYPE_ tolerance)
{
LIME_ASSERT(other != nullptr);
return m_NativeValue->equals(*other->m_NativeValue, tolerance);
}
- array<_WRAPTYPE_>^ ToArray()
+ ///
+ /// Fills an array of 3 values with the vector data.
+ /// Useful for setting in shader constants for example.
+ ///
+ array<_WRAPTYPE_>^ ToArrayOf3()
+ {
+ _WRAPTYPE_ b[3];
+ m_NativeValue->getAs3Values(b);
+
+ array<_WRAPTYPE_>^ a = gcnew array<_WRAPTYPE_>(3);
+ for (int i = 0; i < 3; i++)
+ a[i] = b[i];
+
+ return a;
+ }
+
+ ///
+ /// Fills an array of 4 values with the vector data.
+ /// Useful for setting in shader constants for example. The fourth value will always be 0.
+ ///
+ array<_WRAPTYPE_>^ ToArrayOf4()
{
_WRAPTYPE_ b[4];
m_NativeValue->getAs4Values(b);
@@ -43,72 +82,127 @@ public ref class _REFCLASS_ : Lime::NativeValue<_WRAPCLASS_>
return a;
}
+ ///
+ /// Inverts this vector.
+ ///
+ /// This vector after inversion.
_REFCLASS_^ Invert()
{
m_NativeValue->invert();
- return gcnew _REFCLASS_(*m_NativeValue);
+ return this;
}
+ ///
+ /// Rotates this vector by a specified number of degrees around the Z axis and the specified center.
+ ///
+ /// The center of the rotation. Default is (0,0,0).
void RotateXYby(double degrees, _REFCLASS_^ center)
{
LIME_ASSERT(center != nullptr);
m_NativeValue->rotateXYBy(degrees, *center->m_NativeValue);
}
+ ///
+ /// Rotates this vector by a specified number of degrees around the Z axis and the specified center.
+ ///
void RotateXYby(double degrees)
{
m_NativeValue->rotateXYBy(degrees);
}
+ ///
+ /// Rotates this vector by a specified number of degrees around the Y axis and the specified center.
+ ///
+ /// The center of the rotation. Default is (0,0,0).
void RotateXZby(double degrees, _REFCLASS_^ center)
{
LIME_ASSERT(center != nullptr);
m_NativeValue->rotateXZBy(degrees, *center->m_NativeValue);
}
+ ///
+ /// Rotates this vector by a specified number of degrees around the Y axis and the specified center.
+ ///
void RotateXZby(double degrees)
{
m_NativeValue->rotateXZBy(degrees);
}
+ ///
+ /// Rotates this vector by a specified number of degrees around the X axis and the specified center.
+ ///
+ /// The center of the rotation. Default is (0,0,0).
void RotateYZby(double degrees, _REFCLASS_^ center)
{
LIME_ASSERT(center != nullptr);
m_NativeValue->rotateYZBy(degrees, *center->m_NativeValue);
}
+ ///
+ /// Rotates this vector by a specified number of degrees around the X axis and the specified center.
+ ///
void RotateYZby(double degrees)
{
m_NativeValue->rotateYZBy(degrees);
}
+ ///
+ /// Builds a direction vector from (this) rotation vector.
+ /// This vector is assumed to be a rotation vector composed of 3 Euler angle rotations, in degrees.
+ /// The implementation performs the same calculations as using a matrix to do the rotation.
+ ///
+ /// The direction representing "forwards" which will be rotated by this vector. Default is (0,0,1).
+ /// A direction vector calculated by rotating the forwards direction by the 3 Euler angles (in degrees) represented by this vector.
_REFCLASS_^ RotationToDirection(_REFCLASS_^ forwards)
{
LIME_ASSERT(forwards != nullptr);
return gcnew _REFCLASS_(m_NativeValue->rotationToDirection(*forwards->m_NativeValue));
}
+ ///
+ /// Builds a direction vector from (this) rotation vector.
+ /// This vector is assumed to be a rotation vector composed of 3 Euler angle rotations, in degrees.
+ /// The implementation performs the same calculations as using a matrix to do the rotation.
+ ///
+ /// A direction vector calculated by rotating the forwards direction by the 3 Euler angles (in degrees) represented by this vector.
_REFCLASS_^ RotationToDirection()
{
return gcnew _REFCLASS_(m_NativeValue->rotationToDirection());
}
+ ///
+ /// The rotations that would make a (0,0,1) direction vector point in the same direction as this direction vector.
+ /// Thanks to Arras on the Irrlicht forums for this method. This utility method is very useful for orienting scene nodes towards specific targets.
+ /// For example, if this vector represents the difference between two scene nodes, then applying the result of this property to one scene node
+ /// will point it at the other one.
+ ///
property _REFCLASS_^ HorizontalAngle
{
_REFCLASS_^ get() { return gcnew _REFCLASS_(m_NativeValue->getHorizontalAngle()); }
}
+ ///
+ /// The length of the vector.
+ ///
property _WRAPTYPE_ Length
{
_WRAPTYPE_ get() { return m_NativeValue->getLength(); }
void set(_WRAPTYPE_ value) { m_NativeValue->setLength(value); }
}
+ ///
+ /// The spherical coordinate angles.
+ /// This returns Euler degrees for the point represented by this vector.
+ /// The calculation assumes the pole at (0, 1, 0) and returns the angles in X and Y.
+ ///
property _REFCLASS_^ SphericalCoordinateAngles
{
_REFCLASS_^ get() { return gcnew _REFCLASS_(m_NativeValue->getSphericalCoordinateAngles()); }
}
+ ///
+ /// Z coordinate of the vector.
+ ///
property _WRAPTYPE_ Z
{
_WRAPTYPE_ get() { return m_NativeValue->Z; }
@@ -119,4 +213,4 @@ public ref class _REFCLASS_ : Lime::NativeValue<_WRAPCLASS_>
{
return String::Format("{0}, {1}, {2}", X, Y, Z);
}
-};
\ No newline at end of file
+};
diff --git a/source/Vector_common_template.h b/source/Vector_common_template.h
index 44354c21..bafc65fa 100644
--- a/source/Vector_common_template.h
+++ b/source/Vector_common_template.h
@@ -6,6 +6,9 @@
// operators
+ ///
+ /// Equality operator.
+ ///
static bool operator == (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
bool v1n = Object::ReferenceEquals(v1, nullptr);
@@ -20,11 +23,17 @@
return (*v1->m_NativeValue) == (*v2->m_NativeValue);
}
+ ///
+ /// Inequality operator.
+ ///
static bool operator != (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
return !(v1 == v2);
}
+ ///
+ /// > operator.
+ ///
static bool operator > (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -33,6 +42,9 @@
return (*v1->m_NativeValue) > (*v2->m_NativeValue);
}
+ ///
+ /// >= operator.
+ ///
static bool operator >= (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -41,6 +53,9 @@
return (*v1->m_NativeValue) >= (*v2->m_NativeValue);
}
+ ///
+ /// < operator.
+ ///
static bool operator < (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -49,6 +64,9 @@
return (*v1->m_NativeValue) < (*v2->m_NativeValue);
}
+ ///
+ /// <= operator.
+ ///
static bool operator <= (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -57,6 +75,9 @@
return (*v1->m_NativeValue) <= (*v2->m_NativeValue);
}
+ ///
+ /// Add two vectors.
+ ///
static _REFCLASS_^ operator + (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -65,12 +86,18 @@
return gcnew _REFCLASS_((*v1->m_NativeValue) + (*v2->m_NativeValue));
}
+ ///
+ /// Add vector and scalar.
+ ///
static _REFCLASS_^ operator + (_REFCLASS_^ v1, _WRAPTYPE_ v2)
{
LIME_ASSERT(v1 != nullptr);
return gcnew _REFCLASS_((*v1->m_NativeValue) + v2);
}
+ ///
+ /// Subtract two vectors.
+ ///
static _REFCLASS_^ operator - (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -79,12 +106,18 @@
return gcnew _REFCLASS_((*v1->m_NativeValue) - (*v2->m_NativeValue));
}
+ ///
+ /// Subtract vector and scalar.
+ ///
static _REFCLASS_^ operator - (_REFCLASS_^ v1, _WRAPTYPE_ v2)
{
LIME_ASSERT(v1 != nullptr);
return gcnew _REFCLASS_((*v1->m_NativeValue) - v2);
}
+ ///
+ /// Multiple two vectors.
+ ///
static _REFCLASS_^ operator * (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -93,12 +126,18 @@
return gcnew _REFCLASS_((*v1->m_NativeValue) * (*v2->m_NativeValue));
}
+ ///
+ /// Multiple vector and scalar.
+ ///
static _REFCLASS_^ operator * (_REFCLASS_^ v1, _WRAPTYPE_ v2)
{
LIME_ASSERT(v1 != nullptr);
return gcnew _REFCLASS_((*v1->m_NativeValue) * v2);
}
+ ///
+ /// Divide two vectors.
+ ///
static _REFCLASS_^ operator / (_REFCLASS_^ v1, _REFCLASS_^ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -107,6 +146,9 @@
return gcnew _REFCLASS_((*v1->m_NativeValue) / (*v2->m_NativeValue));
}
+ ///
+ /// Divide vector and scalar.
+ ///
static _REFCLASS_^ operator / (_REFCLASS_^ v1, _WRAPTYPE_ v2)
{
LIME_ASSERT(v1 != nullptr);
@@ -115,6 +157,9 @@
// constructors
+ ///
+ /// Copy constructor.
+ ///
_REFCLASS_(_REFCLASS_^ copy)
: Lime::NativeValue<_WRAPCLASS_>(true)
{
@@ -122,12 +167,18 @@
m_NativeValue = new _WRAPCLASS_(*copy->m_NativeValue);
}
+ ///
+ /// Construct vector with all component same.
+ ///
_REFCLASS_(_WRAPTYPE_ all)
: Lime::NativeValue<_WRAPCLASS_>(true)
{
m_NativeValue = new _WRAPCLASS_(all);
}
+ ///
+ /// Default constructor. Set all components to 0.
+ ///
_REFCLASS_()
: Lime::NativeValue<_WRAPCLASS_>(true)
{
@@ -136,6 +187,9 @@
// Set()
+ ///
+ /// Set this vector to another one.
+ ///
void Set(_REFCLASS_^ copy)
{
LIME_ASSERT(copy != nullptr);
@@ -144,53 +198,97 @@
// other common methods
+ ///
+ /// Get the dot product with another vector.
+ ///
_WRAPTYPE_ DotProduct(_REFCLASS_^ other)
{
LIME_ASSERT(other != nullptr);
return m_NativeValue->dotProduct(*other->m_NativeValue);
}
+ ///
+ /// Check if this vector equals the other one, taking floating point rounding errors into account.
+ ///
bool EqualsTo(_REFCLASS_^ other)
{
LIME_ASSERT(other != nullptr);
return m_NativeValue->equals(*other->m_NativeValue);
}
+ ///
+ /// Get distance from another point.
+ /// Here, the vector is interpreted as point in space.
+ ///
_WRAPTYPE_ GetDistanceFrom(_REFCLASS_^ other)
{
LIME_ASSERT(other != nullptr);
return m_NativeValue->getDistanceFrom(*other->m_NativeValue);
}
+ ///
+ /// Get squared distance from another point.
+ /// Here, the vector is interpreted as point in space.
+ ///
_WRAPTYPE_ GetDistanceFromSQ(_REFCLASS_^ other)
{
LIME_ASSERT(other != nullptr);
return m_NativeValue->getDistanceFromSQ(*other->m_NativeValue);
}
+ ///
+ /// Creates an interpolated vector between this vector and another vector.
+ ///
+ /// The other vector to interpolate with.
+ /// Interpolation value between 0.0f (all the other vector) and 1.0f (all this vector).
+ /// Note that this is the opposite direction of interpolation to GetInterpolatedQuadratic().
+ /// An interpolated vector. This vector is not modified.
_REFCLASS_^ GetInterpolated(_REFCLASS_^ other, double d)
{
LIME_ASSERT(other != nullptr);
return gcnew _REFCLASS_(m_NativeValue->getInterpolated(*other->m_NativeValue, d));
}
- _REFCLASS_^ GetInterpolatedQuadratic(_REFCLASS_^ other1, _REFCLASS_^ other2, double d)
+ ///
+ /// Creates a quadratically interpolated vector between this and two other vectors.
+ ///
+ /// Second vector to interpolate with.
+ /// Third vector to interpolate with (maximum at 1.0f).
+ /// Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector).
+ /// Note that this is the opposite direction of interpolation to GetInterpolatedQuadratic() and Interpolate().
+ /// An interpolated vector. This vector is not modified.
+ _REFCLASS_^ GetInterpolatedQuadratic(_REFCLASS_^ v2, _REFCLASS_^ v3, double d)
{
- LIME_ASSERT(other1 != nullptr);
- LIME_ASSERT(other2 != nullptr);
+ LIME_ASSERT(v2 != nullptr);
+ LIME_ASSERT(v3 != nullptr);
- return gcnew _REFCLASS_(m_NativeValue->getInterpolated_quadratic(*other1->m_NativeValue, *other2->m_NativeValue, d));
+ return gcnew _REFCLASS_(m_NativeValue->getInterpolated_quadratic(*v2->m_NativeValue, *v3->m_NativeValue, d));
}
- _REFCLASS_^ Interpolate(_REFCLASS_^ other1, _REFCLASS_^ other2, double d)
+ ///
+ /// Sets this vector to the linearly interpolated vector between a and b.
+ ///
+ /// First vector to interpolate with, maximum at 1.0f.
+ /// Second vector to interpolate with, maximum at 0.0f.
+ /// Interpolation value between 0.0f (all vector b) and 1.0f (all vector a).
+ /// Note that this is the opposite direction of interpolation to GetInterpolatedQuadratic().
+ /// This vector.
+ _REFCLASS_^ Interpolate(_REFCLASS_^ a, _REFCLASS_^ b, double d)
{
- LIME_ASSERT(other1 != nullptr);
- LIME_ASSERT(other2 != nullptr);
+ LIME_ASSERT(a != nullptr);
+ LIME_ASSERT(b != nullptr);
- m_NativeValue->interpolate(*other1->m_NativeValue, *other2->m_NativeValue, d);
- return gcnew _REFCLASS_(*m_NativeValue);
+ m_NativeValue->interpolate(*a->m_NativeValue, *b->m_NativeValue, d);
+ return this;
}
+ ///
+ /// Check if this vector interpreted as a point is on a line between two other points.
+ /// It is assumed that the point is on the line.
+ ///
+ /// Beginning vector to compare between.
+ /// Ending vector to compare between.
+ /// True if this vector is between begin and end, false if not.
bool IsBetweenPoints(_REFCLASS_^ begin, _REFCLASS_^ end)
{
LIME_ASSERT(begin != nullptr);
@@ -199,25 +297,40 @@
return m_NativeValue->isBetweenPoints(*begin->m_NativeValue, *end->m_NativeValue);
}
+ ///
+ /// Normalizes the vector.
+ /// In case of the 0 vector the result is still 0, otherwise the length of the vector will be 1.
+ ///
+ /// This vector after normalization.
_REFCLASS_^ Normalize()
{
m_NativeValue->normalize();
- return gcnew _REFCLASS_(*m_NativeValue);
+ return this;
}
// properties
+ ///
+ /// Squared length of the vector.
+ /// This is useful because it is much faster than Length.
+ ///
property _WRAPTYPE_ LengthSQ
{
_WRAPTYPE_ get() { return m_NativeValue->getLengthSQ(); }
}
+ ///
+ /// X coordinate of the vector.
+ ///
property _WRAPTYPE_ X
{
_WRAPTYPE_ get() { return m_NativeValue->X; }
void set(_WRAPTYPE_ value) { m_NativeValue->X = value; }
}
+ ///
+ /// Y coordinate of the vector.
+ ///
property _WRAPTYPE_ Y
{
_WRAPTYPE_ get() { return m_NativeValue->Y; }
@@ -230,4 +343,4 @@
: Lime::NativeValue<_WRAPCLASS_>(true)
{
m_NativeValue = new _WRAPCLASS_(other);
- }
\ No newline at end of file
+ }