BearishSun 8 лет назад
Родитель
Сommit
0f35b1f2cb

+ 13 - 7
Documentation/GitHub/roadmap.md

@@ -1,7 +1,5 @@
 # Roadmap
 
-[Detailed task list] (https://trello.com/b/w6CyYY37/banshee-3d)
-
 We are currently focusing on finish up a final set of features before releasing 1.0 stable. These features are:
  - Physically based renderer
  - Linux/Mac ports
@@ -10,18 +8,24 @@ Planned for Q2 2017 release
 
 ---------------------------------------------------
 
-There are many more features planned, but these are without a specific timeline or order:
+Following 1.0 release the focus will be on following features (in no specific order): 
+ - Sprites & 2D rendering
+ - 2D physics (Box2D integration)
+ - 2D animation (Sprite based at least, likely bones as well)
  - Mobile render API (likely Vulkan, possibly Metal for iOS)
  - Android/iOS/WP ports
  - High level networking (replication, RPCs)
+ - Effects/Particle editor
+ - Terrain system
+ - Unified shading language
+ - Visual GUI editor 
+ 
+And more to come after that:
  - Dynamic global illumination (+ other high fidelity graphical improvements)
  - Occlussion culling
- - Terrain
- - Effects/Particle editor
  - AI (pathfinding, navmesh)
  - VR support
  - Cinematics editor
- - Unified shading language
  - Visual shader editor
  - More specialized editor tools for 2D games
  - Script debugging
@@ -33,4 +37,6 @@ There are many more features planned, but these are without a specific timeline
  
 Implementation times for each of those roughly ranges from 1-4 months.
 
-More contributors mean we can add more of these features quicker. Consider contributing!
+---------------------------------------------------
+
+[Detailed task list] (https://trello.com/b/w6CyYY37/banshee-3d)

+ 9 - 0
Documentation/Manuals/Native/User/advancedAnimation.md

@@ -0,0 +1,9 @@
+CAnimation
+ -> sample
+ -> blendAdditive
+ -> blend1D
+ -> blend2D
+ -> blendAdditive
+ -> crossFade
+ -> setState
+ -> stop(layer)

+ 99 - 0
Documentation/Manuals/Native/User/animation.md

@@ -0,0 +1,99 @@
+Playing animation				{#animation}
+===============
+
+Animation playback is handled through the @ref bs::CAnimation "Animation" component. This component must be attached to the same **SceneObject** as the **Renderable** of the object we wish to animate.
+
+~~~~~~~~~~~~~{.cpp}
+HSceneObject animRenderableSO = SceneObject::create("Animated 3D object");
+animRenderableSO->addComponent<CRenderable>();
+// ...set up renderable mesh and material...
+
+animation = animRenderableSO->addComponent<CAnimation>();
+~~~~~~~~~~~~~
+
+# Playback
+To start animation playback simply call @ref bs::CAnimation::play "CAnimation::play()", with the **AnimationClip** you wish to play as the parameter.
+
+~~~~~~~~~~~~~{.cpp}
+animation->play(animationClip);
+~~~~~~~~~~~~~
+
+To stop playback call @ref bs::CAnimation::stopAll "CAnimation::stopAll()".
+
+~~~~~~~~~~~~~{.cpp}
+animation->stopAll();
+~~~~~~~~~~~~~
+
+To check if animation is currently playing call @ref bs::CAnimation::isPlaying "CAnimation::isPlaying()".
+
+~~~~~~~~~~~~~{.cpp}
+if(animation->isPlaying())
+	gDebug().logDebug("Animation is playing!");
+~~~~~~~~~~~~~
+
+You can control the speed of the playback through @ref bs::CAnimation::setSpeed "CAnimation::setSpeed()". The default value is 1, which represents normal speed, while lower values slow down playback accordingly (e.g. 0.5 is half speed) and higher values speed it up (2 is double speed). You can change animation speed during or before you start playing a clip.
+
+~~~~~~~~~~~~~{.cpp}
+animation->setSpeed(2.0f);
+~~~~~~~~~~~~~
+
+Finally, you can decide what happens when the animation clip reaches the end. By calling @ref bs::CAnimation::setWrapMode "CAnimation::setWrapMode()" with the parameter of type @ref bs::AnimWrapMode "AnimWrapMode" you can choose:
+ - @ref bs::AnimWrapMode::Clamp "AnimWrapMode::Clamp" - Once the end is reached the animation will stop.
+ - @ref bs::AnimWrapMode::Loop "AnimWrapMode::Loop" - Once the end is reached the animation will loop back to the beginning, and continue to do so indefinitely, until manually stopped.
+ 
+~~~~~~~~~~~~~{.cpp}
+animation->setWrapMode(AnimWrapMode::Loop);
+~~~~~~~~~~~~~
+
+## Play on wake
+Aside from starting playback manually, you can also tell the animation component to start playing animation as soon as its component is instantiated. This can be useful for animations permanently part of the game level, so they can start playback as soon as the level is loaded.
+
+To do this call @ref bs::CAnimation::setDefaultClip "CAnimation::setDefaultClip()". The system will then keep a permanent reference to the animation clip, and automatically play it whenever the component is instantiated.
+
+~~~~~~~~~~~~~{.cpp}
+animation->setDefaultClip(animationClip);
+~~~~~~~~~~~~~
+
+# Morph shapes
+Both skeletal and morph shape animation playback is handled as we described above. However with morph shapes there is an additional option to consider, concering morph channels. Morph shape animation consists out of one or multiple *morph channels*, each channel can have one or multiple *morph shapes*. A single shape is simply a mesh in a certain pose (i.e. shape).
+
+For example, a morph animation of a raindrop splashing on the ground would have a single channel, and multiple shapes, each shape representing one shape of the raindrop as it splashes. For such animations no additional tweaking is necessary, as the interpolation between the different shapes is done by the animation clip.
+
+But when a morph animation has multiple channels, you must manually control which channels are visible by calling @ref bs::CAnimation::setMorphChannelWeight "CAnimation::setMorphChannelWeight()". The weight should be in [0, 1] range, where channels with 0 weight with not be visible at all, and ones with weight 1 will be fully visible. Multiple channels with non-zero weights will be added together to form the final animation.
+
+~~~~~~~~~~~~~{.cpp}
+// Disable channel 0 and 2, fully enable channel 1
+animation->setMorphChannelWeight(0, 0.0f);
+animation->setMorphChannelWeight(1, 1.0f);
+animation->setMorphChannelWeight(2, 0.0f);
+~~~~~~~~~~~~~
+
+Multiple channels are particularily useful for things like facial animation. In such cases you would have one channel for each facial expression, and then modify their weights depending on what is the character feeling or saying. Such channels would also most likely only have a single shape per channel (but don't have to).
+
+You can find out how many channels a morph shape animation has by retrieving a @ref bs::MorphShapes "MorphShapes" object from **Mesh** by calling @ref bs::Mesh::getMorphShapes "Mesh::getMorphShapes()". Use @ref bs::MorphShapes::getNumChannels "MorphShapes::getNumChannels()" to get the channel count, and @ref bs::MorphShapes::getChannel "MorphShapes::getChannel()" to retrieve information about a channel in the form of @ref bs::MorphChannel "MorphChannel".
+
+~~~~~~~~~~~~~{.cpp}
+// Assuming we have a mesh imported with morph shapes
+SPtr<MorphShapes> morphShapes = mesh->getMorphShapes();
+
+UINT32 numChannels = morphShapes->getNumChannels();
+for(UINT32 i = 0; i < numChannels; i++)
+{
+	SPtr<MorphChannel> channel = morphShapes->getChannel(i);
+	gDebug().logDebug("Found morph channel: " + channel->getName());
+}
+~~~~~~~~~~~~~
+
+# Mesh culling
+Normally, when objects are about to be rendered, the system tries to detect if an object is in view of the camera or not. This ensures that the GPU doesn't waste time on objects that are certain not to be visible. For the purposes of culling the system uses an approximation of the mesh to be rendered, in the form of its bounding box. This is efficient because that bounding box can be pre-calculated, stored and then easily checked for visibility.
+
+But with animation the object is constantly transforming, and it is not efficient to re-calculate the bounding box with each new frame of the animation. The system then instead uses the same bounding box it would have used if the object is static. This means that if the animated object's mesh ever leaves the bounds of that box, the system could decide to cull the object, even though some part of it is still visible. This can result in noticeable graphical artifacts, but Banshee provides a way to fix the issue by providing your own bounds.
+
+By providing your own bounding box, you can ensure the box is large enough to cover the entire range of motion of the animation, so that mesh at no point can leave it. This ensures no incorrect culling will happen. To do this you must first enable custom bounds by calling @ref bs::CAnimation::setUseBounds "CAnimation::setUseBounds()", followed by setting the actual bounds though @ref bs::CAnimation::setBounds "CAnimation::setBounds()".
+
+~~~~~~~~~~~~~{.cpp}
+animation->setUseBounds(true);
+
+AABox customBounds(Vector3(-1, -1, -1), Vector3(1, 1, 1));
+animation->setBounds(customBounds);
+~~~~~~~~~~~~~

+ 364 - 0
Documentation/Manuals/Native/User/math.md

@@ -0,0 +1,364 @@
+Math					{#mathUtilities}
+===============
+
+General purpose math functionality in Banshee is provided through the @ref bs::Math "Math" class. It provides a variety of familiar methods, such as @ref bs::Math::floor "Math::floor()", @ref bs::Math::clamp "Math::clamp()", @ref bs::Math::cos "Math::cos()" and many others. Check the API reference for a full list.
+
+All other math functionality is provided through specific types, as listed below.
+
+# Vectors
+Vectors are represented by @ref bs::Vector2 "Vector2", @ref bs::Vector3 "Vector3" and @ref bs::Vector4 "Vector4" classes. All classes come with a full range of operators so manipulating vectors is easy.
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 a(0.0f, 10.0f, 20.0f);
+Vector3 b(-1.0f, -2.0f, -3.0f);
+
+Vector3 c = a + b;
+Vector3 d = b - a;
+Vector3 scaled = a * 3.0f;
+~~~~~~~~~~~~~
+
+They also come with a variety of helpful methods, and some of the more useful ones are:
+ - @ref bs::Vector3::dot "Vector3::dot()" - Dot product
+ - @ref bs::Vector3::cross "Vector3::cross()" - Cross product
+ - @ref bs::Vector3::normalize "Vector3::normalize()" - Normalizes the vector
+ - @ref bs::Vector3::length "Vector3::length()" - Returns the length of the vector
+ - @ref bs::Vector3::distance "Vector3::distance()" - Returns the distance between two vectors
+ 
+And many more as listed on their API reference pages.
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 cross = a.cross(b);
+float dotProduct = a.dot(b);
+float length = a.length();
+~~~~~~~~~~~~~
+
+## Integer vectors
+Integer 2D vector type is also provided as @ref bs::Vector2I "Vector2I". It also supports a full range of operators and comes with a few helper methods. Higher level integer vector types can also be created in the form of @ref bs::VectorNI<T> "bs::VectorNI<T>".
+
+~~~~~~~~~~~~~{.cpp}
+Vector2I intVec(0, 10);
+~~~~~~~~~~~~~
+
+# Angles
+Angles are represented using either @ref bs::Degree "Degree" or @ref bs::Radian "Radian" classes. They accept a raw floating point value, which they expect to be in degrees or radians, respectively. Once created the system automatically converts between the two.
+
+~~~~~~~~~~~~~{.cpp}
+Degree myAngle(90.0f);
+Radian myAngle2 = myAngle;
+
+void printAngle(Degree angle)
+{
+	float angleValue = angle.valueDegrees();
+	gDebug().logDebug("Angle is " + toString(angleValue));
+}
+
+// Caller doesn't need to care if the method accepts radians or degrees
+printAngle(myAngle2);
+~~~~~~~~~~~~~
+
+# Quaternions
+@ref bs::Quaternion "Quaternion"%s are the primary way of representing rotations in Banshee. They can be created using Euler angles, axis/angle combination, or from a rotation matrix (talked about later). 
+
+~~~~~~~~~~~~~{.cpp}
+// Quaternion that rotates 30 degrees around X axis, followed by 50 degrees around Z axis (Euler angle representation)
+Quaternion a(Degree(30), 0, Degree(50));
+
+// Quaternion that rotates 40 degrees around Y axis (axis/angle representation)
+Quaternion b(Vector3::UNIT_Y, Degree(40));
+
+// Quaternion initialized from a rotation matrix
+Matrix3 someMatrix = ...;
+Quaternion c(someMatrix);
+~~~~~~~~~~~~~
+
+Once created quaternion can be used to apply rotation to a 3D vector by calling @ref bs::Quaternion::rotate "Quaternion::rotate()".
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 myVector(1, 0, 0);
+Vector3 rotatedVector = b.rotate(myVector);
+~~~~~~~~~~~~~
+
+Rotations can be combined by multiplying the quaternions.
+
+~~~~~~~~~~~~~{.cpp}
+// Quaternion that applies rotation b, followed by rotation a
+Quaternion combination = a * b;
+~~~~~~~~~~~~~
+
+Inverse of a rotation can be obtained by calling @ref bs::Quaternion::inverse "Quaternion::inverse()".
+~~~~~~~~~~~~~{.cpp}
+// Quaternion that rotates 40 degrees around Y axis
+Quaternion quat(Degree(40), Vector3::UNIT_Y);
+
+// Quaternion that rotates 40 degrees around Y axis, in opposite direction
+Quaternion invQuat = quat.inverse();
+~~~~~~~~~~~~~
+
+Quaternions only make sense for rotations if they are normalized. If you're doing many operations with them, due to precision issues they might become un-normalized. In such cases you can call @ref bs::Quaternion::normalize "Quaternion::normalize()" to re-normalize them.
+
+~~~~~~~~~~~~~{.cpp}
+quat.normalize();
+~~~~~~~~~~~~~
+
+You can transform a quaternion back to a more familiar form using one of these methods:
+ - @ref bs::Quaternion::toEulerAngles "Quaternion::toEulerAngles()"
+ - @ref bs::Quaternion::toAxisAngle "Quaternion::toAxisAngle()"
+ - @ref bs::Quaternion::toRotationMatrix "Quaternion::toRotationMatrix()"
+ 
+~~~~~~~~~~~~~{.cpp}
+Radian xAngle, yAngle, zAngle;
+quat.toEulerAngles(xAngle, yAngle, zAngle);
+
+Radian angle;
+Vector3 axis;
+quat.toAxisAngle(axis, angle);
+
+Matrix3 rotationMat;
+quat.toRotationMatrix(rotationMat);
+~~~~~~~~~~~~~
+
+## Other useful methods
+
+Often you want to rotate towards a certain direction, for example making a camera look towards something. You can create such rotation by calling @ref bs::Quaternion::lookRotation "Quaternion::lookRotation()".
+
+~~~~~~~~~~~~~{.cpp}
+Quaternion q;
+
+// Look towards negative z axis
+q.lookRotation(-Vector3::UNIT_Z);
+~~~~~~~~~~~~~
+
+You can interpolate between using two quaternions using @ref bs::Quaternion::lerp "Quaternion::lerp()" and @ref bs::Quaternion::slerp "Quaternion::slerp()". The first method offers normal linear interpolation, and the second method offers a specialized form of interpolation possible only with quaternions, called spherical interpolation. Spherical interpolation is special because it doesn't change the magnitude of the quaternion (i.e. the interpolation happens on a surface of a sphere), while linear interpolation might require a quaternion to be re-normalized after interpolating. On the other hand linear interpolation requires less CPU cycles to execute.
+
+~~~~~~~~~~~~~{.cpp}
+Quaternion interpVal0 = Quaternion::lerp(0.5f, a, b);
+interpVal0.normalize();
+
+Quaternion interpVal1 = Quaternion::slerp(0.5f, a, b);
+~~~~~~~~~~~~~
+
+Sometimes you have two vectors and want to find a rotation that rotates the first vector into the position of the second. You can do that by using @ref bs::Quaternion::getRotationFromTo "Quaternion::getRotationFromTo()".
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 from(0.0f, 1.0f, 0.0f);
+Vector3 to(1.0f, 0.0f, 0.0f);
+
+// Generates a rotation that rotates from a vector pointing towards positive Y axis, to a vector pointing towards positive X axis. Essentially creates a 90 degree rotation around the Z axis.
+Quaternion quat = Quaternion::getRotationFromTo(from, to);
+~~~~~~~~~~~~~
+
+You can find out the rotation axes of a quaternion by calling @ref bs::Quaternion::xAxis "Quaternion::xAxis()", @ref bs::Quaternion::yAxis "Quaternion::yAxis()" or @ref bs::Quaternion::zAxis "Quaternion::zAxis()". For example you can use this to find the direction in which a quaternion is facing.
+
+~~~~~~~~~~~~~{.cpp}
+// Assuming we consider the Z axis the facing direction
+Vector3 dir = quat.zAxis();
+~~~~~~~~~~~~~
+
+# Matrices
+
+Matrices can be split into two major types: @ref bs::Matrix3 "Matrix3" representing a 3x3 matrix and @ref bs::Matrix4 "Matrix4" representing a 4x4 matrix. 3x3 matrices are used primarily for representing rotations, and are used similarly to quaternions. 4x4 matrices are used to represent a complete set of transformations like scale, translation and rotation, and are the most commonly used matrix type. We also provide a generic @ref bs::MatrixNxM<N, M> "MatrixNxM<N, M>" template for other matrix sizes, but they come with much simpler functionality.
+
+## Matrix3
+**Matrix3** can be initialized using Euler angles, axis/angle combination, or from a quaternion. It can also accept a scale factor as well as rotation.
+
+~~~~~~~~~~~~~{.cpp}
+// Matrix that rotates 30 degrees around X axis, followed by 50 degrees around Z axis (Euler angle representation)
+Matrix3 a(Degree(30), 0, Degree(50));
+
+// Matrix that rotates 40 degrees around Y axis (axis/angle representation)
+Matrix3 b(Vector3::UNIT_Y, Degree(40));
+
+// Matrix initialized from a quaternion
+Quaternion someQuat = ...;
+Matrix3 c(someQuat);
+
+// Matrix initialized from a quaternion, but also does scaling along with rotation
+Vector3 scale(1.0f, 0.5f, 2.0f);
+Matrix3 d(someQuat, scale);
+~~~~~~~~~~~~~
+
+To apply a matrix transformation to a 3D vector call @ref bs::Matrix3::transform "Matrix3::transform()".
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 myVector(1, 0, 0);
+Vector3 transformedVector = b.transform(myVector);
+~~~~~~~~~~~~~
+
+Matrices can be multiplied to combine their transformations.
+
+~~~~~~~~~~~~~{.cpp}
+// Creates a matrix that first applies transformation of matrix "a", followed by transformation of matrix "b"
+Matrix3 combination = b * a;
+~~~~~~~~~~~~~
+
+Matrices can be transposed (switching rows/columns) by calling @ref bs::Matrix3::transpose "Matrix3::transpose()".
+
+~~~~~~~~~~~~~{.cpp}
+Matrix3 mat(Vector3::UNIT_Y, Degree(40));
+Matrix3 transpose = mat.transpose();
+~~~~~~~~~~~~~
+
+Matrices can be inverted by calling @ref bs::Matrix3::inverse "Matrix3::inverse()". Not all matrices have an inverse therefore this method returns a boolean which returns true if an inverse was found.
+
+~~~~~~~~~~~~~{.cpp}
+Matrix3 inverseMat;
+if(mat.inverse(inverseMat))
+	gDebug().logDebug("Inverse found!");
+~~~~~~~~~~~~~
+
+You can decompose a matrix back into rotation & scale components by calling @ref bs::Matrix3::decomposition "Matrix3::decomposition()". Note that this is only able to work if the matrix contains rotation and/or uniform scale, without any other transformations. Otherwise returned values will likely not be accurate.
+
+~~~~~~~~~~~~~{.cpp}
+Quaternion rotation;
+Vector3 scale;
+mat.decomposition(rotation, scale);
+~~~~~~~~~~~~~
+
+If the matrix contains only rotation you can also use any of the following methods to extract it:
+ - @ref bs::Matrix3::toEulerAngles "Matrix3::toEulerAngles()"
+ - @ref bs::Matrix3::toAxisAngle "Matrix3::toAxisAngle()"
+ - @ref bs::Matrix3::toQuaternion "Matrix3::toQuaternion()"
+ 
+~~~~~~~~~~~~~{.cpp}
+Radian xAngle, yAngle, zAngle;
+mat.toEulerAngles(xAngle, yAngle, zAngle);
+
+Radian angle;
+Vector3 axis;
+mat.toAxisAngle(axis, angle);
+
+Quaternion quat;
+mat.toQuaternion(quat);
+~~~~~~~~~~~~~ 
+ 
+## Matrix4
+
+**Matrix4** can be initialized using any of the following static methods:
+ - @ref bs::Matrix4::rotation "Matrix4::rotation()" - Creates a matrix containing only rotation, from a quaternion.
+ - @ref bs::Matrix4::translation "Matrix4::translation()" - Creates a matrix containing only translation.
+ - @ref bs::Matrix4::scaling "Matrix4::scaling()" - Creates a matrix containing only scale.
+ - @ref bs::Matrix4::TRS "Matrix4::TRS()" - Creates a matrix containing translation, rotation and scale. Scale is applied first, followed by rotation and finally translation.
+ 
+~~~~~~~~~~~~~{.cpp}
+Quaternion rotation(Degree(90), Degree(0), Degree(0));
+Matrix4 rotMat = Matrix4::rotation(rotation);
+
+Vector3 translation(0.0f, 50.0f, 0.0f);
+Matrix4 transMat = Matrix4::translation(translation);
+
+Vector3 scale(1.0f, 1.0f, 2.0f);
+Matrix4 scaleMat = Matrix4::scaling(scale);
+
+Matrix4 combinedMat = Matrix4::TRS(translation, rotation, scale);
+~~~~~~~~~~~~~
+ 
+To apply a matrix transformation to a 4D vector you can call @ref bs::Matrix4::multiply(const Vector4&) const "Matrix4::multiply()".
+
+~~~~~~~~~~~~~{.cpp}
+Vector4 myVector(1, 0, 0, 1);
+Vector4 transformedVector = combinedMat.multiply(myVector);
+~~~~~~~~~~~~~
+
+Not that a vector has its 4th component set to 1. This means the vector is treated as a point, and will be translated by the matrix. If the 4th component was 0, the vector would be treated as a direction instead, and translation would not be applied.
+
+You can also use overriden @ref bs::Matrix4::multiply(const Vector3&) const "Matrix4::multiply()" to multiply a **Vector3**, in which case it is assumed to be a point (4th component is equal to 1). If you instead wish to assume a **Vector3** is a direction, use @ref bs::Matrix4::multiplyDirection "Matrix4::multiplyDirection()" instead.
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 myVector(1, 0, 0);
+Vector3 transformedPoint = combinedMat.multiply(myVector);
+
+// No translation applied (if matrix had any)
+Vector3 transformedDirection = combinedMat.multiplyDirection(myVector);
+~~~~~~~~~~~~~
+
+Matrices can be multiplied to combine their transformations.
+
+~~~~~~~~~~~~~{.cpp}
+// Creates a matrix that first applies transformation of matrix "a", followed by transformation of matrix "b"
+Matrix4 combination = b * a;
+~~~~~~~~~~~~~
+
+Matrices can be transposed (switching rows/columns) by calling @ref bs::Matrix4::transpose "Matrix4::transpose()".
+
+~~~~~~~~~~~~~{.cpp}
+Matrix4 mat(Vector3::UNIT_Y, Degree(40));
+Matrix4 transpose = mat.transpose();
+~~~~~~~~~~~~~
+
+Matrices can be inverted by calling @ref bs::Matrix4::inverse "Matrix4::inverse()". Not all matrices have an inverse therefore this method returns a boolean which returns true if an inverse was found.
+
+~~~~~~~~~~~~~{.cpp}
+Matrix4 inverseMat;
+if(mat.inverse(inverseMat))
+	gDebug().logDebug("Inverse found!");
+~~~~~~~~~~~~~
+
+You can decompose a matrix back into rotation, scale and translation components by calling @ref bs::Matrix4::decomposition "Matrix4::decomposition()". Note that this is only able to work if the matrix contains rotation, translation and uniform scale, without any other transformations. Otherwise returned values will likely not be accurate.
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 translation;
+Quaternion rotation;
+Vector3 scale;
+mat.decomposition(translation, rotation, scale);
+~~~~~~~~~~~~~
+
+# Rays
+@ref bs::Ray "Ray"s are represented using an origin point, and a direction. They are often used in physics for intersection tests.
+
+~~~~~~~~~~~~~{.cpp}
+// Ray with origin at world origin, looking up
+Ray ray(Vector3(0, 0, 0), Vector3(0, 1, 0));
+~~~~~~~~~~~~~ 
+
+You can use @ref bs::Ray::getPoint "Ray::getPoint()" to get a point some distance from ray origin, along the direction.
+
+~~~~~~~~~~~~~{.cpp}
+Vector3 point = ray.getPoint(10.0f);
+~~~~~~~~~~~~~  
+
+Rays can be transformed by matrices by calling @ref bs::Ray::transform "Ray::transform()".
+
+~~~~~~~~~~~~~{.cpp}
+Matrix4 mat = ...;
+ray.transform(mat);
+~~~~~~~~~~~~~  
+
+They also provide a series of *intersects* methods that allow them to test for intersection against axis aligned boxes, spheres, planes and triangles:
+ - @ref bs::Ray::intersects(const AABox&) const "Ray::intersects(const AABox&)" - Axis aligned box intersection
+ - @ref bs::Ray::intersects(const Sphere&) const "Ray::intersects(const Sphere&)" - Sphere intersection
+ - @ref bs::Ray::intersects(const Plane&) const "Ray::intersects(const Plane&)" - Plane intersection
+ - @ref bs::Ray::intersects(const Vector3&, const Vector3&, const Vector3&, const Vector3&, bool, bool) const "Ray::intersects(const Vector3&, const Vector3&, const Vector3&)" - Triangle intersection
+ 
+# Rectangles
+
+@ref bs::Rect2 "Rect2" and @ref bs::Rect2I "Rect2I" structures can be used for storing rectangles using floating point or integer values, respectively. Check their API reference for the methods they support, but in most scenarios you will be using them for storage and method parameters.
+
+# Shapes
+
+Banshee supports a variety of other 3D shapes:
+ - @ref bs::AABox "AABox"
+ - @ref bs::Sphere "Sphere"
+ - @ref bs::Plane "Plane"
+ - @ref bs::Capsule "Capsule"
+ 
+We'll let you deduce how they are used from their API reference, as it should be fairly self explanatory. All of the shapes provide a way be initialized, to be transformed by a world matrix as well a set of intersection tests against rays and other shapes.
+
+~~~~~~~~~~~~~{.cpp}
+// Axis aligned box created from minimum and maximum corners
+Vector3 min(-1.0f, -1.0f, -1.0f);
+Vector3 max(1.0f, 1.0f, 1.0f);
+
+AABox box(min, max);
+
+// Sphere created from center and radius
+Vector3 center(0.0f, 10.0f, 0.0f);
+float radius = 20.0f;
+
+Sphere sphere(center, radius);
+
+// Plane created from normal, and distance from origin along the normal
+Vector3 normal(0.0f, 1.0f, 0.0f);
+float dist = 10.0f;
+
+Plane plane(normal, dist);
+~~~~~~~~~~~~~  

+ 3 - 0
Documentation/Manuals/Native/manuals.md

@@ -54,6 +54,9 @@ Manuals									{#manuals}
  - [Joints](@ref joints)
 - **Animation**
  - [Loading animation clips](@ref animationClip)
+ - [Playing animation](@ref animation)
+ - [Bones](@ref bones)
+ - [Advanced animation](@ref advancedAnimation)
  
 # Developer guides
 

+ 52 - 0
Source/BansheeUtility/Include/BsMath.h

@@ -17,49 +17,100 @@ namespace bs
     class BS_UTILITY_EXPORT Math 
     {
     public:
+		/** Inverse cosine. */
 		static Radian acos(float val);
+
+		/** Inverse sine. */
 		static Radian asin(float val);
+
+		/** Inverse tangent. */
 		static Radian atan(float val) { return Radian(std::atan(val)); }
+
+		/** Inverse tangent with two arguments, returns angle between the X axis and the point. */
 		static Radian atan2(float y, float x) { return Radian(std::atan2(y,x)); }
 
+		/** Cosine. */
         static float cos(const Radian& val) { return (float)std::cos(val.valueRadians()); }
+
+		/** Cosine. */
         static float cos(float val) { return (float)std::cos(val); }
 
+		/** Sine. */
         static float sin(const Radian& val) { return (float)std::sin(val.valueRadians()); }
+
+		/** Sine. */
         static float sin(float val) { return (float)std::sin(val); }
 
+		/** Tangent. */
 		static float tan(const Radian& val) { return (float)std::tan(val.valueRadians()); }
+
+		/** Tangent. */
 		static float tan(float val) { return (float)std::tan(val); }
 
+		/** Square root. */
 		static float sqrt(float val) { return (float)std::sqrt(val); }
+
+		/** Square root. */
         static Radian sqrt(const Radian& val) { return Radian(std::sqrt(val.valueRadians())); }
+
+		/** Square root. */
         static Degree sqrt(const Degree& val) { return Degree(std::sqrt(val.valueDegrees())); }
 
+		/** Square root followed by an inverse. */
 		static float invSqrt(float val);
+
+		/** Returns square of the provided value. */
 		static float sqr(float val) { return val*val; }
 
+		/** Returns base raised to the provided power. */
 		static float pow(float base, float exponent) { return (float)std::pow(base, exponent); }
+
+		/** Returns euler number (e) raised to the provided power. */
 		static float exp(float val) { return (float)std::exp(val); }
 
+		/** Returns natural (base e) logarithm of the provided value. */
 		static float log(float val) { return (float)std::log(val); }
+
+		/** Returns base 2 logarithm of the provided value. */
 		static float log2(float val) { return (float)(std::log(val)/LOG2); }
+
+		/** Returns base N logarithm of the provided value. */
 		static float logN(float base, float val) { return (float)(std::log(val)/std::log(base)); }
 
+		/** Returns the sign of the provided value as 1 or -1. */
 		static float sign(float val);
+
+		/** Returns the sign of the provided value as 1 or -1. */
 		static Radian sign(const Radian& val) { return Radian(sign(val.valueRadians())); }
+
+		/** Returns the sign of the provided value as 1 or -1. */
 		static Degree sign(const Degree& val) { return Degree(sign(val.valueDegrees())); }
 
+		/** Returns the absolute value. */
 		static float abs(float val) { return float(std::fabs(val)); }
+
+		/** Returns the absolute value. */
 		static Degree abs(const Degree& val) { return Degree(std::fabs(val.valueDegrees())); }
+
+		/** Returns the absolute value. */
 		static Radian abs(const Radian& val) { return Radian(std::fabs(val.valueRadians())); }
 
+		/** Returns the nearest integer equal or higher to the provided value. */
 		static float ceil(float val) { return (float)std::ceil(val); }
+
+		/** Returns the nearest integer equal or higher to the provided value. */
 		static int ceilToInt(float val) { return (int)std::ceil(val); }
 
+		/** Returns the integer nearest to the provided value. */
 		static float round(float val) { return (float)std::floor(val + 0.5f); }
+
+		/** Returns the integer nearest to the provided value. */
 		static int roundToInt(float val) { return (int)std::floor(val + 0.5f); }
 
+		/** Returns the nearest integer equal or lower of the provided value. */
 		static float floor(float val) { return (float)std::floor(val); }
+
+		/** Returns the nearest integer equal or lower of the provided value. */
 		static int floorToInt(float val) { return (int)std::floor(val); }
 
 		/** Clamp a value within an inclusive range. */
@@ -77,6 +128,7 @@ namespace bs
 			return std::max(std::min(val, (T)1), (T)0);
 		}
 
+		/** Checks if the value is a valid number. */
 		static bool isNaN(float f)
 		{
 			return f != f;

+ 2 - 2
Source/BansheeUtility/Include/BsSphere.h

@@ -24,13 +24,13 @@ namespace bs
 		{ }
 
         /** Returns the radius of the sphere. */
-        float getRadius(void) const { return mRadius; }
+        float getRadius() const { return mRadius; }
 
         /** Sets the radius of the sphere. */
         void setRadius(float radius) { mRadius = radius; }
 
         /** Returns the center point of the sphere. */
-        const Vector3& getCenter(void) const { return mCenter; }
+        const Vector3& getCenter() const { return mCenter; }
 
         /** Sets the center point of the sphere. */
         void setCenter(const Vector3& center) { mCenter = center; }