{"id":263,"date":"2017-07-23T00:42:47","date_gmt":"2017-07-23T00:42:47","guid":{"rendered":"https:\/\/castle-engine.sourceforge.io\/wp\/?p=263"},"modified":"2017-11-17T00:51:25","modified_gmt":"2017-11-17T00:51:25","slug":"new-modern-api-for-vectors-and-matrices","status":"publish","type":"post","link":"https:\/\/castle-engine.io\/wp\/2017\/07\/23\/new-modern-api-for-vectors-and-matrices\/","title":{"rendered":"New modern API for vectors and matrices"},"content":{"rendered":"<table class=\"thumbnails thumbnails-align-right\"><tr><td>\n          <a href=\"https:\/\/castle-engine.io\/wp\/wp-content\/uploads\/2017\/07\/chinchilla.wrl_0.png\"\n             class=\"screenshot\"\n             title=\"Chinchilla model in X3D, based on high-poly version in &amp;quot;Big Buck Bunny&amp;quot;\"><img loading=\"lazy\" decoding=\"async\"\n            style=\"float: right\"\n            src=\"https:\/\/castle-engine.io\/wp\/wp-content\/uploads\/2017\/07\/chinchilla.wrl_0-200x113.png\"\n             width=\"200\" height=\"113\" \n            alt=\"Chinchilla model in X3D, based on high-poly version in &amp;quot;Big Buck Bunny&amp;quot;\"\n          ><\/a><\/td><\/tr><\/table>\n<p>Our unit <a href=\"https:\/\/michalis.ii.uni.wroc.pl\/cge-www-preview\/apidoc\/html\/CastleVectors.html\">CastleVectors<\/a> was completely reworked this week, and it now features a new, comfortable API for vector and matrix types, using <i>&#8220;advanced records&#8221;<\/i> (records with methods).<\/p>\n<p>I hope that you like the changes \ud83d\ude42 Of course <a href=\"https:\/\/github.com\/castle-engine\/castle-engine\/\">you can already test it all by using the engine version from GitHub<\/a> !<\/p>\n<h2>Type names<\/h2>\n<p>The main vector and matrix types (using Single-precision) are now called <code>TVector2<\/code>, <code>TVector3<\/code>, <code>TVector4<\/code> (in short: <code>TVector{2,3,4}<\/code>) and <code>TMartix{2,3,4}<\/code>. So we have 2D, 3D and 4D vectors (4D vectors are useful for <i>&#8220;homogeneous coordinates&#8221;<\/i> in 3D, and to store colors with alpha). And we have 2&#215;2, 3&#215;3, 4&#215;4 matrices.<\/p>\n<p>These correspond to previous array-based types called <code>TVector{2,3,4}Single<\/code> and <code>TMatrix{2,3,4}Single<\/code>. As you can see, we have removed the <code>Single<\/code> suffix, as these types are used very often throughout the engine and, as such, they are our <i>&#8220;default&#8221;<\/i> vector and matrix types.<\/p>\n<p>As before, we also feature vectors with Double precision (<code>TVector{2,3,4}Double<\/code>), and based on various integer types (<code>Byte<\/code>, <code>Integer<\/code> and <code>Cardinal<\/code>). They are all available in 2D, 3D, 4D variants, and are implented using the new <i>&#8220;advanced records approach&#8221;<\/i> and are consistent with Single-precision vectors.<\/p>\n<h2>Features<\/h2>\n<ul>\n<li>\n<p>As these types are <i>&#8220;advanced records&#8221;<\/i>, they include various methods, class methods and constants nicely grouped within the record. This makes the API look nicer, e.g. now you can write <code>MyVector.Length<\/code> instead of <code>VectorLen(MyVector)<\/code>. They have one field, <code>Data<\/code>, which is defined like <code>array [0..2] of Single<\/code> for <code>TVector3<\/code>. This allows to keep them fast (in terms of speed, and memory layout). <a href=\"https:\/\/michalis.ii.uni.wroc.pl\/cge-www-preview\/apidoc\/html\/CastleVectorsInternalSingle.TGenericVector3.html\">See the documentation of the generic 3D vector (this API is used by both TVector3 and TVector3Double)<\/a>.<\/p>\n<li>\n<p>You can access the individual components of the vector as <code>V.X<\/code>, <code>V[0]<\/code> or <code>V.Data[0]<\/code>. And the last two notations are checked, even at compile-time, so this will make a clear warning (that index is 3, but should be between 0..2):<\/p>\n<pre>\r\nuses CastleVectors;\r\nvar\r\n  V: TVector3;\r\nbegin\r\n  V[3] := 123; \/\/ incorrect example, index should be in 0..2 !\r\nend.\r\n<\/pre>\n<li>\n<p>All the operators, like <code>+<\/code> and <code>*<\/code>, are overloaded on vectors and matrices. Just like with old types.<\/p>\n<li>\n<p>These types work in both FPC and Delphi. They work without the FPC macros (as Delphi doesn&#8217;t support them). I wish they could use generics, but they cannot (it&#8217;s not possible to put constraints on Pascal generics to enable efficient arithmetic operations on fields).<\/p>\n<li>\n<p>Along with it, triangles (<code>TTriangle{2,3,4}<\/code>) was also remodelled as a record, and the Double-precision equivalent (<code>TTriangle3Double<\/code>) was removed (not really useful, and implementing it without macros or generics is uneasy). <a href=\"https:\/\/michalis.ii.uni.wroc.pl\/cge-www-preview\/apidoc\/html\/CastleTriangles.TTriangle3.html\">See TTriangle3 documentation<\/a>.<\/p>\n<li>\n<p>Along with it, the <code>TBox3D<\/code> was a bit improved, it now has <code>Min<\/code> and <code>Max<\/code> properties, that look friendlier than <code>Data[0]<\/code> and <code>Data[1]<\/code>. <a href=\"https:\/\/michalis.ii.uni.wroc.pl\/cge-www-preview\/apidoc\/html\/CastleBoxes.TBox3D.html\">See TBox3D documentation<\/a>.<\/p>\n<li>\n<p>Along with it,  the color types have changed too, as <code>TCastleColor<\/code> and <code>TCastleColorRGB<\/code> are still just aliases for (respectively) <code>TVector4<\/code> and <code>TVector3<\/code>. See <a href=\"https:\/\/michalis.ii.uni.wroc.pl\/cge-www-preview\/apidoc\/html\/CastleColors.html\">CastleColors unit documentation<\/a>.<\/p>\n<li>\n<p>The new vectors vaguely resemble <a href=\"http:\/\/docwiki.embarcadero.com\/Libraries\/Tokyo\/en\/System.Math.Vectors\">the vectors from Delphi standard unit System.Math.Vectors<\/a>, but are better in many ways. We offer many more types and with many more methods. And, frankly, our naming is more consistent, IMHO \ud83d\ude42\n<\/ul>\n<h2>Backward compatibility<\/h2>\n<p><b>While the change is for good, it is not 100% backward-compatible<\/b>. I put a lot of effort to minimize the compatibility &#8220;disruption&#8221;, adding many &#8220;glue&#8221; functions and types to keep your existing code working (and merely warn about being &#8220;deprecated&#8221; during compilation). But there is still chance that you will need to change something in your code to make it compile with the engine >= 6.3 API. Read the hints below, and please <a href=\"https:\/\/sourceforge.net\/p\/castle-engine\/discussion\/general\/\">ask on the forum<\/a> if you&#8217;re unsure how to upgrade.<\/p>\n<p>The changes that break compatibility (things that you will <i>have<\/i> to change in your code in order to compile):<\/p>\n<ul>\n<li>\n<p>When declaring constants, your old code may use this:<\/p>\n<pre>const MyConstant: TVector2Single = (1.0, 2.0); \/\/ old code<\/pre>\n<p>As the vectors, matrices, colors and triangles are now record types with a <code>Data<\/code> field, so it has to be changed to:<\/p>\n<pre>const MyConstant: TVector2Single = (Data: (1.0, 2.0));<\/pre>\n<li>\n<p>The <code>TBox3D.Data<\/code>, and your custom <code>array of TVectorXxx<\/code> types, are no longer <i>&#8220;arrays of arrays&#8221;<\/i>. They are now <i>&#8220;arrays of records&#8221;<\/i>. Your old code may use this:<\/p>\n<pre>Box.Data[0, 0] := 0.0; \/\/ old code<\/pre>\n<p>This has to be changed to:<\/p>\n<pre>Box.Data[0][0] := 0.0;<\/pre>\n<p>    <!--p>Or this, using nice names for clarity:<\/p>\n\n\n    \n\n<pre>Box.Min.X := 0.0;<\/pre-->\r\n    <p>Or this, if you want to avoid any &#8220;getter&#8221; properties and just access the (addressable) variable directly:<\/p>\r\n    <pre>Box.Data[0].Data[0] := 0.0;<\/pre>\n\n    \n\n  \n\n<li>\n\n<p>Although you can still access the vector component using <code>V[0]<\/code>, this is now a &#8220;getter&#8221; property. It often doesn&#8217;t matter&#8230; unless you want to use it as <code>var<\/code> or <code>out<\/code> parameter for some function, or if you use C-like operators like <code>+=<\/code>. So if your old code has this:\n     \n\n<pre>V[0] += 10; \/\/ old code<\/pre>\n\n\n     \n\n<p>This has to be changed to this:<\/p>\n\n\n     \n\n<pre>V.Data[0] += 10;<\/pre>\n\n\n     \n\n<p>Of course, in this case you can also just resign from using C-like operators, and have this:<\/p>\n\n\n     \n\n<pre>V[0] := V[0] + 10;<\/pre>\n\n\n     \n\n<p>Or this:\n     \n\n<pre>V.X := V.X + 10;<\/pre>\n\n\n<\/ul>\n\n\n\nSidenote: I tried a different approach to backward-compatibility too (keeping both old and new APIs in parallel) but this was creating more compatibility problems than it was solving (gory details in the <cpde>KEEP_OLD_VECTOR_API<\/code> comments in <a href=\"https:\/\/github.com\/castle-engine\/castle-engine\/commit\/c3e6836f9b3fb3ad10610c0be5b064b3def43408\">this commit<\/a>).\n\n\n\n<p>Have fun with the new API, and, as always, please <a href=\"https:\/\/sourceforge.net\/p\/castle-engine\/discussion\/general\/\">ask on the forum<\/a> if you have any questions!\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Our unit CastleVectors was completely reworked this week, and it now features a new, comfortable API for vector and matrix types, using &#8220;advanced records&#8221; (records with methods). I hope that you like the changes \ud83d\ude42 Of course you can already test it all by using the engine version from GitHub ! Type names The main &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/castle-engine.io\/wp\/2017\/07\/23\/new-modern-api-for-vectors-and-matrices\/\" class=\"more-link\">Continue reading  \u27a4<span class=\"screen-reader-text\"> &#8220;New modern API for vectors and matrices&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":274,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"publish_to_discourse":"","publish_post_category":"","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"","discourse_permalink":"","wpdc_publishing_response":"","wpdc_publishing_error":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-263","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/castle-engine.io\/wp\/wp-content\/uploads\/2017\/07\/chinchilla.wrl_0.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9IgYW-4f","jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts\/263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/comments?post=263"}],"version-history":[{"count":16,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts\/263\/revisions"}],"predecessor-version":[{"id":361,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts\/263\/revisions\/361"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/media\/274"}],"wp:attachment":[{"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/media?parent=263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/categories?post=263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/tags?post=263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}