Block Selection

Mike Kienenberger

Active Member
Contributor
Architecture
GUI
I took a look at the block selection code today.

What we currently had in engine was very specialized: based on the local player activating an item and always rendered, and only one selection could ever be in effect.

I separated it out into two new base systems and reworked the current functionality to use those two base systems in a way that should be completely backwards compatible, although I suspect a more optimized approach might be possible.

synopia did most of the hard word. All I've done is reorganize it.

The base BlockSelectionSystem simply tracks block selections for BlockSelectionComponents. A LocationComponent sends a BlockStartSelectionEvent with a reference to a BlockSelectionComponent. The BlockSelectionComponent is updated with that location as a starting point and the selected region as that single point. Another (or the same) LocationComponent sends a BlockEndSelectionEvent to set a second selection point which resets the selected region. BlockSelectionCompletedEvents and BlockSelectionStartedEvents are sent out as appropriate.

A BlockSelectionRenderSystem will draw any block selections which have been registered for rendering. Currently they all use separate instances of the original block selection renderer class, but there's no reason why that instance cannot be customized or replaced with an alternate renderer. Register block selections with RegisterBlockSelectionForRenderingEvents and UnregisterBlockSelectionForRenderingEvents.

LocalPlayerBlockSelectionByItemSystem imitates the original functionality by working with the base BlockSelectionSystem events.

Here's a good branch for merging these changes.

https://github.com/mkienenb/Terasology/tree/component-based-block-selection
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
Thank you! Better selection is one of the key foundation pieces we need to do fancier stuff like having the player designate "rooms" and stuff like that :)

I meant to badger synopia about that sometime but this works too :D

Am oddly curious to see random color selection added sometime.
 

Mike Kienenberger

Active Member
Contributor
Architecture
GUI
Yes, that was exactly my thought. Since so many of the things I'm looking at are waiting for NUI, I figured I'd see what can be done to have "invisible" npc entities just start digging out designated areas, or perhaps computing their own designated areas to perform work in.

I only gave the SelectionBlockRenderer a passing glance, but I'd guess that @synopia's code can easily be expanded to provide different colors. The Block Rendering System was definitely set up to support independent renderers for each block selection.
 

Mike Kienenberger

Active Member
Contributor
Architecture
GUI
Block selection now supports picking the color of the block selection renderer (and there's a new programmable ColorTexture class for general use). I still need to pass in the color as part of the render registration event, and then I think this will be ready for general use and integration into the develop branch. For now, there is a set of predefined primary colors, and the color cycles with each new selection started -- just for you, Cervator :)
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
(and there's a new programmable ColorTexture class for general use)
Shouldn't need this. You can just create a TextureData of the correct color and generate a Texture asset from it, or the color could be a parameter of the Material used to render the selection.
 

synopia

Member
Contributor
Architecture
GUI
Hey, great to see, someone took over this topic ;)

The original BlockSelection code was quick and dirty to just get some blocks highlighted somehow. I have another render component, which uses this class internally. I suppose, I can drop this and replace it by your changes. Will do that soon ;)
 

Mike Kienenberger

Active Member
Contributor
Architecture
GUI
Shouldn't need this. You can just create a TextureData of the correct color and generate a Texture asset from it,
You're right. If you look at the ColorTexture class, that's exactly how I did it. ColorTexture just encapsulates this behavior, since the actual creation of the TextureData from a Color value isn't trivial for most people.

or the color could be a parameter of the Material used to render the selection.
I had forgotten that Materials can specify a texture by color as well as by external file. The only other project that I worked with materials only used texture data from a file. I guess it doesn't matter too much which way it's done, but the current renderer uses Textures directly. There may be other use cases down the road where we programmically create a Texture that neither rely on external files nor a solid color, and ColorTexture is a good example on how to create one.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
I had forgotten that Materials can specify a texture by color as well as by external file. The only other project that I worked with materials only used texture data from a file. I guess it doesn't matter too much which way it's done, but the current renderer uses Textures directly. There may be other use cases down the road where we programmically create a Texture that neither rely on external files nor a solid color, and ColorTexture is a good example on how to create one.
Materials don't specify textures by color, the color is a modifier that is used instead or as well as a texture - and that is entirely shader dependent anyway. (Materials are shaders combined with parameters).

I think having a ColorTexture class is a bad example of how to create one. You should not be creating new texture classes, and especially not by extending OpenGLTexture (which isn't exposed for mods, and really should be marked final). The intended mechanism is to generate a TextureData, and submit it create a Texture via Assets.generateAsset() or the asset manager. This allows whatever render is in use to create the correct texture subclass for itself. This will be important for a dedicated server (which will be using a NullRenderer, and will have no OpenGL context, so the ColorTexture class would crash it). I would suggest a static utility class or factory class instead.

You could also register an AssetResolver with the AssetManager that will resolve generated color texture URIs by generating a color texture as necessary. This also allows the asset manager to take care of caching and lifecycle management.
 

Mike Kienenberger

Active Member
Contributor
Architecture
GUI
Materials don't specify textures by color, the color is a modifier that is used instead or as well as a texture - and that is entirely shader dependent anyway. (Materials are shaders combined with parameters).
My mistake. What little I know about "Materials" is based on parsing/generating the .obj/.mat file formats, and the .mat file formats have a color option as well as a texture option from what I remember.

I think having a ColorTexture class is a bad example of how to create one. You should not be creating new texture classes, and especially not by extending OpenGLTexture (which isn't exposed for mods, and really should be marked final). The intended mechanism is to generate a TextureData, and submit it create a Texture via Assets.generateAsset() or the asset manager. This allows whatever render is in use to create the correct texture subclass for itself. This will be important for a dedicated server (which will be using a NullRenderer, and will have no OpenGL context, so the ColorTexture class would crash it). I would suggest a static utility class or factory class instead.

You could also register an AssetResolver with the AssetManager that will resolve generated color texture URIs by generating a color texture as necessary. This also allows the asset manager to take care of caching and lifecycle management.
Thanks. That makes perfect sense in retrospect. While what I had meant was "a good example of how to create TextureData", I hadn't considered some of the other problems my approach was going to cause. I'll rework the registration/creation of the texture using your suggestions!
 

Mike Kienenberger

Active Member
Contributor
Architecture
GUI
Here's the newly-improved Color Texture support.

I see I need to rebase my commit so it doesn't include everything else, and that I probably need to reformat some code (editor added some empty lines to TerasologyEngine and I likely have tabs in my other files), but I'm out of time for tonight.

Immortius, can you take a look and see if it's on the right track? Here's the specific commit containing only the files relating to color textures.

https://github.com/mkienenb/Terasology/commit/086d9751846fba200812840ea6a4c4edf3b7f8a8

This code works for the Maze module when using Assets.get(TextureUtil.getTextureUriForColor(color), Texture.class)) to fetch a Texture.

I will probably also write some unit tests for this piece as well before finalizing it. And I still need to determine if I can use guava's UnsignedBytes.checkedCast as well.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Looks like it is on the right track to me. Not sure which Color implementation would be best though (this is a bit of a mess throughout the engine), I guess I'm thinking ultimately the NUI implementation. Note that nui's color has toHexString() so that saves you about 25 lines of code. Likewise you can use new Color((int) Long.parseLong(value, 16), true) to go from string back to the the awt color, or the same for a nui color without the boolean.
 
Top