{"id":885,"date":"2009-07-05T15:50:32","date_gmt":"2009-07-05T14:50:32","guid":{"rendered":"\/blog\/?p=885"},"modified":"2009-07-05T15:50:32","modified_gmt":"2009-07-05T14:50:32","slug":"3d-cabs-openbve-v1-1-0-development-branch-new-video-uploaded","status":"publish","type":"post","link":"https:\/\/railsimroutes.net\/blog\/openbve\/3d-cabs-openbve-v1-1-0-development-branch-new-video-uploaded\/","title":{"rendered":"New Video Uploaded: 3D Cabs (openBVE v1.1 Development Branch), 323 Interior, Watford Junction to Rugby Hi-Res"},"content":{"rendered":"<p><strong><span style=\"text-decoration: underline;\">openBVE v1.1.1.0 (Development Branch), 3D cabs, and other stuff&#8230;<\/span><\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"padding-right: 5px; float: left; padding-top: 3px;\" title=\"openBVE 3D cab \/ X-City South screenshot - see video below\" src=\"\/images\/thumbnails\/xcs14_3dcab_0.png\" alt=\"openBVE 3D cab \/ X-City South screenshot - see video below\" width=\"240\" height=\"150\" \/>The first release (v1.1.0.0) in the development branch of openBVE was made available a few days ago, and now v1.1.1.0 has subsequently been released &#8212; the development branch includes support for <strong>full 3D cabs with animated objects<\/strong>, and <strong>mouse controlled camera rotation<\/strong>. v1.1.1.0 also introduces <strong>driver&#8217;s head motion<\/strong>, which responds to acceleration and deceleration, as well as inertia.<\/p>\n<p>As many will no doubt have noticed, I&#8217;ve not shown much by way of screenshots or video of openBVE&#8217;s in-cab experience thus far, as personally, I&#8217;ve always viewed the existing 2D panel support as something of a legacy feature which didn&#8217;t really demonstrate openBVE&#8217;s true potential, so I&#8217;ve been waiting for this moment for a long time, and I have to say, it most certainly lives up to expectations and is quite simply fantastic! Applying emergency brakes has never been so much fun. \ud83d\ude09<\/p>\n<p>Firstly, releases in the openBVE development branch are intended for developers who wish to expermiment with new features and offer feedback before these are eventually incorporated into the stable branch. Development releases may contain undetected issues, and features are subject to change, which means the development releases aren&#8217;t entirely suitable for regular users and the less technically minded, however I strongly recommend that developers and advanced users take a look at the development releases. If you&#8217;re interested in examining the new 3D cab support, you can head over to the <span style=\"white-space: nowrap;\"><a href=\"http:\/\/openbve.trainsimcentral.co.uk\" target=\"_blank\" rel=\"noopener\">\u00bb openBVE homepage \u00ab<\/a><\/span> to download version 1.1.1.0, along with a demonstration 3D cab update for the 113-1000atccab train (look under Examples via the <span style=\"white-space: nowrap;\"><a href=\"http:\/\/openbve.trainsimcentral.co.uk\/develop\/index.html\" target=\"_blank\" rel=\"noopener\">\u00bb Developing for openBVE \u00ab<\/a><\/span> menu). Please also read the <span style=\"white-space: nowrap;\"><a href=\"http:\/\/openbve.trainsimcentral.co.uk\/changelog.html#development\" target=\"_blank\" rel=\"noopener\">\u00bb Changelog \u00ab<\/a><\/span> for a full list of alterations and new features.<\/p>\n<p>Anyway, I&#8217;ve spent around a week working on a 3D cab for the new class 323 EMU and Cross-City South v1.4, and I&#8217;m really pleased with the results so far. I&#8217;ve uploaded a new YouTube video to briefly demonstrate the<strong> immersive nature of a 3D cab<\/strong>, the added realism, and some of the animated object possibilities &#8212; animated <strong>traction\/brake controller, reverser and horn lever<\/strong>, working <strong>in-cab safety system indicators<\/strong>, simulated working headlights which give the effect of<strong> outside illumination (but see caveat below)<\/strong>, along with working <strong>in-cab illumination<\/strong>. I think the potential of openBVE as a cab based simulator can now be truly realised, and speaking personally, this has forever changed the way I experience openBVE routes, and as long as photo-realism is maintained in new 3D cab environments, I&#8217;ll likely not want to go back to 2D cabs now.<\/p>\n<p>This latest video was originally intended to show some other things I&#8217;ve been working on, so you&#8217;ll find many clips of the new <strong>3D interior<\/strong> for the class 323, which includes <strong>seating<\/strong>, working <strong>television screens and lights<\/strong>, moving and <strong>streaking raindrop effects <\/strong>(inspired by the rain effects from Flight Unlimited 3), and <strong>ground illumination<\/strong> from the windows and pantograph sparking at night. The performance improvements which came with openBVE v1.0.7 also enabled me to capture some <strong>higher resolution video of Watford Junction to Rugby<\/strong>, of which many shots are included (and it has train sounds rather than my dreadful music this time \ud83d\ude09 ).<\/p>\n<p>I&#8217;m also pleased to say that Cross-City South v1.4 now includes a full set of <strong>on-train conductor&#8217;s announcements<\/strong>, with enormous thanks to voice recording artist Pete Kingwell <span style=\"white-space: nowrap;\"><a href=\"http:\/\/www.petekingwell.com\" target=\"_blank\" rel=\"noopener\">\u00bb http:\/\/www.petekingwell.com \u00ab<\/a><\/span>. Pete has also recorded a set of <strong>alternative Birmingham New Street station announcements<\/strong>, and we agreed that all these sounds could be released into the public domain along with the rest of the Cross-City South v1.4 files once released. Thanks must also go to Paul Sladen (maintainer of the Ubuntu version of openBVE) for intiating this aspect of the project as well. I&#8217;m glad to be able to remove another set of copyright files from the route now, while being able to add something new which has been missing from the Cross-City South route for years as well, and an example on-train announcement is included in the video.<\/p>\n<p>While viewing the 323&#8217;s cab, please note that I don&#8217;t actually know what the non-driver&#8217;s side of the cab looks like in any detail at all, so I&#8217;ve just had to use my imagination; if anyone can point out inaccuracies, feel free to tell me about them. Other than that, enjoy. \ud83d\ude42<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img decoding=\"async\" style=\"width: 100%;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" height=\"2\" \/><br \/>\n<span style=\"text-decoration: underline;\"><strong>Video:<\/strong> Demonstration of class 323 3D cab, interior fittings, and Watford Junction to Rugby hi-res (work-in-progress)<\/span><\/p>\n<p>I strongly recommend viewing this video in full screen due to some night time shots, in which some details might be hard to make out otherwise.<\/p>\n<p>By the way, yes, I know 323 EMUs don&#8217;t run from Watford Junction &#8212; that part of the video is just a bit of fun. \ud83d\ude42<\/p>\n<p><span style=\"text-decoration: underline;\"><br \/>\n<\/span><\/p>\n<p><object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" width=\"780\" height=\"460\" codebase=\"http:\/\/download.macromedia.com\/pub\/shockwave\/cabs\/flash\/swflash.cab#version=6,0,40,0\"><param name=\"allowFullScreen\" value=\"true\" \/><param name=\"allowscriptaccess\" value=\"always\" \/><param name=\"src\" value=\"https:\/\/www.youtube.com\/v\/QxgfhGZHznU&amp;hl=en&amp;fs=1&amp;rel=0&amp;ap=%2526fmt%3D22\" \/><param name=\"allowfullscreen\" value=\"true\" \/><embed type=\"application\/x-shockwave-flash\" width=\"780\" height=\"460\" src=\"https:\/\/www.youtube.com\/v\/QxgfhGZHznU&amp;hl=en&amp;fs=1&amp;rel=0&amp;ap=%2526fmt%3D22\" allowscriptaccess=\"always\" allowfullscreen=\"true\"><\/embed><\/object><\/p>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=QxgfhGZHznU&amp;fmt=22\">\u00bb Link to YouTube page (HD &#8211; *Best Quality*) \u00ab<\/a><br \/>\n<a href=\"https:\/\/www.youtube.com\/watch?v=QxgfhGZHznU&amp;fmt=18\">\u00bb Link to YouTube page (High Quality) \u00ab<\/a><\/p>\n<p><img decoding=\"async\" style=\"width: 100%; padding-top: 3px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" height=\"2\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Here&#8217;s a 1280&#215;1024 resolution screenshot of the new 3D cab. The framerate here is 25 fps, with 8x anti-aliasing and 16x anisotropic filtering enabled (on a Radeon HD 2600 Pro graphics card). Smooth transparency and anistropic filtering was also enabled in openBVE&#8217;s settings as well:<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><a class=\"imglink\" href=\"\/images\/xcs_14_openbve_19.jpg\"><br \/>\n<img decoding=\"async\" style=\"padding: 0px;\" title=\"openBVE\/Cross-City South v1.4 screenshot--click to enlarge\" src=\"\/images\/thumbnails\/xcs_14_openbve_19.png\" alt=\"openBVE v1.1.1.0\/3D Cab\/Cross-City South v1.4 screenshot--click to enlarge\" \/><\/a><br \/>\nopenBVE \/ 3D Cab \/ X-City South v1.4 screenshot&#8211;click to enlarge<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img decoding=\"async\" style=\"width: 100%; padding-top: 3px; padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" height=\"2\" \/><br \/>\n<strong><span style=\"text-decoration: underline;\">3D Cab Features and Animation<\/span><\/strong><\/p>\n<p>For the 323&#8217;s 3D cab, I&#8217;ve opted for a combination of moderately complex 3D geometry combined with photo-realistic textures, some of which were easily adapted from the existing 2D panel images. Developing the new cab wasn&#8217;t really more difficult than developing any other animated object, as that is exactly what the cab is &#8212; it just took longer as there are more animated parts. The most difficult tasks I found, were probably the gauges and needles, which needed quite a lot of experimentation before the results were right, partly because the 323&#8217;s panel is sloped backwards rather than being vertical, meaning that correctly tilting the axis around which the animated needles rotate took a little while.<\/p>\n<p>As an additional starting point for other train developers, here are the functions I&#8217;m using in the <em>panel.animated<\/em> file for the speedometer, main reservoir and brake cylinder needles, amongst other features, which I&#8217;m using.<\/p>\n<p><strong>Note:<\/strong> Some examples include two states, where one specifies an object illuminated by in-cab lighting, and the other specifies a non-emissive version of the object, shown when the power is cut, based on state of the <em>ats31<\/em> plugin variable defined in the 323&#8217;s panel2.cfg file (when used with Simon Gathercole\u2019s UKMUt.dll).<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>The Base 3D Cab<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ 3D cab screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_3dcab_1.png\" alt=\"openBVE \/ 3D cab screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"codebox\" style=\"width: 700px;\">\n<p><strong><span style=\"text-decoration: underline;\">Base 3D Cab Objects:<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\class323_dmso_cab_interior_lights_on.csv, 3dcab\\class323_dmso_cab_interior_lights_off.csv<br \/>\nstatefunction = !pluginstate[31]<\/p>\n<\/div>\n<p><strong> <\/strong>These two objects contain any non-animated portions of the cab, but one is a duplicate with emissive properties disabled, so in-cab lighting can be turned on and off according to the state of plugin variable <em>ats31<\/em> in this case, which simulates the effect of the power being cut, or a cold and dark cab environment.<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Speedometer and Brake Gauge<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ 3D cab screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_3dcab_2.png\" alt=\"openBVE \/ 3D cab screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Speedometer Needle Object (with day\/night textures):<\/span><\/strong><\/p>\n<p>CreateMeshBuilder<br \/>\nAddVertex,-0.003,0.04,0<br \/>\nAddVertex,0.003,0.04,0<br \/>\nAddVertex,0.003,0.00,0<br \/>\nAddVertex,-0.003,0.00,0<br \/>\nAddFace,0,1,2,3<\/p>\n<p>LoadTexture,speedometer_needle.bmp, speedometer_needle_n.bmp<br \/>\nSetTextureCoordinates,0, 0, 0<br \/>\nSetTextureCoordinates,1, 1, 0<br \/>\nSetTextureCoordinates,2, 1, 1<br \/>\nSetTextureCoordinates,3, 0, 1<br \/>\nSetDecalTransparentColor,0,0,0<br \/>\nSetEmissiveColor,200,200,200<\/p>\n<p>RotateAll,0,1,0,90<\/p>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"\/interface\/trans.gif\" alt=\"Horizontal Rule\" width=\"1\" height=\"1\" \/><\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Speedometer (100 mph):<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\gauges\\speedometer_needle.csv, 3dcab\\gauges\\speedometer_needle_dark.csv<br \/>\nstatefunction = !pluginstate[31]<br \/>\nposition = -0.5505, 2.232, 11.452<br \/>\nrotatexdirection = -1, 0, 0<br \/>\nrotatexfunction = -3.678 + abs[speedometer] * 0.0945<br \/>\nrotateyfunction = -1.11<br \/>\nrotatezfunction = -1.57<\/p>\n<\/div>\n<p><strong> <\/strong>The gauge background and cover are included as part of the base 3D geometry of the cab itself, not as seperate objects. The value -3.678 in <tt>rotatexfunction<\/tt> rotates the needle to 0 mph on this speedometer (adjust for your own gauge as required, using ObjectViewer to check the results). Where the last value (0.0945) is concerned, you can adjust this, initially, in 0.01 increments and test drive your train in openBVE until your speedometer is calibrated correctly (press Ctrl+V multiple times as required in-game, and compare the actual speed with the speed shown on the speedometer). Alternatively, you can temporarily replace the variable <tt>speedometer<\/tt> with a value in m\/s (converted from the unit of measurement shown on your speedometer), check the calibration via ObjectViewer, and adjust the last value accordingly. The other rotation commands are there to tilt the axis around which the needle rotates, to match the sloped 323&#8217;s panel.<\/p>\n<p>A similar approach applies to the following needles:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Main Reservoir (range covers 7-8 bar, as per the 2D panel):<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\gauges\\brake_needle.csv, 3dcab\\gauges\\brake_needle_dark.csv<br \/>\nstatefunction = !pluginstate[31]<br \/>\nposition = -0.741, 2.263, 11.462<br \/>\nrotatexdirection = -1, 0, 0<br \/>\nrotatexfunction = 1.12 + mainReservoir * 0.0000051<br \/>\nrotateyfunction = -1.11<br \/>\nrotatezfunction = -1.57<\/p>\n<p><strong><span style=\"text-decoration: underline;\">Brake Cylinder (range covers around 0-3.5 bar, as per the 2D panel)<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\controls\\brake_needle.csv, 3dcab\\controls\\brake_needle_dark.csv<br \/>\nstatefunction = !pluginstate[31]<br \/>\nposition = -0.731, 2.263, 11.462<br \/>\nrotatexdirection = 1, 0, 0<br \/>\nrotatexfunction = -1.52 + brakeCylinder * 0.0000053<br \/>\nrotateyfunction = -1.11<br \/>\nrotatezfunction = -1.57<\/p>\n<\/div>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 15px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Combined Traction\/Brake Controller<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ 3D cab screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_3dcab_3.png\" alt=\"openBVE \/ 3D cab screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The reverser is pretty straightforward, however this is what I&#8217;m using for the combined power\/brake handle:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Combined Traction\/Brake Controller:<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\controls\\power_handle.csv, 3dcab\\controls\\power_handle_dark.csv<br \/>\nposition = -0.952, 2.0, 11.173<br \/>\nstatefunction = !pluginstate[31]<br \/>\nrotatexfunction = if[powerNotch &gt;= 1, -0.125 * powerNotch, 0.10 * brakeNotchLinear]<br \/>\nrotatexdamping = 20, 0.8<br \/>\nrotatezfunction = if[powerNotch &gt;= 1, 0.05, 0]<br \/>\nrotatezdamping = 20, 1<\/p>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"padding-right: 4px; padding-bottom: 5px; float: left; padding-top: 3px;\" title=\"Class 323 Combined Traction\/Brake Controller\" src=\"\/images\/thumbnails\/xcs14_323_tbc_1.jpg\" alt=\"Class 323 Combined Traction\/Brake Controller\" width=\"250\" height=\"214\" \/>The <tt>rotatexfunction<\/tt> line allows both brake and power notches to be taken into account; adjust the -0.125 value to change the angle of the controller when position P1 or above is chosen, and similarly the value 0.10 for the brake steps. While determining what values to use, you can temporarily replace the above function in <tt>rotatexfunction<\/tt> with a simple function in the form of <tt>ROTATION_VALUE * <em>x<\/em><\/tt>, where the former determines the degree of rotation, and <em>x<\/em> represents your chosen power\/brake setting (for example, in the case of the class 323, a value of 1 to 4 for position P1-P4, and similarly 1 to 4 for position B1 to B3 and EMG as we&#8217;re using <tt>brakeNotchLinear<\/tt> here).<\/p>\n<p>Also, the class 323&#8217;s combined traction\/brake controller doesn&#8217;t just pivot back and forth; it&#8217;s also offset slightly to the left during the P1-P4 steps compared to the B1-B3 steps (you can see this in the screenshot on the left), which is what the <tt>rotatezfunction<\/tt> and <tt>rotatezdamping<\/tt> commands are for.<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Incidentally, you might have noticed that the combined traction\/brake handle appears to be a rather rounded, and smoothly sculpted object &#8212; this is achieved with a combination of 3D geometry and a good texture which captured some reflected light, further improved with <a href=\"\/blog\/?p=882\">custom normals<\/a> (as another side note, the spherical object at the end of the horn lever shown in the next section is a pair of simple 2D surfaces arranged in a cruciform fashion; no detailed 3D geometry is needed there). How might one go about creating an object like this power\/brake controller, without a 3D modelling tool? What I do, is apply the idea of the computed axial tomography medical imaging technique (CT scan) to object building; I first create a set of flat, 2D polygons or layers with temporary faces to build the basic framework of the mesh (you can draw this on paper first and number the vertices, if it helps &#8212; handy when it comes to defining faces and texture mapping later), then I adjust the vertices of the first layer until the shape looks about right, and then create the next layer and adjust and so-on, and then define final faces of the object and delete the temporary faces, followed by the addition of custom normals and texture mapping:<br \/>\n<img decoding=\"async\" style=\"padding-right: 4px; padding-bottom: 25px; padding-top: 10px;\" title=\"Class 323 Combined Traction\/Brake Controller Mesh\" src=\"\/images\/thumbnails\/xcs14_3dcab_7.png\" alt=\"Class 323 Combined Traction\/Brake Controller Mesh\" \/><br \/>\nThis is also the technique I used for creating the AC electric loco roof sections, by the way:<br \/>\n<a class=\"imglink\" href=\"\/images\/openbve_normals_2d.png\"><img decoding=\"async\" style=\"padding-top: 6px; padding-right: 6px;\" title=\"AC Electric loco roof section\" src=\"\/images\/thumbnails\/openbve_normals_2d.png\" alt=\"AC Electric loco roof section\" \/><\/a><\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Horn Lever<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ 3D cab screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_3dcab_4.png\" alt=\"openBVE \/ 3D cab screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Horn Lever:<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\horn_lever.csv, 3dcab\\horn_lever_dark.csv<br \/>\nposition = -0.07, 2.06, 11.234<br \/>\nstatefunction = !pluginstate[31]<br \/>\nrotatexfunction = pluginstate[24] * 0.5<br \/>\nrotatexdamping = 30, 0.8<br \/>\nrotateyfunction = -0.3<\/p>\n<\/div>\n<p><strong> <\/strong> The horn lever was straightforward to implement; it&#8217;s rotation simply depends on the value of the <em>ats24 <\/em>plugin variable in this case. <tt>rotateyfunction = -0.3<\/tt> simply rotates the object so it&#8217;s perpendicular to the desk panel it&#8217;s attached to.<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Other indicators<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ 3D cab screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_3dcab_5.png\" alt=\"openBVE \/ 3D cab screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">For any other standard atsi plugin variable with two states (e.g. 0 and 1):<\/span><\/strong><\/p>\n<p><strong> <\/strong>[object]<br \/>\nstates = 3dcab\\indicators\\tpws_isol.csv<br \/>\nposition = 0, 0, 0<br \/>\nstatefunction = !pluginstate[10]<\/p>\n<\/div>\n<p><strong> <\/strong>This is simple and works fine, and is also recommended. However, if on a state change, you notice that the newly loaded object appears momentarily untextured, and this bothers you, then you can use the following technique instead&#8230;<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n[object]<br \/>\nstates = 3dcab\\controls\\dra.csv<br \/>\nposition = 0, 0, 0<br \/>\ntextureshiftyfunction = pluginstate[13] * 0.5\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"\/interface\/trans.gif\" alt=\"Horizontal Rule\" width=\"1\" height=\"1\" \/><\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Texture mapping in dra.csv object:<\/span><\/strong><\/p>\n<p>CreateMeshBuilder<br \/>\nAddVertex,-0.5905,2.0885,11.381<br \/>\nAddVertex,-0.5485,2.0885,11.381<br \/>\nAddVertex,-0.5485,2.0525,11.365<br \/>\nAddVertex,-0.5905,2.0525,11.365<br \/>\nAddFace,0,1,2,3<\/p>\n<p>SetTextureCoordinates,0, 0, 0<br \/>\nSetTextureCoordinates,1, 1, 0<br \/>\nSetTextureCoordinates,2, 1, 0.5<br \/>\nSetTextureCoordinates,3, 0, 0.5<br \/>\nSetDecalTransparentColor,0,0,255<br \/>\nSetEmissiveColor,255,255,255<br \/>\nSetColor,130,130,130<br \/>\nSetBlendMode,Additive<\/p>\n<\/div>\n<p>Here, the illuminated DRA image is placed in the bottom half of the texture, while the top half of the image is transparent. By using a texture shifting function, no state change occurs, so you won&#8217;t notice any momentarily untextured surface appearing which can happen when a state is changed and the object hasn&#8217;t been loaded previously.<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"text-align: left;\"><img decoding=\"async\" style=\"padding-top: 10px; padding-bottom: 10px;\" title=\"DRA example\" src=\"\/images\/thumbnails\/dra_example.png\" alt=\"DRA example\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>If, for example, your ats subject had 4 states rather than 2 as in the above DRA example (with it&#8217;s bitmap split into 4 sections), you could use a value of 0.25 (i.e. 1 \/ 4) in your texture shifting function instead:<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td style=\"text-align: left;\"><img decoding=\"async\" style=\"padding-top: 10px; padding-bottom: 10px;\" title=\"Proving lights example\" src=\"\/images\/thumbnails\/provinglights_example.png\" alt=\"Proving lights example\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Simulated Headlight Effects<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ 3D cab screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_3dcab_6.png\" alt=\"openBVE \/ 3D cab screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>I&#8217;m still experimenting with the simulated in-cab headlight effects and some refinements are needed, but here&#8217;s what I&#8217;ve come up with so far:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\"><strong><span style=\"text-decoration: underline;\">Working Headlight (panel.animated file):<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = 3dcab\\ext_headlight_1.csv, 3dcab\\ext_headlight_1a.csv, 3dcab\\ext_headlight_1b.csv<br \/>\nposition = 0, 0, 0<br \/>\nstatefunction = if[pluginstate[20] &gt; 0, pluginstate[20] &#8211; 1, -1]<\/p>\n<\/div>\n<p>The object code I&#8217;m using is like the following:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Working Headlights (csv object example):<\/span><\/strong><\/p>\n<p><span style=\"text-decoration: underline;\">ext_headlight_1.csv<\/span><\/p>\n<p>CreateMeshBuilder<br \/>\nAddVertex,-1.3, 3.0, 11.67<br \/>\nAddVertex,0.6, 3.0, 11.67<br \/>\nAddVertex,0.6, 1.5, 11.67<br \/>\nAddVertex,-1.3, 1.5, 11.67<br \/>\nAddFace,0,1,2,3<\/p>\n<p>LoadTexture,transparent.png, headlight_interior.png<br \/>\nSetTextureCoordinates,0, 0, 0<br \/>\nSetTextureCoordinates,1, 1, 0<br \/>\nSetTextureCoordinates,2, 1, 1<br \/>\nSetTextureCoordinates,3, 0, 1<br \/>\nSetBlendMode,Additive<br \/>\nSetColor,150,130,100,120<\/p>\n<\/div>\n<p>The three objects are flat, vertical surfaces which load a simple texture with a sunburst gradient fill, representing a glow (similar to the <em>light_xxxxx.png<\/em> signal glow images included with openBVE&#8217;s compatibility signal objects, or the pantograph sparking effects I&#8217;ve shown previously). The glow colour in the texture is white, and the <tt>SetColor<\/tt> command is used to determine what colour headlight is depicted (a yellowish-white in the example above); this way, only one texture is needed. These objects are positioned just beyond the cab window, and the additive blending mode simulates the effect of illuminating whatever is behind the surface (the track and scenery, in this case). The height of the surface determines whether just the track, or the scenery, appears to be illuminated. The file &#8220;transparent.png&#8221; is a tiny, completely transparent PNG file loaded as the daytime texture, so the headlight effect is only visible in low light (as it&#8217;s loaded as a nighttime texture), or when the .Brightness command is used.<\/p>\n<p>The states are linked to the proving lights in the cab (<em>ats20<\/em>), and each object has it&#8217;s surface repositioned to simulate headlights on the left or right, or centred in the case of the marker lights.<\/p>\n<p>There is one caveat however; while this works well at night, or when in a tunnel during daytime, the effect doesn&#8217;t look so good when passing beneath a short overbridge (i.e. where a low .Brightness value is set over a distance of just a few metres), as the headlight glow becomes visible here, when in reality it wouldn&#8217;t. As a compromise, what I&#8217;ll probably do in the final release, is reserve the headlight effect for the nighttime headlight configuration only, not the daytime configuration (possible with the UKMUt.dll plugin). You&#8217;ll have to decide whether this minor issue is worth it or not.<br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"width: 100%; padding-top: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"380\" height=\"2\" \/><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Class 323 Interior<\/strong><\/span><\/p>\n<p>I thought I&#8217;d talk a little about the 323&#8217;s interior as well. The interior view features the expected things; i.e. seats and partitions, but I&#8217;ve also included working TV screens, working carriage lighting, raindrop effects which run down and streak across the windows at varying speeds (depending on the speed of the train), and ground illumination from the windows and sparking pantograph.<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Working TV Screens<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ class 323 interior screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_323_interior_2.png\" alt=\"openBVE \/ class 323 interior screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The working TV screens use simple texture shifting and translation functions &#8212; for the left screen with the car and rolling news ticker, there&#8217;s nothing I haven&#8217;t described before, apart from applying the functions to a very different set of meshes. Where the static effect is concerned, this is created by using two surfaces with a small texture containing a patchwork of black and white pixels; one of the objects has the texture reversed vertically and horizontally. One object is positioned slightly in front of the other, and both have alpha values set via the <tt>SetColor<\/tt> command to soften the appearance of the end result. These objects then have their textures shifted via the same function:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">TV Screen Static Effect (Object 1):<\/span><\/strong><\/p>\n<p>CreateMeshBuilder<br \/>\nAddVertex,0.46, 3.492, 3.597<br \/>\nAddVertex,0.765, 3.492, 3.597<br \/>\nAddVertex,0.765, 3.273, 3.597<br \/>\nAddVertex,0.46, 3.273, 3.597<br \/>\nAddFace,0,1,2,3<\/p>\n<p>LoadTexture,Class323_TV_Texture_2.png<br \/>\nSetTextureCoordinates,0, 2, 0<br \/>\nSetTextureCoordinates,1, -0.001, 0<br \/>\nSetTextureCoordinates,2, -0.001, 2<br \/>\nSetTextureCoordinates,3, 2, 2<br \/>\nSetColor,0,0,0,180<br \/>\nSetEmissiveColor,255,255,255<\/p>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"\/interface\/trans.gif\" alt=\"Horizontal Rule\" width=\"1\" height=\"1\" \/><\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">TV Screen Static Effect (Object 2):<\/span><\/strong><\/p>\n<p>AddVertex,0.46, 3.492, 3.595<br \/>\nAddVertex,0.765, 3.492, 3.595<br \/>\nAddVertex,0.765, 3.273, 3.595<br \/>\nAddVertex,0.46, 3.273, 3.595<br \/>\nAddFace,0,1,2,3<\/p>\n<p>LoadTexture,Class323_TV_Texture_2.png<br \/>\nSetTextureCoordinates,0, 2, 0<br \/>\nSetTextureCoordinates,1, 2, 2<br \/>\nSetTextureCoordinates,2, -0.001, 2<br \/>\nSetTextureCoordinates,3, -0.001, 0<br \/>\nSetColor,0,0,0,180<br \/>\nSetEmissiveColor,255,255,255<\/p>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"\/interface\/trans.gif\" alt=\"Horizontal Rule\" width=\"1\" height=\"1\" \/><\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">TV Screen Static Effect (Animation Function):<\/span><\/strong><\/p>\n<p>[object]<br \/>\nstates = ..\\Class323_TV_2.csv, ..\\Class323_TV_2a.csv<br \/>\nposition = 0, 0, 0<br \/>\nstatefunction = if[pluginstate[31] == 0 &amp; pluginstate[33] == 0, -1, value == 0]<br \/>\ntextureshiftxfunction = 2 * time<br \/>\nrefreshrate = 0.01<\/p>\n<\/div>\n<p>The <tt>pluginstate[i]<\/tt> variables are there so that the TVs are only switched on when there&#8217;s power, and stay on when passing though a neutral section (ats31 is the Line Volts indicator, and ats33 the Vacuum Circuit Breaker indicator). The <tt>refreshrate = 0.01<\/tt> line just adds a slight degree of flickering to the screen.<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 5px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Window raindrop effects<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ class 323 interior screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_323_interior_3.png\" alt=\"openBVE \/ class 323 interior screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The raindrop effects also deserve a little more explanation. These are comprised of two surfaces, the first of which has ordinary raindrops similar to what you&#8217;ve seen in BVE 4 cabs, except here, the surface simply has one tiled, transparent texture containing multiple raindrops and the texture is slowly shifted. The second surface, loads a texture depicting several streaking rain drops, and the speed of the streaking is linked to the speed of the train, although they still move slowly down the window when the train is stationary. What I did differently, was to make the surface irregularly shaped, so the raindrops appear to change direction as they travel across the window due to turbulence or inteference:<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><a class=\"imglink\" href=\"\/images\/xcs14_323_interior_4.png\"><img loading=\"lazy\" decoding=\"async\" style=\"\" title=\"Raindrop mesh--click to enlarge\" src=\"\/images\/thumbnails\/xcs14_323_interior_4.png\" alt=\"Raindrop mesh--click to enlarge\" width=\"240\" height=\"150\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Raindrop effect animation code:<\/span><\/strong><\/p>\n<p>[Object]<br \/>\nposition = 0, 0, 0<br \/>\nstates = Class323_DMSO_1_RainDrops_1.csv<br \/>\nstatefunction = !pluginstate[200]<br \/>\ntextureshiftyfunction = -0.1 * time<br \/>\ntextureshiftxdirection = 0, 1<br \/>\ntextureshiftxfunction = value &#8211; delta * speed \/ 60<br \/>\nrefreshrate = 0.01<\/p>\n<\/div>\n<p><tt>ats200<\/tt> is one of the raindrops you&#8217;re familiar with from the 2D BVE 4 cabs&#8230;<\/p>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 15px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Pantograph spark and ground lighting effect<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ class 323 interior screenshot - please see video above\" src=\"\/images\/thumbnails\/xcs14_323_interior_5.png\" alt=\"openBVE \/ class 323 interior screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The pantograph sparking and ground illumination effect is a simple additively blended glow effect, which will appear mostly briefly at various times during a journey, but not continuously and not necessarily frequently. When seen for the first time, it might seem as though the effect appears at random, but actually the times at which you&#8217;ll see sparking are based on the speed of the train. This is acheived via the following function:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Sparking effect:<\/span><\/strong><\/p>\n<p>[Object]<br \/>\nstates = Class323_Spark_1.csv<br \/>\nposition = 0, 0, 0<br \/>\nstatefunction = if[mod[speed, 3] &gt; 2.9, value == 0, -1]<br \/>\nrefreshrate = 0.03<\/p>\n<\/div>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 15px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Flashing Tail Light<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ Watford Junction to Rugby screenshot - please see video above\" src=\"\/images\/thumbnails\/wj-r_openbve_10.png\" alt=\"openBVE \/ Watford Junction to Rugby screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In terms of visual effect, the tail light is implemented just like the signal aspects. The animation code I&#8217;m using to achieve a short blink followed by a longer period of extinguishment is as follows:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong><span style=\"text-decoration: underline;\">Flashing Tail Lamp Animation:<\/span><\/strong><\/p>\n<p>[Object]<br \/>\nStates = TailLamp_1a.csv<br \/>\nPosition = 0, 0, 0<br \/>\nStateFunction = if[mod[time, 0.55] &gt; 0.08, -1, 0]<\/p>\n<\/div>\n<table style=\"width: 100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td align=\"center\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-top: 15px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<strong>Signal Ground Lighting<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"400\" height=\"2\" \/><br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"padding-bottom: 10px;\" title=\"openBVE \/ Watford Jn to Rugby screenshot - please see video above\" src=\"\/images\/thumbnails\/wj-r_openbve_11.png\" alt=\"openBVE \/ Watford Jn to Rugby screenshot - please see video above\" width=\"240\" height=\"150\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>These effects are really easy &#8212; the objects are just like the headlight objects mentioned previously, except these extend out behind the signal and are animated objects loaded via .SigF commands instead. The simple animation function I&#8217;m now using is as follows:<\/p>\n<div class=\"codebox\" style=\"width: 700px;\">\n<strong>Signal ground lighting animation function (assumes .Section 0;2;3;4 commands and 4 aspect signals):<\/strong><\/p>\n<p>[Object]<br \/>\nPosition = 0, 0, 0<br \/>\nStates = Sig_GroundLight_R.csv, Sig_GroundLight_Y.csv, Sig_GroundLight_Y.csv, Sig_GroundLight_G.csv<br \/>\nStateFunction = if[section &gt; 0, section &#8211; 1, 0]<\/p>\n<\/div>\n<p>Incidentally, I&#8217;ve now adopted more or less the same technique developed by michelle for openBVE&#8217;s compatibility signal objects where my own signal aspect\/lens and glow effects are concerned, as it&#8217;s obvious that a lot of care went into these effects, and they look superb when applied to my own signal objects with the lens hoods as well (see the video&#8230;).<br \/>\n<img loading=\"lazy\" decoding=\"async\" style=\"width: 100%; padding-top: 10px;\" src=\"\/interface\/themes\/modern\/dividers\/divider.gif\" alt=\"Horizontal Rule\" width=\"380\" height=\"2\" \/><\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Updated Pantograph Animation Functions<\/strong><\/span><\/p>\n<p>Lastly, I&#8217;ve updated my old <a href=\"\/blog\/?p=64\">Animated Exterior Car Objects blog entry<\/a> to include some updated unctions which resolve a problem with the code which I hadn&#8217;t considered previously. Bascially, the code I used meant that the pantograph animation speed was dependent on the framerate on the user&#8217;s computer, which is obviously no good &#8212; if slow framerates were encountered, the animation would proceed very slowly, while if high framerates were experienced, the animation speed would be too high. By incorporating the delta variable and a factor into the functions, this problem is solved. Actually this should have occured to me, because I observed this behaviour when I was experimenting with the wheel rotation initially&#8230; D&#8217;oh. Thanks michelle !<\/p>\n<div id=\"_mcePaste\" style=\"overflow: hidden; position: absolute; left: -10000px; top: 1606px; width: 1px; height: 1px;\">I also thought you might like to see a high resolution image of Cross-City South v1.4 and the new high detail class 323; in this screenshot, I&#8217;m running openBVE fullscreen at a resolution of 1280&#215;1024, with 8x anti-aliasing and 16x anisotropic filtering enabled (on a Radeon HD 2600 Pro graphics card). Bilinear interpolation was enabled in openBVE&#8217;s settings, with the Transparency mode set to Sharp. I was getting around 16-19 fps at the time; the framerates in the next version of openBVE will hopefully be a little higher due to performance optimisations where animated object normals are concerned, although this gain may be offset by the addition of more animated scenery objects to the route:<\/div>\n","protected":false},"excerpt":{"rendered":"<p>openBVE v1.1.1.0 (Development Branch), 3D cabs, and other stuff&#8230; The first release (v1.1.0.0) in the development branch of openBVE was made available a few days ago, and now v1.1.1.0 has subsequently been released &#8212; the development branch includes support for full 3D cabs with animated objects, and mouse controlled camera rotation. v1.1.1.0 also introduces driver&#8217;s [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[6,7,8,9,11,15,20,21],"class_list":["post-885","post","type-post","status-publish","format-standard","hentry","category-openbve","tag-animated-objects","tag-artwork","tag-cross-city-south","tag-functions","tag-openbve","tag-screenshots","tag-videos","tag-watford-jn-to-rugby"],"_links":{"self":[{"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/posts\/885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/comments?post=885"}],"version-history":[{"count":0,"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/posts\/885\/revisions"}],"wp:attachment":[{"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/media?parent=885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/categories?post=885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/railsimroutes.net\/blog\/wp-json\/wp\/v2\/tags?post=885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}