Archive for August 2014
gimbal lock
when throwing my “3d soft” rendering engine together i’d gotten to the point where i could place an opaque aa triangle on the screen.. i then set up some rotation functions and watched my triangle spin around the y axis.
as i added rotation to more than one axis, i noticed that multiaxis rotation resulted in a locked orbit, though the rotation coefficients did tilt the orbit between poles in relation to the rate of rotation. i’d read about gimbal lock a few days previously but it took someone more experienced to point out that this is what was occuring, as at that point in development i was thinking that perhaps i’d misconceived it.. and a few other possibilities.
i had added rotation to each axis as a sine cosine pair instead of using quaternions. my friend recommended i switch to quaternions.
as i was developing casually, often in less than optimal states of consciousness it was probably around 2am half asleep that, from years of audio dsp (and a few simple 3d graphics, like global terrain generation) that my method was fine without quaternions, what i lacked was a state vector..
so i added the state vector (eg. instead of rotating the triangle by a degree, increment a variable for the rotation amount) and that resumed the anticipated rotation behaviour.
so that’s what gimbal lock looks like, and that’s one way to defeat it without quaternions.
aa triangle caveat
recently conceived of making the step to opaque 3d over wireframing. found a popular resource that helpfully defined two cases of triangles (an arbitrary definition but any case of two for triangles applied to a cartesian grid is okay) – when y for points is arranged low to high, the median point is to the left or to the right…
equipped with such a definition one is presented with two cases for procedurally approaching the triangle.. now the left and right borders can be easily defined and intermediate pixels rendered.
to aa my triangles i took the slope from each side and computed the number of pixels width that a 1 pixel aa border would occupy (as a float) so that rendering each aa’ed side is not intensive.
the tutorial i followed, after presenting the case for left pointing and right pointing triangles, rendered them in two stages – top corner to middle corner, middle corner to lowest.. seems a sensible approach, one side on the left, one side on the right…
following this topology, one is then presented with four special considerations – rows containing corners overshot the aa from the opposite side. so i had to rewrite my triangle prodecure, and here’s what i did differently:
there are still two cases, for left pointing and right pointing triangles going by the intermediate y coordinate. however, the entire triangle is rendered in one for loop, which uses the float border value at pixel + 0.5 and uses the slope with the current pixel’s x + 0.5 to determine an aa value for each side..
if the aa value is lower than 0, the point is outside of that side.. if it’s greater than 1, it’s inside that side. then clip them all at [0,1]. instead of attempting to save cycles with sneaky crap like dividing the process at the median y point, do the whole thing, compute all three sides, then go aaa * aab * aac
this will work much better than “efficient procedures” that will fuck up if triangle sides et c. are subpixel, or slopes are almost horizontal et c.
about developing
two patterns
recently upgraded my personal assessment to include the ability to create opaque 3d objects. i realised that conceptually, this stage is often reached about a minute after the ability to wireframe, but for me it took about five years.
sdks infuriate me. generally documentation is terse as effort goes towards the resource itself. i have continually been confronted with some barrier of data that prevented me from some ability. often these barriers are installed for years, eg. the three year wait to install the synthedit sdk with fclt. how was i supposed to know it just goes in the folder.. many requests for assistance ignored. that’s pattern number one – i work merrily when i don’t need someone else’s shit. i’ve now had several compounded multi-year breaches due to lack of transmission of very simple basics.. putting an sdk in a folder makes a lot of sense to anyone used to programming applications that use resources, but that’s never been my style. to save myself additional trauma, i have a very low threshold for shortcomings in documentation, and have no difficulty absolving myself of the responsibility for not being able to parse poor documentation due to the scope of my pursuits.
around 2009 i realised that 3d coordinates could easily be placed on a screen if one simply defines an angle of vision (eg. 180 degrees becomes 1024 pixels, and after that i messed with transforms for better perspective) allowing me to wireframe. i assessed that calculating the angle of reflection would be very intensive using transcendentals, so i decided to adjourn from 3d solids given the madness of attempting it using rudimentary angle calculations with lots of transcendental functions. i didn’t know about dot and cross products. (anyway that’s pattern #2.. creation is much easier once a precedent element is created with which to synthesize relation.. take a step forward.. petition the equation.. the dao of motion and creation. without a frustrum it’s difficult to conceive of how to wireframe).
perhaps if i’d messed with 3d coordinates for some years i would have discovered them. dunno, haven’t tried it. it took me five years because to learn about normals i had to start handling points with classes. before doing this, material was impenetrable due to the class simplifications – 3d can be done without them, and i’ve now seen a few examples of it beyond my own..
of course it is immensely better to use classes, it makes the syntax so much easier. so of course i can’t blame the public for failing to clarify opaque triangles to those who have avoided using classes, and similarly in many cases i can understand why people don’t take time away from their pursuits to facilitate absent informations for aspirants. and of course i can still permit myself to resent obscured resources for Things That Affect People, like windows. it’s kind of socially irresponsible how western forum users demote people for their english and culturally limit the resource, seen it in several fields, but things are getting cooler. (like in audio dsp at kvr there used to be a strong sense of exclusory snobbery, eg. it was considered impolite to give code to programmers who displayed deficiencies in some/other areas.. “if you let them know how, they’ll make some buggy as fuck version and it will affect us all”. here again, the persistence of public contributions has pretty much eliminated any public statements to this effect).
things are getting cooler. i upgraded the 2d vector classes i wrote last year to 3d yesterday, reviewed resources and found several that were “approachable” to me.. most of them created in the last four years.
point of all this.. hope the future is better.. my experience, saying a lot about me, maybe so maybe not.. i have one kind unusual hybrid erudition..
treasure your resources, or appreciate them, when they work for you. the folks who help out. i’ve seen a lot of snakes in the grass, people who trip others up to keep them uncompetitive. it’s been a tough slog, i’ve spent a lot of time staring at very puzzling things (julius o. smith) and it’s been a fight for people to establish cooperative, helpful venues and paradigms.
doing shaded 3d triangles is pretty easy, conceptually approachable by an algebra student. i’m 44, which makes it just over 3 decades of coding for me, and i just got here. many people have made it there before me, but all those fuckers had money, or friends, or someone or something they could understand. i spent years waiting to pay $60 for petzold, and i’m going to get a good 60 years screaming about how the world would be a different place if MS had intended for that text to dispense information easily.
bug in vector.zip source
one of the soundcard callback messages uses WM_SYSCOMMAND. in another app i found this method wasn’t passing other things through WM_SYSCOMMAND (perhaps i had added a break; in the wrong place..?) so that when i added a frame to the window, i was not able to move or maximise it as these were being dumped at WM_SYSCOMMAND.
the few things done in that statement were moved into the next thing that would have been called for them and window could be moved again 🙂 hazards of source..
(laying on back, don’t feel like messing with compiler to fix source, hopefully soon.. itm here’s a note)