Tuesday, August 12, 2014

Eyes Test 3

Alright, I've been struggling with figuring out how I'm going to do layers... I decided I'd take a break from that and focus on 3D stuff. By applying transformations to a 4x4 Matrix (and then casting it to a 3x3 Matrix), I can use it to give the impression that a shape exists in a 3D space.


Oh yeah, I also added in some code for doing gradients. Anyways, I've at least got those things out of the way, so I'll be focusing again on doing layers....ugh.

Friday, August 8, 2014

Layering - a Work In Progress

Hi!

Today I decided I needed to focus on doing proper, optimized layering, but unfortunately it's complicated enough that I feel I need to make sure I have everything written in stone before actually trying to do layering myself. For that reason, I've started a document describing my thoughts and ideas for how I might (and will) go through getting layering to work. It is a WIP, so you might actually catch me working on it in real-time.

Click here to view the document.

I also suspect this will take several days to get in order, which is why I'm posting now as apposed to later when I've finished everything. That way, you can keep an eye on my progress.

Thursday, August 7, 2014

Putting it all together - Eye Test 2

This is the result of everything I've done today. Hot dog, I got a LOT of stuff done today.


I still have a lot of work to do in order for this to be efficient and working properly. It might be necessary for me to do 3D vectors and 4x4 Matrices as well to get things like this eye test to work right, but THAT'LL BE FOR ANOTHER DAY, MKAY?

Parenting

Wow, I never thought I'd post this much stuff in one day.

I've whipped up a class called Entity that serves to contain shapes and other entities. It manages it's own attributes, such as rotation, shear, scale, etc... and can "recursively" draw to the screen in a layered manner similar to how Flash might.

I did a simple test where there's only two entities.
  1. The first entity only contains a red shape
  2. The second entity contains a hollow box, the first entity, and a green shape
I then performed the same test I did the other day with the matrices, but instead I did it on the second entity. The first entity does it's own thing, but is always affected by any changes done to it's parent - the second entity.


Masking - Take 2

Ok, I found a solution. My solution is to type-cast the masked layer's alpha array to contain values of type <type 'numpy.uint16'> instead of <type 'numpy.uint8'>, which allows me to multiply the values of the two alpha arrays without worrying about modulation since 255*255 (the largest value this could possibly produce) isn't bigger than nor equal to 2^16. I then divide the resulting product-array by the value 255, and then finally assign it to the alpha values in the masked layer.

        masked_alpha = pygame.surfarray.pixels_alpha(self.output_layer)
        mask_alpha = pygame.surfarray.pixels_alpha(self.mask_layer)

        new_masked_alpha = numpy.uint16(masked_alpha)
        new_masked_alpha *= mask_alpha
        new_masked_alpha /= 255
        masked_alpha *= 0
        masked_alpha += new_masked_alpha

        del new_masked_alpha
        del masked_alpha
        del mask_alpha


The result is beautiful.


The only complaint that I have about using this method is that since I have to type-cast the one array, the values have to be copied over instead of referenced, which can be SLOW. Even so, I'm very happy with this result since it performs perfectly and is relatively fast.

Masking - Take 1 Analysis

Alright, so I figured out the issue with the first solution. The problem is the values are of type <type 'numpy.uint8'>. What's special about these values is that they're modulated by 2^8, meaning the values wrap around whenever they get larger than 255 or less than 0.

I'll have to figure out a way to get around this issue.

Masking - Take 1

Good morning!

Today I'd like to focus on doing masking. Masking is, by definition, applying the alpha of one image multiplicity to the alpha of another image. To explain this simply, it just means that an additional layer of alpha is applied to an image (even if that image already has an alpha channel), and will only allow that image to show through wherever the alpha is greater than 0 on the mask.

I've already whipped up an example, which I was surprised to find was much simpler than I had expected. As it turns out, the guys who work on Pygame recently added a feature to the surfarray sub-module to allow users to directly reference the alpha pixels of a surface in the form of an array. This is an extremely fast operation since it's merely referencing the alpha values rather than copying them. The fact that they're being referenced is also very useful since any changes done to the values in that array immediately show on the surface.

What I've done is generated the alpha-arrays for both the masked layer and the masking layer and multiplied the masking layer's alpha-array to the masked-layer's alpha array. I then made sure to delete those arrays, since the surfaces remain locked as long as those arrays exist.

        masked_alpha = pygame.surfarray.pixels_alpha(self.output_layer)
        mask_alpha = pygame.surfarray.pixels_alpha(self.mask_layer)

        masked_alpha *= mask_alpha

        del masked_alpha
        del mask_alpha


The result is shown in the image below. The order is masked layer, masking layer, output layer.


For the most part, this does the job as described, but if you look carefully you can see that there's some strange artifacts showing up in the output layer. It's really unfortunate that those are showing up, since this solution is near perfect for what I am doing. Unfortunately, those stupid artifacts are reason enough to look for another solution (or simply a fix to this existing solution), which is why this post is titled "Take 1." I'll see what I can figure out.



Wednesday, August 6, 2014

Matrices

Hi guys. Yeah sorry, I know it's been a while since my last update but I've been busy with life stuff...

Today I focused on learning about matrices and how they're freaking awesome for vector graphics because you can do all your transformations to the matrix first before applying it to a shape. This means you'd only need to do ONE transformation calculation per point, as compared to doing each transformation one at a time for every single point (which can be costly when there's a lot of points and a lot of transformations).

Here's a little animation I threw together where I manipulate a shape using a matrix.


This is also really nice for doing cumulative transformations on children of parent entities - a topic  which will be relevant in the near future. We'd only need to pass down the resultant transformation matrix from the parent to the child when calculating the new shape the child would form after the transformations are applied. This way, any transformations done to the parent will directly affect the child as well.