1. Neos VR
  2. News

Neos VR News

2021.9.3.1281 - Vector Swizzle Drivers, dynamic bone & image collider fixes

Hello everyone, just a small build to fixup a few issues and crashes. Sorry for not pushing this earlier, we ended up having a meeting and then I was too sleepy and worried I broke something (the dynamic bones would randomly cause everything to freeze at some point during fixing), but our QC team gave this a good test, so it should be good!

[h2]New Features:[/h2]
- Added vector swizzle driver components (under Relations/Swizzle Drivers)
-- These allow driving any vector type from any other vector type of the same type, but different sizes
-- You can select which component of the source vector maps to which component of target vector, allowing you to shuffle them around
-- Selecting value that's outside of the range (e.g. -1) will drive that component to default (typically 0 or false)

[h2]Tweaks:[/h2]
- Photos and imported image now use a BoxCollider instead of Mesh Collider
-- This improves performance and memory usage a bit
-- This also fixes them being one-sided after recent change (reported by @kazu0617 Neos:kazu and @Aesc/あすく, GH #2918)
-- Existing photos are auto-upgraded on load

- Added MMC2021 locale strings by @ProbablePrime | Docs
- Create New directory strings are now localizable (implemented by @ProbablePrime | Docs)

- Merged Japanese locale updates by @Aesc/あすく and @kazu0617 Neos:kazu
- Merged Czech locale update by @rampa_3 (UTC +1, DST UTC +2)
- Merged Russian locale update by @Shadow Panther [RU/EN, UTC+3]
Security:
- Fixed extremely long paths put into Create New Form, Component Attacher and LogiX resulting in crash (reported by @art0007i, Ticket #576377, fixed by @ProbablePrime | Docs)

[h2]Bugfixes:[/h2]
- Fixed potential race condition when removing dynamic bones from the collision management system, resulting in corruption and crash (based on report by @jeana, GH #2919)
- DynamicSubtitleProvider now triggers update when the subtitles are changed
-- This fixes Animator not picking up the new track (reported by (@jeana and @Enverex, GH #2920)
- Fixed running updates on dynamic bone chains that just got destroyed, resulting in exceptions
- added protection against creating inventory folders with excessively long names, resulting in potential corruption of the record and inability to delete it (based on report by @Malice, GH #2754, fixed by fixed by @ProbablePrime | Docs)

BEPUv2 upgrade complete - improved performance, step up logic, proto-rigidbodies

Hello everyone and welcome to another of our weekly updates!

Last week we have released one of the biggest updates to Neos yet, upgrading the physics engine from BEPUv1 to BEPUv2, with a greatly improved performance and re-engineered how the integration works with Neos and has been one of the top requested changes both by GitHub and Patreon voting.

Combined this has greatly improved performance in many situations (particularly collider heavy worlds and items), improved physics behavior (e.g. when really small or going really fast) and fixed number of longstanding issues, such us users getting dropped out of fast moving vehicles or colliders lagging a frame behind.

There's a number of improvements as well, for example we implemented proper step up logic for character controller - no longer will you get stuck on small bumps in the environment - now you can walk up 2 meter tall stairs steps if you really want to!

Character controller can now also use any shape and update in realtime. With this it now respects your actual height in-game, so you can duck and walk under obstacles! Another addition lets you modify the interaction with specific colliders (or even spot on a collider using a texture), making surface sticky, slippery, bouncy and more!

And perhaps the most fun, you can now unlock rotation on character controller. As somewhat unintended side effect, this lets you create simple "proto-rigidbodies", that many of you have already been having fun with.

While we don't want to stop anyone from messing around with those (they are very fun after all!), please give the post below a read to understand their limitations and what is planned for the full rigidbody support that's coming at later point as separate major update, so you don't run into any nasty surprises!

You can read a lot more about the changes and improvements below and check out the detailed change log - we don't think that any build in the past ever had one this big!

In big part it's also thanks to our QC Team and Danger Testers, who helped catch dozens of issues and content breakages before the update went public, ensuring mostly smooth release.

There's a lot more exciting stuff to come in the future with the upgrade done, such as full rigidbody physics, culling systems for optimizations, value control volumes and more!

[h2]BEPUphysics v2 upgrade complete![/h2]
Last week we completed one of the biggest upgrades of Neos’ codebase to date - switching the physics engine from BEPUv1 to BEPUv2 and completely re-engineering how Neos integrates with a physics engine to power its interactions.

Despite the name, BEPUv1 and BEPUv2 are completely different physics engines, with BEPUv2 being written completely from scratch for greatly improved performance and flexibility of integration. Both are open-source projects by Ross Nordby.



Inside of Neos the physics engine is used to power the majority of interactions - whenever you point at something with a laser, grab an object, use a tool to interact with in-world items or move around the environment, the physics engine is used to figure out which objects in the 3D space are hit.

Because it’s the underlying layer for the majority of the core interactions with the environment, the integration with BEPUv1 has been one of the oldest parts of Neos’ codebase and it was showing its age in a number of issues that have accumulated over the years, both with glitchy behaviors and performance.

With the upgrade, we took the opportunity to completely scrap all the Neos code that integrates the physics engine as well and write a completely new one, with the latest conventions and good practices of Neos’ codebase.

In combination with BEPUv2 being a major upgrade in terms of performance and allowing better flexibility in integration thanks to its low level interface, Neos now has greatly improved performance in many areas, fixed numerous bugs and implemented a number of new features that have been requested for a while, with much more to come in the future! Let’s dive into them!

[h3]Improved world performance[/h3]
Thanks to BEPUv2’s performance oriented design and our re-engineered integration, performance issues in a number of areas have been fixed, particularly with very collider heavy worlds.

The improvement will depend greatly on a world or session, depending on what particular bottleneck is. Certain worlds have seen great improvement in performance. For example Dark City 2 went from 70 FPS to around 120 FPS on the same system in the same spot. Large Minecraft import worlds have seen huge benefits thanks to their heavy use for triggers, some of the biggest ones going from 20 FPS to smooth 110 FPS and being limited by the amount of rendered geometry instead.

[previewyoutube][/previewyoutube]

Many of these improvements are to improve handling of the colliders, ensuring that changes and moved colliders don’t cause unnecessary calculations (such as waking up colliders that aren’t interested in the updates) and certain parts of the update process run asynchronously from the rest of the updates.

Other worlds have seen smaller performance boosts, while other very negligible ones, due to being bottlenecked by other parts of the system, such as heavy LogiX use. This was expected, since with any complex system any part can become bottlenecked and our goal is to continually optimize all of them, with each optimization improving the general performance.

[previewyoutube][/previewyoutube]

[h3]Smoother loading[/h3]
The loading process should be now smoother as well. We fixed a number of issues causing extremely heavy CPU and memory usage which could lock up some systems, due to computing mesh metadata and colliders.

With BEPUv1 the acceleration structures required for mesh colliders and convex hulls were always computed on the fly as you loaded into the world, resulting in more stutters. With BEPUv2 integration the system now utilizes our asset variant system instead, computing the data only once and then loading it from the cache or the cloud.

Thanks to this the loading process should now be smoother and cause less load on the system. In our testing, computing a mesh collider for a dense mesh would take around 680 ms, while decompressing and loading a precomputed one took around 40 ms.

[h3]More efficient Raycast and Sweep queries[/h3]
Thanks for BEPUv2’s low level design, we could optimize the common queries against the physics representation of the world - raycasts and convex sweeps, used to find which objects are hit in the world - e.g. when you use a tool, click on something with your laser or shoot a weapon.

If the query is interested in only one closest hit, it now uses a specialized path that adjusts the tested ray distance based on the found hits and avoids building a list of all hits to sort out later, reducing some memory usage. Both the LogiX RaycastOne and internal uses (e.g. particle system collisions) have been replaced with this variant.

[h3]More efficient dynamic bone chain collision queries[/h3]
Part of our reason to upgrade to BEPUv2 was to also utilize some of its efficient data structures for our own features and various culling systems. One of the first such optimizations has been reworking the way dynamic bone chains look for potential colliders in the environment.

Previously each chain would scan all users by itself individually. With an increasing number of users (and dynamic bone chains) in the world, this would scale poorly and cost more and more CPU performance.

With the reworked system the initial intersections are now efficiently distributed using BEPUv2’s Tree structure, which should provide much better scaling and give us framework for more culling optimizations in the future.

[previewyoutube][/previewyoutube]

[h3]Character Step Up logic[/h3]
One of the longstanding issues in Neos reported by many users was the character controller getting stuck on small obstacles, requiring the heavy use of ramps when building worlds. We have previously deferred this issue to the BEPUv2 upgrade and with it now done, the issue has been resolved!

Thanks to the low level integration, we have implemented a proper step up logic, which will automatically walk up vertical obstacles, such as stairs, bumps and even tall vertical walls if the step height is configured so.

This should provide a lot more flexibility for creators to build the environments and make it easier for users to walk around any map, without getting stuck on small bumps and pieces of geometry. Setting up ramps might still be preferable, as it will provide a smoother movement, but is no longer necessary.

[previewyoutube][/previewyoutube]

[h3]Character Controller now respects your current height and can be any shape[/h3]
Another of the long requested features has been the ability for character controller to respect your current height - for example when you crouch, the shape representing you in the world gets smaller, allowing you to walk under obstacles.

With the upgrade and the logic of the character controller reworked, this is now fully supported! Rather than always being a fixed capsule shape, the collider has now been decoupled from Character Controller and is presented by a separate component on the same Slot.

[previewyoutube][/previewyoutube]

As a result, you can use any convex shape - box, cylinder, sphere, even convex hull! The shape can also be updated as any other too. For Character Controller specifically there’s a new SingleShapeCharacterControllerManager component, which automatically adjusts the height of the collider based on the current position of your head.

This means in VR you can now duck and walk under obstacles! Desktop mode has a bit of extra behavior as well on top, which will prevent the character from standing up after crouching if there’s something above them.

https://www.youtube.com/watch?v=GNW59n3M8sQ

We are looking into doing more in the future as well. With planned compound collider support, it should be possible to split the character body into multiple shapes instead of a single one and provide even more precise collisions with the environment when leaning over or laying down in full-body.

[h3]Character Controller surface modifiers[/h3]
To give you even more flexibility when building worlds, we introduced a new type of component - character controller modifiers! These allow you to modify the behavior of a particular collider for character collisions - dynamically changing the traction parameters, speed, jump height and more.

With this you can easily create surfaces that are sticky (like the purple goo from DOOM Eternal), slippery (like ice that makes you slide), ladders that you can climb vertically by walking into them and much more!

It’s also possible to utilize a texture to control the parameters, allowing you to vary the parameters depending on where the player is colliding. This can be very useful for terrains. We can’t wait to see what kinds of maps and cool things you’ll build with this new mechanism!

[previewyoutube][/previewyoutube]

[h3]Fixed collisions being a frame behind and getting dropped out of vehicles[/h3]
With previous integration users ran into a number of problems, particularly when building fast moving vehicles. Oftentimes users would end up randomly dropping out of the vehicle if it’s moving fast enough and interacting with any colliders within it would be difficult as well, as they would be lagging a frame behind from the visual.

[previewyoutube][/previewyoutube]

Thanks to the whole integration being re-engineered, we put a lot more care into how the new one is designed to avoid those problems altogether, by paying more attention about the order of operations and ensuring that the physics representation is updated at the right time.

This was done by splitting movement events between general and physics, allowing the colliders to update their poses before interactions happen, without causing issues with other components that must update late.

Along with a whole number of smaller design changes, those issues are now completely gone! Vehicles and other behavior should now be reliable and easier to enjoy!

[h3]Improved interactions at small scales[/h3]
One of the big changes in BEPUv2’s design is it’s auto-tuning mechanism. The previous version had a number of manual settings to make it behave well for particular use-case and scale. As a result if you scaled yourself down in Neos (or large), interactions with the environment would feel “off” and glitchy.

BEPUv2’s design however tries to avoid those manual settings whenever possible and instead the calculations are tuned automatically. As a result of the upgrade, interactions while being scaled significantly down in Neos now feel the same as at regular scale, giving users more flexibility on interacting with the environment!

[h3]Mesh Colliders can now be single sided[/h3]
Previously all mesh colliders in Neos would be dual-sided - you would collide and hit the mesh from whichever side you’d come in. In a large number of cases, this was actually undesirable - you could easily get stuck in the geometry or halfway through a terrain due to colliding with both sides of it.

With the new integration, we have now exposed this as a configurable option, allowing you to set collisions to only happen from the front side of the mesh - the one that you see with a single sided-material.

On top of that we have also added heuristic that automatically converts any character colliders into Front sided only, unless some conditions are met - there’s a dual-sided material on the same slot or any negative scaling.

This technically changes behavior of existing content, but from our testing phase this seems generally beneficial in improving the behaviors of those worlds and improving performance, with the heuristics preventing the upgrade in cases where it would cause issues. If you find any more, let us know though and we can tweak them some more!

[h3]Static Trigger types[/h3]
We have added some new collider types to the mix as well! In addition to Trigger and HapticTrigger, there are now static variants as well - StaticTrigger and HapticStaticTrigger. These are functionally the same, but assuming they don’t move relative to the world, will skip some of the overhead that non-static variants have.

If you’re building new content, it’s recommended to use those types whenever you know that it won’t move which can give you a bit of extra performance (especially if there’s a lot of them). If they are moving however, use the regular ones.

You’ll probably notice that there’s also “Auto” variants of these. Any existing content is automatically switched to those, so it can gain benefits of their optimizations. If any movement is detected over several frames, they will automatically be switched to the non-static version.

[h3]Main physics and Haptic colliders are now separated[/h3]
Previously a single physics simulation was used to handle all the different types of colliders - both for environment collisions and triggers, as well as haptic volumes, triggering any haptic interactions in the environment.

Because those two types of interactions never interact with each other, the new integration now splits them up into two completely separate simulations. Not only does this avoid a bunch of cross testing of colliders that will never interact, but allows us to update them fully in parallel, for a bit of additional performance!

[h3]Mesh density heuristics - no more lag when laser tries to stick to dense mesh[/h3]
Another of the small, but hopefully impactful performance improvements is handling of dense mesh colliders. Lasers in Neos have a “sticking” logic, which tries to stick the laser point to the last object when it goes past the edge.

[previewyoutube][/previewyoutube]

Generally this works pretty well, unless the object is using a dense mesh collider. The sticking tests can be very expensive against those colliders, which would cause your framerate to randomly drop as you interact with the environment.

Neos now computes average triangle sizes and areas as part of the mesh metadata, which now allows us to estimate average density of the mesh relative to the scale it’s being tested at. If we detect that the test would be likely too expensive, we simply skip the expensive tests and just stick to the last known point.

This should help improve the general user experience with unoptimized content and avoid another case of accidental stutters that can be uncomfortable to users.

[h3]Double buffered procedural mesh collider updates[/h3]
When using mesh colliders with procedural meshes, Neos would previously try to update the acceleration data in-place. In some cases this would result in glitchy behaviors, where certain colliders would seem to flicker in and out of existence or produce random ghost collisions, due to being in the middle of an update. You could particularly notice this with LogiX in some cases.

To improve this behavior and prevent potential race conditions, the new mechanism is now double buffered, simply computing a new acceleration structure in the background, while the existing one is in use and then swapping them over.

This mechanism also improves the memory management, avoiding lots of new allocations on frequently changing mesh colliders.

While this improves the behavior, generally it’s recommended to use simpler colliders instead, especially for anything that changes over time, as it will provide better performance.

[h3]Numerous other performance improvements and fixes[/h3]
Apart from these notable changes, the upgrade process had many more bug fixes and small performance improvements that should overall help improve the user experience for both end users and creators.

If you’d like to see a more complete list of the changes, check out the release notes here, which go into a bit more detail.

https://steamcommunity.com/games/neos/announcements/detail/2944778418489689560

[h2]Proto-rigidbody physics - what are they?[/h2]
Perhaps one of the most exciting and somewhat unintended features of the BEPUv2 upgrade is the ability to get simple rigidbody simulation, thanks to the combination of being able to use any shape with CharacterController and new ability to unlock its rotation.

With this, you can get objects that behave like rigidbodies, which can be very fun to interact and play with, but which also come with some important limitations that everyone needs to understand first.

Importantly, those are NOT what the actual planned rigidbody support entails - it is a separate body of work that will come at a later point after this upgrade and will be designed to handle the rigidbody simulation efficiently (both on system resources and network) and give you full control.

[h3]Why character controllers aren't suitable for rigidbody simulations[/h3]
  • They're optimized for character locomotion and will have odd behavioral quirks when used otherwise, these will be addressed by the actual rigidbody support, so before that comes you'll have to deal with them
  • Having many of them won't perform well, both on CPU and network. They're not optimized for this use case
  • You have limited control. You can't control aspects like friction or create constraints (e.g. joining bodies with joints, hinges, motors etc) that actual rigidbodies support.
  • We STRONGLY discourage building too complex long term content with this mechanism, other than one that involves actual character control.


Now if you understand these limitations, feel free to have fun with them in the meanwhile, before the full support actually comes. Neos is all about tinkering, toying around and messing with things and it will give you a bit of a taste of what will come.

Here are some videos of our users playing with them!

[previewyoutube][/previewyoutube]
[previewyoutube][/previewyoutube]
[previewyoutube][/previewyoutube]

[h3]What will full rigidbody support offer?[/h3]
The full rigidbody support covered by this issue is a significant chunk of work that will come after the BEPUv2 upgrade completes. It will focus on following:
  • CPU and network efficiency - with engine optimizations, efficient handling of many bodies in the simulation and specialized network encoding will allow you to have many bodies in the world with significantly lower impact
  • Simple to use with less glitchiness - controlling the friction, bounciness, applying forces and impulses and more, without the extra “cruft” that character controllers have - these will be pure rigidbodies
  • Constraints - you will be able to connect the rigidbodies with a number of constraints - joints, springs, hinges, motors and more, to create complex setups and interactions
  • Smooth simulation and interaction for everyone - character controllers are simulated by a single user only and can be quite choppy and glitchy (for example when grabbing they just randomly poof off somewhere) for others if not setup properly. Full rigidbody support will be designed to not have these issues.
  • New features and tools - instead of having to go through convoluted process to enable the simulation, we’ll add quick tools and integrate physical interactions across Neos, to make it very easy to start playing with them and building cool content

Make sure to also check the roadmap for physics support, we'll expand it with individual tasks once work begins on this (we're still finishing BEPUv2 upgrade at the moment, so it won't happen before then): https://github.com/Neos-Metaverse/NeosPublic/projects/19

[h2]Big thanks to everyone who helped with the upgrade![/h2]
The upgrade has been a relatively long and tedious process, as we had to remove a significant chunk of Neos’ codebase and completely redesign and rework it on a new system, while making sure that existing interactions and content doesn’t break.

--- --- BEPUv2 integration merge request, right before public release, along with all reports by QC team and public testing (click to view full image)

Before releasing the upgrade to the public, we ran closed testing first with our new QC team in order to find out the most egregious bugs and issues, followed by public testing with our Danger Tester group afterwards, to get much broader coverage of issues and problems.

Thanks to everyone’s efforts, we found dozens of bugs, content breakages, crashes, performance issues and other issues during the testing phase and addressed them before the public release, leading to a relatively smooth release. Of course if you find any more bugs and regressions, feel free to report them on GitHub, we'll still be fixing what we can even post-release!

Here’s a huge thanks to Shifty and her QC team for helping out catch all the early bugs, as well as Danger Tester's who participated in the public testing: Shadow Panther, Beaned, ohzee, Zyzyl, Alex from Alaska, Snooper, Pat cat, LucasRo7, Turk, Enverex, MattyK, Cyro, Modern, 1amNick, Hayden, Toxic_Cookie | NTC CEO, Elizabeth Dayax, Epsilion, epicEaston197, DrFrank, TheBasementNerd (she/her), Alex rainbowdashie, Sloppy McFloppy , Ian Corvid, Kulza, Tatsu Kimiero, Sylva, Gawdl3y and everyone who tested without reports!

Another huge thanks also goes to Ross Nordby, the developer of BEPUphysics 2, for his detailed explanations and responses that helped with the integration process and quick bug fixes of issues we found in the physics engine itself!

And last but not least, there’s a huge thanks to everyone in the community and our Patreon supporters, who have enabled us to work on this large project. BEPUv2 upgrade has been one of the top requested changes, both on GitHub and Patreon and with it now complete Neos has made an important leap forward, with many great things to come in the future on top of this foundation.

There are exciting times ahead! See you next week!

2021.9.1.665 - Dynamic Bone Chain optimization, bugfixes, security improvements

Hello everyone! I got another build for you, with one of the first optimiztaions built with some of BEPUv2's structures - I've reworked the dynamic bone chain collision system to efficiently query and propagate any collision overlaps, rather than having each chain finding its own collisions. This should make it scale better with increasing number of users in the session and help improve the performance a bit. That said, I'm testing the waters a bit with this approach, so there's a bunch more to come in the future with this. Let me know how it goes!

There's a whole bunch of other stuff too, more bugfixes for BEPUv2 upgrade (notably a fix for point clouds generating nonsense colliders that cause severe lag), security improvements and various quality of life improvements!

[h2]New Features:[/h2]
- Added DynamicSubtitleProvider
-- This will dynamically import a subtitle as Neos animation from given URL (requested by @Enverex, GH #1260)
-- Supported files are the same as the statically imported ones. HTTP(s) sources are supported
- Added GetActiveUserSelf LogiX node (requested by @Shadow Panther [RU/EN, UTC+3], GH #2790, implemented by @ProbablePrime | Docs)
- It is now possible to listen for Equipped and Dequipped events on any Tooltip, instead of just RawDataTooltip (requested by @Turk and @3x1t_5tyl3, GH #2026, implemented by @ProbablePrime | Docs)
- Added support for Parsec for Distance unit parsing and formatting
Optimizations:
- Implemented initial version central dynamic bone chain update and collision management system
-- The manager collects all colliders and dynamic bones and asynchronously updates bounding box tree structures for efficient search of overlaps, instead of each dynamic bone chain searching for its own collisions
-- The implicit player colliders are generated only once globally, rather than being generated for each dynamic bone present
-- This should help improve how part of the dynamic bone chain scales with increasing number of users in the session, improving part of their performance
-- Please let us know if you notice any difference in scenarios with many users! We'll need to do more profiling and figure out how this affects the rest of the system, there's more changes and optimizations to be done
-- Amount of memory allocations should be reduced
-- Note that the actual simulation performance is unaffected by this change, it mainly addresses poor scaling of collecting potential colliders
- Added more efficient pruning of dynamic bone collisions before performing more expensive checks

[h2]Tweaks:[/h2]
- Merged latest BEPUv2 updates from upstream
- Added reference proxies to the imported subtitle object to allow it to be dropped in the inspector directly
- UTCNow node is now also in Math/DateTime folder (requested by @Epsilion, implemented by @ProbablePrime | Docs)

[h2]Security:[/h2]
- Laser offset and direction from the world is now temporarily supressed when context menu is opened in the userspace (based on report by @seif1, Ticket #622989)
-- This prevents a potential attack by hijacking user's laser in-world to make them point at an item in the Userspace
-- Normally this should pose no functional difference, as the laser offset doesn't typically change unless the avatar is switched
- Added "Remove Single Instance" button to SimpleAvatarProtection (based on feedback by @xYreous, @Khosumi, @Alex from Alaska, @kazu0617 Neos:kazu, @Electronus and @Zyzyl, GH #2897)
- Added warning to SimpleAvatarProtection, indicating that removal by any means other than dedicated buttons will result in self destruction (based on the same issue above)
- Added protection against infinite recursion when generating LogiX visuals if they're removed within the generation, resulting in a crash (reported by @marsmaantje, Ticket #790410)
- Removed old DebugFingerPoseCompensation component which causes world to crash when added (reported by dmx, Ticket #599312 and #910271)

[h2]Bugfixes:[/h2]
- Fixed mesh collider generation for point clouds producing garbage data, resulting in those colliders not being grabbable and causing extreme freezes when queried
- Fixed regression causing IsCharacterOnGround, CharacterLinearVelocity, CharacterGravity and CharacterGroundCollider requiring updating relay, rather than updating themselves (reported by @Earthmark and @Ho'polis, GH #2896
- Fixed some invalid meshes causing exceptions during loading, generating metadata and asset variants
- Fixed potential slight memory corruption when computing colliders for meshes with no geometry
- Fixed HandCollisionVibration on DynamicBoneChain not working
- Fixed procedural textures and meshes failing to bake if they're not referenced by anything (based on report by @Dante | Moderation Team and @Snooper, GH #2899)
- CharacterController legacy content upgrade will now disable UseUserHeadHeightWhenAvailable option when there's no locomotion module present on the same slot
-- This can fix some old vehicles breaking when being grabbed (reported by @H3BO3, GH #2898)
- Fixed dynamic bone chains colliding with own head when "CollideWithOwnBody" is not checked (reported by @epicEaston197)

2021.8.29.1240 - Subtitle import support, reading texture 2D pixels in LogiX...

Hello everyone! I got another build for you with a whole bunch of new goodies and bugfixes.

You can now import Subtitle files natively into Neos! This can be useful for a lot of various workflows, as they get converted into native Neos animation file and can be sampled by time for lots of purposes, syncing them with anything, including custom content.

On related note, LogiX has been expanded a bit with access to some asset types. You can now read the pixels of static 2D textures (either by UV or pixel position)! This could prove useful if you need to encode some 2D spatial information into texture data and use if for your own logic. Similarly you can sample animation tracks from LogiX as well, using time as an input, letting you build cool systems on top of it.

There's also a potentially very important bugfix - turns out that headless wasn't syncing the master clock due to not having any streams of its own. This had a bit of a cascade effect, where a lot of things could drift out of sync on headless sessions, like video/audio playback, LogiX setups and other things, so hopefully this will fixup a lot of issues in one swoop!

I've also merged in latest updates from BEPUv2 upstream and cleaned up everything to now build on the Azure Pipelines rather than local only build so other devs aren't blocked by a missing dependency. This should include some collision edge case improvements too as well as some small optimizations that were missing in our fork.

I'm designing the optimization for dynamic bones on top of BEPUv2 structures, it's going to take a bit more time, so I'm pushing this out before then, but hopefully that should come soon enough too! From some preliminary profiling it should give us another nice performance boost.

[h2]New Features:[/h2]
- Added native subtitle import support (based on request by @Karel | CEO, @Robyn (QueenHidi), RoxyBoxxy, @DovahDoVolom and others, GH #1260)
-- Following formats are currently supported: srt, sub, ssa, ttml, vtt
-- The subtitle is converted in Neos native animation (AnimX) with track with string keyframes. This can be used to sync playback with video or any other playback (including any custom Neos content - they are simply treated as animation with keyframes that are pieces of text)
-- Note that subtitles embedded in video files aren't supported yet
- Added PlaybackSynchronizer, which syncs one playback to another
-- It can optionally sync normalized positions for clips of different duration
-- Note that both playbacks are still individual and can have slight jitter. This doesn't guarantee perfect synchronization, but it should be generally low enough, depending on what's being synchronized
-- You can specify position offset and position rate (this adjusts speed as well)
- Added GetAsset node (under Assets), which will get the asset from input asset provider (e.g. plugging StaticTexture2D will give you Texture2D)
- Added Sample Texture2D UV node (under Assets) which will sample the texture color at given UV coordinate using bilinear interpolation (requested by @BlaXun | Ingo#6920, @Shifty | Quality Control Lead and others, GH #365)
-- Note that the texture must be marked as readable in order to access its data and in format that supports CPU read (e.g. not block compressed)
- Added Texture2D Format node (under assets) which provides basic format and dimensions of input texture
- Added Get Texture2D Pixel node (under Assets), which allows getting specific pixel at specific mip level of a given texture
-- Note that the texture must also be marked as readable for this to work
-- If the position or mipmap are outside of range, clear color will be returned
- Added SampleAnimationTrack node which allows sampling values from imported animations at given time point
-- T must be same type as the corresponding animation track, otherwise it won't work
- Added FindAnimationTrackIndex which finds index of a track for given node and property
-- Returns -1 if no matching track is found
-- It's recommended to cache this value instead of fetching it every time - you can even store it ahead of time if you're always using same animation track - the indexes don't change between loads of the same animation asset
- Added CurrentClockError to VideoTexture, which provides the current time offset of the video playback (as reported by the video playback engine) to the desired playback position from Neos
-- This can be used for diagnostics or to correct other playback components to match the video (you might need to apply some smoothing rather than using raw value due to jitter)

- Added DiscreteAnimationTrack type internally, which allows efficiently holding "Hold" type keyframes that are generally more sparse

[h2]Security:[/h2]
- Removed old ChildrenSynchronizer component (Ticket #145123)
-- This is due to combination of it's half broken state (it's from before inventory was implemented) and newly found security issues that wouldn't be possible to solve without complete redesign
-- Please use inventory or grab things if you want to move them between the worlds, as this gives you more control over what's transfered and is more reliable
- Internal moderation system improvements
Tweaks:
- Merged latest BEPUv2 upstream changes to our fork
-- Has improved corner case handling for triangle-cylinder collisions
-- Fixes for convex hull generation producing invalid hulls
-- Various small(ish) optimizations
- Neos now prints out supported file formats on startup for diagnostics and reference
- Removed workaround for invalid convex hulls thanks to the direct fix from BEPUv2
- Partially reverted input deadzone behavior to original (previously changed based on GH #2613) for turning
-- This fixes forward movement usually causing small amount of turning, since it's impossible to tilt the joystick perfectly straight (reported by @Veer | CMO)

- Merged Spanish locale additions by @Ruz
- Merged Japanese locale tweaks by @Aesc/あすく

[h2]Optimizations:[/h2]
- Small BoundingBox code optimizations
- Fixed forgotten Compound collider test override in BEPUv2, resulting in performance drops in some cases
- Fixed memory streams not being recycled when there are no network streams to encode at given frame, resulting in unecessary memory allocations and additional CPU usage
- Removed unused collider metadata handling

[h2]Bugfixes:[/h2]
- Added a regular stream packet transmission when no other stream packets were sent (typically a headless host), fixing cases where the master clock to drift
-- This should fix numerous time sync issues (reported by @Enverex , @Jolts, @Axius, @AshtonSparx, @Ikani [she/her], @Party_Grunt, GH #2895)
-- E.g. Video, audio, animation playback
-- Audio not playing for some users (reported by @Enverex and @Shadow Panther [RU/EN, UTC+3], GH #2890)
-- Any LogiX using T as the time basis for animating parameters
-- Any time-based driving components - panner, spinner, wiggler and so on
-- Any other time based nodes like Stopwatch or Elapsed Time
- Fixed uninitialized use of data structures in Contact Event Handling
- Fixed disposing of uninitialized data structures in the BEPUv2 integration, potentially causing corruptions
- AudioOutput volume is now clamped before the user volume setting is applied, preventing it from exceeding the user set maximum volume (reported by @AshtonSparx, GH #2894)
- Fixed CharacterEventTrigger & CharcterForceField only responding to Triggers, despite TriggersOnly being false (reported by @Shifty | Quality Control Lead and @Green, GH #2891)


2021.8.27.146 - Character Controller Modifiers, security improvements, bugfixes

Hello everyone, got another physics related goodie for you - Character Controller Modifiers! These new components let you modify the parameters of Character Controller dynamically on contact with a particular collider - e.g. you can make some colliders sticky (slow to walk on and hard to jump), slippery or easy to climb vertically (like ladders) and lots of other cool stuff! With mesh colliders you can even use a texture to modulate those parameters for extra control!

There's a whole bunch of other smaller additions, tweaks, security improvements and more bugfixes based on reports from the community!

[h2]New Features:[/h2]
- Added CharacterControllerModifier components (under Locomotion/Modifiers) which allow modifying character controller properties on contact with colliders:
-- They need to be placed on the same slot as the character collider
-- If there are multiple ones for the same parameter, the behavior can be unpredictable. Please make sure to only have one
-- Following parameters can be modified (some of these both for traction and sliding): MaximumTractionSlope, MaximumSupportSlope, Speed, Force, Speed and MaximumGlueForce
-- Following modes are supported:
--- Override - simply replaces the current value
--- Add - adds the value to the current one
--- Multiply - multiplies the current value with the modifier one

- ConstantCharacterControllerModifier
-- This uses a single value that's constant regardless of where the contact happens
- SubmeshCharacterControllerModifier
-- Specifically for mesh colliders, allow specifying constant value per submesh
- TextureCharacterControllerModifier
-- For mesh colliders only, samples the UV coordinate of the contact point from collision and then samples a texture channel (you can select any) to modulate the final value
-- The referenced texture must be marked as Readable and must be Uncompressed
- Added "Readable" property to StaticTexture2D
-- This keeps the texture data in memory for CPU access. This uses additional memory, but allows components read the texture data for additional features

- Added >, =, - Added >, =, - Added "System Default" language option, which will reset Neos to always use the language specified by the OS locale (requested by @kazu0617 Neos:kazu, GH #2849)
- Added Strip RTF Tags LogiX node that will strip any Neos-supported RTF tags from the input string (requested by @AshtonSparx, GH #2801)

[h2]Tweaks:[/h2]
- Merged French locale update from @Khosumi
- Merged Russian locale addition from @Shadow Panther [RU/EN, UTC+3]
- Merged Czech locale addition from @rampa_3 (UTC +1, DST UTC +2)
- Merged Japanese locale update from @Aesc/あすく

[h2]Security:[/h2]
- SimpleAvatarProtection removal confirmation is now spawned in the userspace (reported by @art0007i, Ticket #892900)
- SimpleAvatarProtection will now self-destruct if removed by the X button in the inspector by the owner. Use the dedicated button for removal of all instances (reported by @art0007i, Ticket #892900)
- Contact status information is now properly sanitized when they're invisible to avoid leaking information that might indicate that they're actually online (reported by @art0007i, Ticket #452151)

[h2]Bugfixes:[/h2]
- Fixed world crash when corrupting the TransformStreamDriver on an user (reported by @LucasRo7, Ticket #887374)
- Fixed DynamicVariables not working for a few frames after duplication (reported by @Psychpsyo, @H3BO3, @Ukilop, @Zyzyl, @orange, @rhenium and yoshi1123_, GH #2012, GH #2860)
- Fixed playback state LogiX nodes not firing a change when the clip stops playing, resulting in a single state change being missed
-- This fixes IsPlaying not forcing an update when the playback stops playing (reported by @Aesc/あすく and kinoko_b, GH #2844)
- Fixed incorrect color value clamping when converting to hex codes, resulting HDR colors in printing out "10" instead of "F" (reported by @Sharkmare, GH #2832)
- Component attacher component labels will no longer be parsed as RTF, fixing cases where generic component braces are interpreted as RTF tags (reported by @kazu0617 Neos:kazu, GH #2805)
- Implemented correct handling of Offset for MeshCollider
-- This fixes random crashes due to corruption of the physics system (reported by @Nicole+ and @Cyro, Ticket #800275)
-- Note that it's recommended to use hierarchy offsets for MeshColliders instead, especially if you want to animate their offset. Animating offset for MeshColliders will force the entire physics entity to be scrapped and rebuilt every frame
- Fixed off by one error when sampling Bitmap2D on the CPU