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 + }