{"id":3241,"date":"2022-05-06T18:21:48","date_gmt":"2022-05-06T18:21:48","guid":{"rendered":"https:\/\/castle-engine.io\/wp\/?p=3241"},"modified":"2022-05-06T18:25:05","modified_gmt":"2022-05-06T18:25:05","slug":"camera-and-navigation-rework-almost-finished-todo-this-news-announcement-is-too-long-we-have-too-much-new-stuff-to-announce","status":"publish","type":"post","link":"https:\/\/castle-engine.io\/wp\/2022\/05\/06\/camera-and-navigation-rework-almost-finished-todo-this-news-announcement-is-too-long-we-have-too-much-new-stuff-to-announce\/","title":{"rendered":"Camera and navigation rework almost finished. TODO: This news announcement is too long, we have too much new stuff to announce"},"content":{"rendered":"<table class=\"thumbnails thumbnails-align-right\"><tr><td>\n          <a href=\"https:\/\/castle-engine.io\/wp\/wp-content\/uploads\/2022\/05\/Zrzut-ekranu-z-2022-05-06-20-13-02.png\"\n             class=\"screenshot\"\n             title=\"Camera from Sketchfab in glTF\"><img loading=\"lazy\" decoding=\"async\"\n            style=\"float: right\"\n            src=\"https:\/\/castle-engine.io\/wp\/wp-content\/uploads\/2022\/05\/Zrzut-ekranu-z-2022-05-06-20-13-02-200x113.png\"\n             width=\"200\" height=\"113\" \n            alt=\"Camera from Sketchfab in glTF\"\n          ><\/a><\/td><\/tr><\/table>\n<p>I&#8217;m nearly done with the big amount of changes on <a href=\"https:\/\/github.com\/castle-engine\/castle-engine\/tree\/new-cameras\">new-cameras<\/a> branch. Below is a draft news announcement that <strong>will<\/strong> become official (and more complete) soon!<\/p>\n<p>TODO: This is too long to announce, too many things. And this is not even finished yet, there will be more gains from this in UI.<\/p>\n<p>TODO: Record a movie about this.<\/p>\n<p><b>New features of camera and navigation:<\/b><\/p>\n<ol>\n<li>\n    <strong>During design-time (that is, in CGE editor) you use an internal editor camera and navigation to move around the scene, without automatically changing the camera \/ navigation that will be used later for playing the game.<\/strong><\/p>\n<p>This gives you more flexibility in how you move in the world at design-time, and this gives us more flexibility to implement best navigation at design-time, without worrying what is best for run-time.<\/p>\n<p>In particular<\/p>\n<ul>\n<li>\n<p>Dragging with left mouse button over viewport now doesn&#8217;t change camera. This makes it safer to navigate, as you don&#8217;t accidentally drag transform when you want to change camera, or vice versa, because now they are tied to different mouse buttons.<\/p>\n<li>\n<p>Navigation at design-time is activated by pressing and holding right mouse button over a viewport. This is consistent with various other game engines.<\/p>\n<li>\n<p>Design-time navigation fly mode shortcuts:<\/p>\n<pre>\nChange speed by mouse wheel, as well as + and - keys.\nKeep holding right mouse button to rotate using mouse look.\nNove by ASWD.\nMove down\/up by QE.\n<\/pre>\n<li>\n<p>Also (Viewport menu):<\/p>\n<pre>\nHome to view all\nF to focus selected (a bit like in Unity, yes :) )\n<\/pre>\n<\/ul>\n<li>\n<p><strong>TCastleCamera is now a TCastleTransform descendant<\/strong>, and as such it can be placed on Viewport.Items now.<\/p>\n<p>The current camera should be assigned to Viewport.Camera.<\/p>\n<p>In general Viewport.Camera and adding camera to Viewport.Items are independent actions (it was a mess when we tried to make them too much &#8220;magically&#8221; auto-connected). But<\/p>\n<ul>\n<li>\n<p>for backward-compatibility, camera from old designs is automatically assigned as Viewport.Camera, so old designs just work<\/p>\n<li>\n<p>when creating new viewport from code (but not when deserializing and not at design-time), we add new unnamed camera (as Viewport.Camera, and to Viewport.Items)<\/p>\n<li>\n<p>when creating new viewport in editor (but not when deserializing) we add new named camera (as Viewport.Camera, and to Viewport.Items)\n    <\/ul>\n<li>\n<p><strong>Camera can have children, like any other TCastleTransform.<\/strong><\/p>\n<p>This is nice to place something relative to camera, e.g. <strong>weapon in typical FPS games<\/strong>. <\/p>\n<p>It is also new advised way to make a &#8220;<strong>headlight<\/strong>&#8220;. Just add a light, like TCastleDirectionalLight, as camera child. That&#8217;s it. Leave Viewport.UseHeadlight as hlOff, or UseHeadlight=hlMainScene (default) and leave Viewport.Items.MainScene=nil (default). We don&#8217;t need MainScene, we don&#8217;t need UseHeadlight anymore. This way it is also trivial how to control or adjust the headlight. It&#8217;s just your component, change it freely to another light, remove it, change the light Exists property etc.<\/p>\n<p>The default TCastleDirectionalLight direction is -Z, conveniently, as this is also the direction along which the camera is looking at. So just dropping default TCastleDirectionalLight as a TCastleCamera is all you need.<\/p>\n<p>See examples\/viewport_and_scenes\/headlight\/ for example.<\/p>\n<li>\n<p><strong>Camera can be a child of some other transformation, e.g. you can mount camera on a car, or attach it to a bone of your skeleton.<\/strong><\/p>\n<li>\n<p>You can <strong>create TCastleCamera instances, from code or from editor, and have as many as you need<\/strong>. Just set Viewport.Camera to the current camera. You can set this property freely, also to nil (for consistency, it must be prepared for &#8220;no camera&#8221;, e.g. if you destroy the camera; viewport rendering is not done in this case).<\/p>\n<p>It also auto-synchronizes Viewport.Items.MainCamera with Viewport.Camera, if they were synchronized already. In simple cases (if you don&#8217;t use multiple viewports) Viewport.Items.MainCamera and Viewport.Camera are always synchronized.<\/p>\n<li>\n<p>We display a <strong>preview from selected camera<\/strong>. This way you can reliably move any camera. And you can reliably move things with respect to camera.<\/p>\n<p>You can <strong>pin the preview, make it larger\/smaller<\/strong>, to control and display it as necessary.<\/p>\n<li>\n<p>This also makes the <strong>AnimateTo of cameras<\/strong> more useful.<\/p>\n<p>You can now setup various cameras around the world in editor, and use CurrentCamera.AnimateTo(SomeCamera) to smoothly animate to them.<\/p>\n<li>\n<p>Adding Navigation components (to use at run-time) is no longer &#8220;special&#8221;. <strong>Just use &#8220;Add User Interface -> Navigation\/xxx&#8221; to insert navigation as child of viewport<\/strong>.<\/p>\n<p>No more special menu to do that (that was previously trying to do some needless automatic around it, removing\/adding it to children, removing previous navigation etc.) Also there&#8217;s no longer a need to use TCastleViewport.Navigation. It&#8217;s a deprecated property now, that just adds\/removes children, nothing more.<\/p>\n<p>Also <strong>Navigation Exists works as expected<\/strong>. You can have multiple navigation components within on TCastleViewport, they can even work &#8220;all at once&#8221; but in practice (with current navigation classes) you will want to use Exists to make only one of them active.<\/p>\n<li>\n<p>New property <strong>TCastleNavigation.CheckCollisions<\/strong> is also available.\n<\/ol>\n<p><b>More new features, done BTW:<\/b><\/p>\n<ol>\n<li>\n    Editor improvements: <strong>Smaller gizmos<\/strong><\/p>\n<li>\n<p>Editor improvements: S<strong>how whether whole vector\/color has modified state properly<\/strong>, e.g. see if Translation value is not bold or not<\/p>\n<li>\n<p>glTF interpolators with unique names<\/p>\n<li>\n<p>Inspector on F8 shows modified props (non-default value) more emphasized (blueish background for now)<\/p>\n<li>\n<p>TCastleVectorXxxPersistent is now a TCastleComponent descendant, it can have owner, it can react to csLoading, it can and should be SetSubComponent(true), it is deserialized better: sets the final vector at once.\n<\/ol>\n<p><b>Backward compatibility notes:<\/b><\/p>\n<ol>\n<li>\n    At the center of this change, is that TCastleCamera is now a TCastleTransform descendant. This generally makes it more powerful (e.g. you can add child objects to camera) but also makes some changes to API:<\/p>\n<li>\n<p>TCastleCamera no longer stores &#8220;initial&#8221; vectors. Just like all TCastleTransform, it just stores current position\/direction\/up, delegating to some other code management of &#8220;initial&#8221; vs &#8220;current&#8221; state, if you need that.<\/p>\n<li>\n<p>TCastleCamera.Position is deprecated. Use now Translation, not Position. Or WorldTranslation to get it in world-coordinates.<\/p>\n<li>\n<p>TCastleCamera.Update now follows the signature of TCastleTransform.Update, thus it gets extra RemoveType parameter.<\/p>\n<li>\n<p>TCastleCamera had some specialized GetView \/ SetView overloads. They have been removed &#8212; because they would be confusing now.<\/p>\n<p>TCastleCamera.GravityUp is always in world space.<\/p>\n<p>To get\/set camera vectors, you should usually use GetWorldView \/ SetWorldView to operate in world space. The GetView \/ SetView, defined in TCastleTransform, continue to operate in local space.  The new code should usually be updated from GetView \/ SetView to GetWorldView \/ SetWorldView &#8212; because almost always you want to query\/set camera in world coordinates, not in local coordinates. This way you support the case &#8220;camera can be a child of something else&#8221;.<\/p>\n<p>So you should usually upgrade this code:<\/p>\n<pre>\n\/\/ OLD\nMainViewport.Camera.GetView(Pos, Dir, Up, GravityUp);\n<\/pre>\n<p>into this:<\/p>\n<pre>\n\/\/ NEW\nMainViewport.Camera.GetWorldView(Pos, Dir, Up);\nGravityUp := MainViewport.Camera.GravityUp;\n<\/pre>\n<p>And this code:<\/p>\n<pre>\n\/\/ OLD\nMainViewport.Camera.SetView(Pos, Dir, Up, GravityUp);\n<\/pre>\n<p>into this:<\/p>\n<pre>\n\/\/ NEW\nMainViewport.Camera.SetWorldView(Pos, Dir, Up);\nMainViewport.Camera.GravityUp := GravityUp;\n<\/pre>\n<li>\n<p>TCastleNavigation had some deprecated GetView, SetView, Position, Direction, Up.<\/p>\n<p>They have been removed now. You should use Camera.GetWorldView, Camera.SetWorldView in most cases now.<\/p>\n<li>\n<p>World.CameraXxx deprecated functions have been removed:<\/p>\n<pre>\nfunction CameraPosition: TVector3; deprecated 'use MainCamera.Position if MainCamera <> nil';\nfunction CameraDirection: TVector3; deprecated 'use MainCamera.Direction if MainCamera <> nil';\nfunction CameraUp: TVector3; deprecated 'use MainCamera.Up if MainCamera <> nil';\nfunction CameraGravityUp: TVector3; deprecated 'use MainCamera.GravityUp if MainCamera <> nil';\nfunction CameraKnown: Boolean; deprecated 'use MainCamera <> nil';\n<\/pre>\n<p>Because you should now usually upgrade to MainCamera.GetWorldView or WorldTranslation.<br \/>\n    In general you have to now be aware that camera that world and local coords,<br \/>\n    just like everything other TCastleTransform.<\/p>\n<p>Same for TCastleSceneCore, removed deprecated:<\/p>\n<pre>\nfunction CameraPosition: TVector3; deprecated 'do not access camera properties this way, instead use e.g. Viewport.Camera.Position';\nfunction CameraDirection: TVector3; deprecated 'do not access camera properties this way, instead use e.g. Viewport.Camera.GetView';\nfunction CameraUp: TVector3; deprecated 'do not access camera properties this way, instead use e.g. Viewport.Camera.GetView';\nfunction CameraViewKnown: boolean; deprecated 'do not access camera properties this way, instead use e.g. Viewport.Camera';\n<\/pre>\n<p>Also TCastleViewport.XxxCamera methods that actually talked about navigation (and not Camera) are removed. They have been deprecated for some time, and right now could be quite confusing. So removed:<\/p>\n<pre>\nRequiredCamera\nWalkCamera\nExamineCamera\nInternalExamineCamera\nInternalWalkCamera\nClearCameras\n<\/pre>\n<li>\n<p>The already deprecated methods to auto-create the navigation have moved to separate deprecated class TCastleAutoNavigationViewport. The base TCastleViewport is free from their complication (that turned out to be useless, in most cases).<\/p>\n<p>This applies to you if you use AutoNavigation, NavigationType, ExamineNavigation, WalkNavigation.<\/p>\n<p>We advise you to instead create navigation explicitly, in code or in editor, like<\/p>\n<pre>\nMyWalkNavigation := TCastleWalkNavigation.Create(...);\nViewport.InsertBack(MyWalkNavigation);\n<\/pre>\n<p>But if you really need automatic management of navigation you can still use TCastleAutoNavigationViewport.\n<\/ol>\n<p>Screenshot using <a href=\"https:\/\/sketchfab.com\/3d-models\/steampunk-camera-a2210a0ba6834141af3bf83ee1e03f07\">Steampunk Camera<\/a> by <a href=\"https:\/\/sketchfab.com\/lumoize\">lumoize<\/a> from Sketchfab.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m nearly done with the big amount of changes on new-cameras branch. Below is a draft news announcement that will become official (and more complete) soon! TODO: This is too long to announce, too many things. And this is not even finished yet, there will be more gains from this in UI. TODO: Record a &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/castle-engine.io\/wp\/2022\/05\/06\/camera-and-navigation-rework-almost-finished-todo-this-news-announcement-is-too-long-we-have-too-much-new-stuff-to-announce\/\" class=\"more-link\">Continue reading  \u27a4<span class=\"screen-reader-text\"> &#8220;Camera and navigation rework almost finished. TODO: This news announcement is too long, we have too much new stuff to announce&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3252,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"publish_to_discourse":"0","publish_post_category":"9","wpdc_auto_publish_overridden":"1","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"1967","discourse_permalink":"https:\/\/forum.castle-engine.io\/t\/camera-and-navigation-rework-almost-finished-todo-this-news-announcement-is-too-long-we-have-too-much-new-stuff-to-announce\/581","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":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-3241","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\/2022\/05\/Zrzut-ekranu-z-2022-05-06-20-13-02.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9IgYW-Qh","jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts\/3241","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=3241"}],"version-history":[{"count":14,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts\/3241\/revisions"}],"predecessor-version":[{"id":3256,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/posts\/3241\/revisions\/3256"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/media\/3252"}],"wp:attachment":[{"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/media?parent=3241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/categories?post=3241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/castle-engine.io\/wp\/wp-json\/wp\/v2\/tags?post=3241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}