Wednesday, November 4, 2015

Funnels and Math

The first thing that I noticed after adding the ability for bottles to pour into each other was that it was a major pain to actually make that happen. Since they're bottles, their openings are rather small, and since I currently only move them in discrete amounts its hard to place them exactly where I want them. This means that trying to fill one with another consists primarily of tipping one over and waggling it in the direction of another, hoping their tops happen to line up. This is annoying for testing, and pretty early on reveals a major user annoyance point that really should be cleared up.

My solution, as alluded to by the title, was to add a funnel.
Still liking the glass shader, but perhaps the lighting could be positioned a bit better to show it off here.
Using the power of Duck Typing I was able to simply make the funnel another Lua object that happened to have the same fill and drain methods as the bottle, except draining was a no-op and filling passed the buck onto whatever bottles were below the funnel. Then all I had to do was cram this new object into the same list as the bottles and bam, the funnel can fill bottles below it.



Since I really don't want to go to the hassle of recording video at the moment, you'll just have to trust my word that the bottle on the bottom was empty at some point, and the bottle on the top filled it up. Why would I lie about that, I mean come on.

The problem is that the funnel is just sort of sitting there in space. It gets added to the scene at the start and doesn't interact with anything in any way outside of being used for filling bottles. This means the user can't grab or position it, and could actually look straight through it and move bottles on the other side.



The fact that the funnel is translucent is both good, because it makes it easier to demonstrate how the bottle is being moved around behind it, and bad because it makes it more apparent that the bottle is being moved around behind it. Also, this shows how multiple layers of glass can override each other and it really doesn't look as good. On the one hand if I'm actively trying to add more and more glass things I should make this kind of case look nicer. On the other hand that will involve yet more render target wizardry and I don't quite feel like that at the moment.

In any case, making the funnel interactive was my first priority. The first problem being that the funnel had to scripting to move it around. For this I was able to simply copy over all the grabbing and moving code from the bottles. That was an easy fix, but once again demonstrates how I really should get object oriented features into my Lua code before things become overwhelmingly terrible and maintainable. The second problem was that I had no way to actually tell if the user was looking at the funnel. 

For detecting if the viewer is looking at something, I detect the intersection between a ray coming out of the camera and geometric shapes that are tied to the actors and move with them. When there used to be buttons they had circles attached. The bottles are simplified to just the sphere bulb. I also had stuff to detect triangles and rectangles, because I needed super simple test cases. The common thread among all of those shapes is that it is super easy to detect their collision with a ray. The funnel however can't nicely be broken up into those shapes though, so I had to come up with a new shape.

Pretty apparently, the best shape would be a Frustum (of a cone). (For anyone who doesn't know, that's basically a circular cone but with the tip chopped off parallel to the base). A frustum can be used to represent the actual funnel part. If I want a simple bounding area I can use the whole frustum, if I want to put other things inside a super large funnel I can leave the end-cap circles off and just detect collision with the edges. A frustum whose base and top are the same was secretly a cylinder all along, and a frustum whose top has no radius is just a cone. Its a pretty versatile shape that will allow me to kill a handful of birds with one stone. The only problem is that ray-cone collision involves a good deal of math.

Math!

I was able to find some advice online about how to do ray-cone collision, but most of it was either just source code that I didn't want to copy, references to books I didn't own, or had what seemed to be typos and was a pain to try to parse into something usable for my case.

So I decided to solve the problem myself, 'cause I had to justify my math minor somehow. (Related note, if anyone has any bright ideas as to how I can apply topology to my work let me know, it'll make me feel better). This led to a couple pages of scribbling, and a few equations that would let me find my collisions.

That's not entirely true. First it led me to a set of equations that didn't find the correct collisions but I didn't realize that for about 3 hours. However, eventually I figured it out and now I can add frustums to the list of stuff I can detect in space. Which is neato, and it was actually rather fun to get my hands dirty with pretty dense but basic equations.

Sadly, the next thing on my plate is figuring out why you can see through bottles from the inside. I added a second set of triangles, blender tells me their normals point inwards, but noooooooooo, their winding makes them visible from the outside for some reason. Debugging that involves less thinking and writing and more swearing and glowering, so it'll be a bit more work.

No comments:

Post a Comment