x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Calculating the total area painted in game

Hi, I've recently started working on a splatoon-inspired independent project as way of learning more about UE4 and all the things we can do in here. I'm using Render Targets and drawing splatter textures onto them to produce the effect of a paintball hit on the wall. I've hit a snag with calculating how much area each team has painted though. I've never worked with Render Targets before so I don't know what all they have to offer. I also don't suppose I could read the paint material details since there's no communication with the Render Target? I read about ReadPixels() and used it in my code, but it was just awfully slow. Supposing it's just one wall I'm painting on and just this wall needs to be evaluated for the amount of paint from each team, what would be the best way going about this? I also had another idea, although I don't know whether it'd work - what if the game could "see and interpret" the wall as I do? Is there a way I could perhaps take a screenshot of the wall in game and have it process the amount of each color present in it? I looked around on the forums and I did find a way to take screenshots, but they're just saved locally and I couldn't find a way to process them in game.

Any thoughts or ideas or even just brainstorming would be greatly appreciated, since I've been stuck on this for a while. Thanks!

Product Version: UE 4.17
Tags:
more ▼

asked Jun 02 '18 at 02:40 AM in C++ Programming

avatar image

hussainAbis
30 2 4 11

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

If you have the world transform of your surface and the ball, converting them both to local space of the surface would make things simple (so you can perform the calculations in the XY plane as opposed to XYZ)

 FTransform SurfaceWorldTransform = Surface->GetActorTransform();
 FTransform ProjectileWorldTransform = Projectile->GetActorTransform();
 
 FTransform WorldToLocal = SurfaceWorldTransform.Inverse()

 FTransform LocalSurfaceTransform = WorldToLocal * SurfaceWorldTransform;
 FTransform LocalProjectileTransform = WorldToLocal * ProjectileWorldTransform;


In your surface actor have a 2D array and some config values

 const float SIZE = 32;
 float Influence[SIZE][SIZE] // initialized to 0
 int SurfaceWidth = 2000; // in unreal units. fill this based on your art asset
 int SurfaceHeight = 2000; // in unreal units. fill this based on your art asset 
 float ProjectileRadius = 100;

...

 float ProjectileRadiusSquared = FMath::Square(ProjectileRadius);
 for (int x = 0; x < SIZE; x++) {
   for (int y = 0; y < SIZE; y++) {
     // Find the position of the cell x,y in local space
     float u = x / SIZE;
     float v = y / SIZE;
     // uv is between 0..1.  convert to local space coord by multiplying with the surface size
     FVector2D LocalCellPosition = FVector2D(u * SurfaceWidth, v * SurfaceHeight);

     // Find the vector from the cell to the projectile (so we can find the distance)
     FVector2D ProjectileToCell = LocalCellPosition - LocalProjectileTransform.GetLocation();

     // Add the surface local offset as well (depends on the pivot of  your  art asset. needs to be aligned with some testing)
     ProjectileToCell += LocalSurfaceTransform.GetLocation();

     // Find the distance. check with distance squared for optimization (to avoid square root)
     float DistanceToProjectileSquared = ProjectileToCell.SizeSquared();

      if (DistanceToProjectileSquared < ProjectileRadiusSquared) {
           // The cell is close to the projectile.  apply some ramp function to get the influence, or just set it to 1 
           // to indicate the cell has been painted
           Influence[x][y] = 1.0f;
      }
   }
 }


You will run this code only once when the projectile gets destroyed on impact (on the surface that it has touched). So having hundreds of projectiles won't matter

more ▼

answered Jun 03 '18 at 07:48 AM

avatar image

Ali Akbar
691 2 6 8

avatar image hussainAbis Jun 03 '18 at 06:23 PM

Thanks for all the effort you've put in Ali, I really appreciate it. I went through the code you wrote and I understand the logic, seems to be a solid solution. I'll try this out. Again, thanks a lot!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

I'd use the render target only for rendering and the gameplay stats would be saved in a faster data structure in the cpu memory

Create a surface actor that contains a quad and a material to render your render target When the user paints, you probably have some projectile hitting this tile from the game logic that you use to paint on your render target. Use this same logic to also "paint" on a low resolution data grid on the cpu based grid like data structure (e.g 32x32 grid in local memory for a 1024x1024 backing render target). You can find the influence each grid cell will get based on the projectile's sphere radius and the quad's world transform.

Calculate how much area the user has painted in by simply adding these grid cell influences for all the surface actors you've placed on the scene. Since all this happens in the cpu without any texture reads, it should be very fast

more ▼

answered Jun 03 '18 at 02:25 AM

avatar image

Ali Akbar
691 2 6 8

avatar image hussainAbis Jun 03 '18 at 05:33 AM

Hi Ali, thanks for the input. However there are a few things that I'm confused about. Firstly, how are we "painting" on this low resolution data grid? The way I'm making the paintball splats are that I have splat textures, one of which is selected randomly and painted onto the render target using Dynamic Materials. How would this translate onto the low res data grid ? Secondly, with thousands of paintballs being fired per minute, don't you think this process might clog things up? I'd appreciate if you could explain it a little bit. I'm still pretty much a noob.

avatar image Ali Akbar Jun 03 '18 at 07:50 AM

posted as a new answer below due to character limit

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question