venerdì 30 ottobre 2015

Day 87: Emitters of Emitters

Today I drastically refactored the particle engine, and now each emitter features a GenericMap and 3 lamdas (setup, spawn and particle_update).
By dividing the code in the three lambdas and passing data around with the GenericMap it is possible to build whatever kind of stuff inside the particle engine.
The system is not incredibly immediate if you don't know how it works, mainly because it is built in a very unconventional way, but now it is very well organized and give complete freedom to the game programmer.
For example, I created fireworks with the following emitters:

EMITTER 1:
Lambda creation: Setup yellow spheres, and attach to them EMITTER 2
Lambda spawn: Create the spheres and reset them to the original position/color
Lamda particle update: Move them and scale them up. When they are near their deaths make them invisible and tell EMITTER 2 to activate itself to simulate the explosion of the secondary firework.

EMITTER 2:
Lambda creation: Setup red cubes
Lambda spawn: Create the cubes and reset them to the position of the sphere
Lambda particle update: Move them to simulate the explosion



giovedì 29 ottobre 2015

Day 86: GenericMap

Today I managed to do something pretty interesting, but only partially related to the engine.
I noticed that I often needed to pass different data types from the emitter to the particles, and there is no way to know what will be used inside the lambdas. It is then impossible to decide which parameters to give the particle.
So i decided to write a generic map, which can accept all kinds of data, and you can add them and retrieve them with a string id.
To do so I used void pointers ant templates, and now I have a functioning class that can also be used for other things.
In the picture, instead of making global the cone mesh so that it can be accessed from the lambda, I just added it to the map inside the emitter lambda, and each particle retrieves it inside its lambda and use it to change shape after a certain amount of time.
I also did other little improvements to the engine, for example I added static colors in the color class, so that now I can just type ColorRGBA::red instead of creating it every time.




mercoledì 28 ottobre 2015

Day 85: Math library and Dust

Today I continued to improve the particle system.
First I made a math library, which is something I was willing to do for a lot of time. That's because the cpp one (STL) is pretty limited, and I also wanted a few functions that work with vectors or colors.
I made it as a class and gave it multiple Lerp and RandomRange functions, which are useful in lots of situations, and also in particle systems.

After that I tried to use the emitter to generate a completly different effect: atmospheric dust.
To do so I needed to program the emitter to emit all the particles at the beginning, and in a wide range of different locations. They are also randomly rotated and deformed, to look less like cubes.
The single particle now moves randomly around very slowly.
The performance is quite ok, not great because I used cubes, and every one of them is a whole gameobject (which also cast shadows), while something like dust should be done in a more optimized way.
However I decided to trade performance for customizability in this particle engine, so that is fine.

In the picture you can see the little particles (which actually looks nicer thanks to the bad compression) and there is also a particle very close to the camera which shows how the model is rotated/deformed.


martedì 27 ottobre 2015

Day 84: Lambdas

Today I refactored and perfected the logical division between data, particles and emitters. This was not so easy, because it is not always clear if some property should be assigned to the particle, to the emitter or neither of them.
For example I completly removed the "number_of_particles_per_second" field, which is standard in basically every particle system I know of, because now the control over it is given through the lambda emitter.
In the picture you can see an emitter where:

1) The particle lambda change the color from green to blue, move the particle of a constant speed  and if the lifetime of the particle is greater than 0.6, then the mesh is changed to a sphere

2) The emitter lambda spawns particles in a direction included in a 180 degrees field, and olso reset the mesh to a cube.

By using the two lambdas the possibilities are quite endless. It is also possible to switch them on the fly, even though in that case one must be careful to make them really independent.


lunedì 26 ottobre 2015

Day 83: 3D Emitter

Today I noticed that porting the 2D emitter in 3D is an enormous task.
That's because I need to rewrite the 2D rendering, I need to rotate sprites so that they face the camera and so on, really an annoying work and even if i manage to do that, there are still problems with transparency and the ability to cast shadows.
So I decided to just do a 3D emitter, which cannot spawn as many particles as the 2D one, but there are tons of pros, because I'm going to implement it in a very customizable way.

The idea behind this emitter is:
1) Particles ARE game_objects. So they can have all the components they like, something not supported by unity and (if i remember correctly) the standard classes of unreal engine.
2) The behaviour of a single particle is dictated by a lambda function
3) The particles are spawned by the emitter with another lambda function

The incredible power of doing it this way, is that each particle can have all the components of a game object. This include shadow mapping, specular and diffuse lighting, light emission, and eventually physics in the future. Oh, and since the Emitter is a component, a single particle could emit particles as well.
The behaviours are dictated by lambdas, so that the game programmer can just assing two different functions instead of changing the whole class.
Right now I built the skeleton of everything, except the emitter lambda, which is a little harder.

In the picture are spawned ~10.000 little cubes, with textures, mapping and shadows enabled, and the fps are ~30, which is pretty nice for such a complex emitter.


domenica 25 ottobre 2015

Day 82: Particle System

I took a little pause from the engine both for school reasons and for the disappointment with the GJK algorithm which i just can't fix.
So today I decided to start anew with a particle system. I already implemented something like that for an old 2D engine, and back there everything was really easy, now it is quite complex for multiple reasons:
1) In 3D the particles must always face the camera, which is something not supported by the GUI sprites
2) Transparency doesn't work with deferred rendering, so I'm not really sure that something like smoke will ever be possible to implement without some trick I don't know yet. Full transparecny could be supported though, which is the most important thing.
3) Mesh particle systems would be a nice future add to the engine, because they work perfectly with deferred rendering, and potentially I could create parcicles that emit lights, respond to  collisions (if I will ever have a collision system) or even cast shadows. Of course I won't be able to spawn millions of those ones though.

Right now I just implemented a simple emitter in camera view, it needs tons of optimizations and refactoring, and then I'll try to port it in 3D, which will probably take some time.


lunedì 5 ottobre 2015

Day 81: Other convex collisions

Today I played with the convex colliders I implemented yesterday, and added a cone collider.
As always the collision behaves strngely, sometimes it seems correct, some other times not...
When the collision occurs, the collision is always detected, but it is sometimes detected even if not colliding, and there is no way for a physics engine to tell whether the check was right or not...
I don't really know how to fix this, I'll keep working on it


domenica 4 ottobre 2015

Day 80: Convex Colliders

Today I decided to implement something I wanted to add AFTER making the GJK work.
But since I've been stuck on it for more than a week, I decided to implement this now, because it could also help to debug the GJK.
I'm talking about arbitrary convex mesh colliders.
To do so I added a function to the MeshManager class to load simplified models, beacause the only interesting property is the position of a vertex.
Then I created a ConvexCollider class with the relative support function, and did a general refactoring on the other colliders as well.
I tried to load a cube mesh to see if the behaviour is the same as the AABB collider.
Here is what I observed:

1) AABB-Convex -> works
2) Convex-Convex -> works
3) Convex-Sphere -> Exactly as AABB-Sphere there are false positives....however they occurs in a way slightly different than before, so the bug I'm struggling to find behaves differently depending on how the AABB is implemented, as AABB or as a convex cube.

Except for the last point, which is not what should happen so it doesn't really count, I would say that the AABB and ConvexCube are functionally identical, and other meshes should work as well (not tried yet).



sabato 3 ottobre 2015

Day 79: Problems with GJK

It's been a few days since I wrote the GJK algorithm, but somehow I'm not having progresses, it still have false positive collisions.
The 2D is now correct, but the 3D is still faulty, and all the implementations I found online are identical to mine, so I'm not sure of where the problem lies...