= Introduction to Mathematical Functionality :revnumber: 2.1 :revdate: 2020/07/24 It's a fact of life, math is hard. Unfortunately, 3D graphics require a fair bit of knowledge about the subject. Fortunately, jME is able to hide the majority of the details away from the user. Vectors are the fundamental type in the 3D environment, and it is used extensively. Matrices are also a basic necessity of 3D for representing linear systems. xref:core:math/quaternion.adoc[Quaternions] are perhaps the most powerful and complicated of the basic types and are used for rotation in jME. I'll discuss how these are used in the system for the core functionality. Including Transforming, Visibility Determination, Collision Detection, and the Coordinate System. Note, that these are low level details. Further chapters will discuss how to use these various systems from a high level perspective. To get a visual introduction to math in jME3 for the absolute beginner, check out our xref:concepts/math_for_dummies.adoc[Math for Dummies] introduction class. == Coordinate System === Definition A _coordinate system_ consists of an origin (single point in space) and three coordinate axes that are each unit length and mutually perpendicular. The axes can be written as the column of a Matrix, R = [U1|U2|U3]. In fact, this is exactly how CameraNode works. The coordinate system defined by Camera is stored in a Matrix. jME uses a Right-Handed coordinate system (as OpenGL does). The definition of a coordinate system is defined in jME by the properties sent to Camera. There are no error checks to insure that: 1) the coordinate system is right-handed and 2) The axes are mutually perpendicular. Therefore, if the user sets the axes incorrectly, they are going to experience very odd rendering artifacts (random culling, etc). image::concepts/coordinate-system.png[coordinate-system.png,width="235",height="210",align="center"] === Homogenous coordinates Homogenous coordinates have an additional _W_ value tacked on to the end. The XYZ values are to be divided by W to give the true coordinates. This has several advantages, one technical, some relevant to application programmers: Technically, it simplifies some formulae used inside the vector math. For example, some operations need to apply the same factor to the XYZ coordinates. Chain multiple operations of that kind (and vector math tends to do that), and you can save a lot of multiplications by simply keeping the scaling factor around and doing the multiplication to XYZ at the end of the pipeline, in the 3D card (which does accept homogenous coordinates). It also simplifies some formulae, in particular anything that is related to rotations. For application programmers, this means you can express infinitely long vectors that still have a direction - these tend to be used in lighting. Just use a W value of 0.0. == Transformations Transformations define an operation that converts points from one coordinate system to another. This includes translation, rotation and scaling. In jME, local transforms are used to represent the positioning of objects relative to a parent coordinate system. While, world transforms are used to represent the positioning of objects in a global coordinate system. == Visibility Determination Visibility Determination concerns itself with minimizing the amount of data that is sent to the graphics card for rendering. Specifically, we do not want to send data that will not be seen. Data not sent to the graphics card is said to be culled. The primary focus of this section is Frustum Culling based on the Camera's view frustum. In essence, this frustum creates six standard view planes. The BoundingVolume of an object is tested against the frustum planes to determine if it is contained in the frustum. If at any point the object's bounding is outside of the plane, it is tossed out and no longer processed for rendering. This also includes any children that it managed, allowing fast culling of large sections of the scene. === Fundamental Types == ColorRGBA === Definition ColorRGBA defines a color value in the jME library. The color value is made of three components, red, green and blue. A fourth component defines the alpha value (transparent) of the color. Every value is set between [0, 1]. Anything less than 0 will be clamped to 0 and anything greater than 1 will be clamped to 1. *Note:* If you would like to "`convert`" an ordinary RGB value (0-255) to the format used here (0-1), simply multiply it with: 1/255. === jME Class ColorRGBA defines a few static color values for ease of use. That is, rather than: [source,java] ---- ColorRGBA red = new ColorRGBA(1,0,0,1); object.setSomeColor(red); ---- you can simply say: [source,java] ---- object.setSomeColor(ColorRGBA.red) ---- ColorRGBA will also handle interpolation between two colors. Given a second color and a value between 0 and 1, a the owning ColorRGBA object will have its color values altered to this new interpolated color. == Matrix See link:{link-javadoc}/com/jme3/math/Matrix3f.html[Matrix3f Javadoc] and link:{link-javadoc}/com/jme3/math/Matrix4f.html[Matrix4f Javadoc] === Definition A Matrix is typically used as a _linear transformation_ to map vectors to vectors. That is: Y = MX where X is a Vector and M is a Matrix applying any or all transformations (scale, xref:concepts/rotate.adoc[rotate], translate). There are a few special matrices: _zero matrix_ is the Matrix with all zero entries. [cols="3", options="header"] |=== a|0 a|0 a|0 a|0 a|0 a|0 a|0 a|0 a|0 |=== The _Identity Matrix_ is the matrix with 1 on the diagonal entries and 0 for all other entries. [cols="3", options="header"] |=== a|1 a|0 a|0 a|0 a|1 a|0 a|0 a|0 a|1 |=== A Matrix is _invertible_ if there is a matrix _M^-1^_ where _MM^-1^ = M^-1^M = I_. The _transpose_ of a matrix _M = [m~ij~]_ is _M^T^ = [m~ji~]_. This causes the rows of _M_ to become the columns of _M^T^_. [cols="7", options="header"] |=== a|1 a|1 a|1 > objects that represent the three points of the triangle. These can be retrieved via the `get` method. The `get` method, obtains the point based on the index provided. Similarly, the values can be set via the `set` method. === Example 1 - Creating a Triangle [source,java] ---- //the three points that make up the triangle Vector3f p1 = new Vector3f(0,1,0); Vector3f p2 = new Vector3f(1,1,0); Vector3f p3 = new Vector3f(0,1,1); Triangle t = new Triangle(p1, p2, p3); ---- ==== Tips and Tricks == How do I get height/width of a spatial? Cast the spatial to com.jme3.bounding.BoundingBox to be able to use getExtent(). [source,java] ---- Vector3f extent = ((BoundingBox) spatial.getWorldBound()).getExtent(new Vector3f()); float x = ( (BoundingBox)spatial.getWorldBound()).getXExtent(); float y = ( (BoundingBox)spatial.getWorldBound()).getYExtent(); float z = ( (BoundingBox)spatial.getWorldBound()).getZExtent(); ---- == How do I position the center of a Geometry? [source,java] ---- geo.center().move(pos); ----