Jump to content

  • Log In with Google      Sign In   
  • Create Account


Android, Pyweek and Seperate Axis Theorem

Posted by , in Python, Tutorials and Explanations 12 April 2011 - - - - - - · 582 views
Python, pyweek and 6 more...
[BLURB:] Sooooo... Perhaps I should work on smaller projects... hmmm. In any case, spent some time taking a look into python on Android, tried the pyweek challenge, and NAILED THE HELL out of SATs... not the school education kind.

Hmmm... Archetype needs to take a little break (not that I haven't already put it on the back burner). I've thought this many times, but still, I'll say it... I need to work on smaller projects. To that end, I tried my hand at the pyweek challenge that just occurred. For those that don't know, the challenge is to write a game, either alone or in a team, within one week, based off a theme that isn't revealed until the moment the challenge begins. This challenge was "Nine Times".

So... did I succeed...
Ummm, not exactly.

Turns out, having to help move family from one apartment to another takes a hell of a lot of time (8 hours of day 1... lost).
Nine hours a day due to my full time job doesn't help much either.
Then, of course, my father's computer fails two days before the end of the challenge and who's the only one in the family that can fix it? Yeeeah...

None-the-less I still spent most of my free hours working on something, and while I didn't have anything playable until 5 minutes AFTER the end of the challenge, I learned a lot!

One thing I learned was that Android's SL4A is not a viable platform for writing games. I'm thrilled that there's a method for writing applications for the Android outside of Java and C++, but as I looked into the SL4A project, I soon realized that the Android graphics library was not exposed to the scripting languages. This is a HUGE oversite of the project, I think, and, as such, I lost a few hours of the pyweek challenge because I didn't realize this issue until I was preparing to develop my pyweek game on Android. DRAT! With any luck, SL4A will get a graphics hook and then we'll REALLY be cooking! HA!

Pyweek wasn't a total loss, though, as I learned and nailed Separate Axis Theorem collisions!! There's a bit of documentation out on SATs and it's all pretty good, but I figured I'd share my discoveries with my wide blog audience for no other reason than to solidify my understanding of the system.

  • Firstly, I'd like to point out that this is for calculating collisions on 2D objects. While SAT works on 3D, I only really worked with 2D, and that's what I'm working with.
  • Secondly... I haven't worked with sphere (or rounded) objects. It wasn't what I was focusing on when I was developing my application, and so, for the time being, I'm skipping rounded objects.
  • Thirdly, SAT ONLY WORKS WITH CONVEX OBJECTS! These are objects that if you drew a strait line through them, the line could NEVER intersect the object in more than 2 locations regardless of where you drew the line.
What is Projection:
To begin let's talk about projection. What is projection? It's a shadow. For a 3D object projected onto a plane, the result is a 2D shape (or, if you think of the real world... a shadow). For a 2D object, the projection is a line with a length long enough to encompass the entire 2D object when viewed from the axis in which one is projecting.

Well... let's think of a rectangle. The axises of a rectangle are the X and Y axis, and the projection of a rectangle upon the X axis would be the same as the length of the rectangle.

Projection in regards to SATs:
Let's stick with the rectangle for a little while and start talking about SATs...
With the Separate Axis Theorem we can determine if two objects are colliding with one another if ALL of the axises of projection between the two objects in question overlap each other. If even a single projection doesn't, then there is no collision.

Think of the two rectangles... I dare you to try drawing two rectangles in such a way that the shadows on the X axis AND the Y axis for BOTH rectangles touch but the rectangles AREN'T colliding. Go ahead. I'll sit here and wait for you...


No? Couldn't do it? And that's the point. If all shadows for both objects are all overlapping each other, then your objects are colliding. If even a single pair of shadows ARE NOT colliding, then the objects ARE NOT colliding. That's the Separate Axis Theorem. Take your objects, find all axies in which you need to project upon. If even a single axis has a pair of projections that DO NOT overlap, then there is no collision and you're done.

Finding Axises to Project Upon:
Great! Now you may be wondering... "If I'm suppose to project upon some axises, what axises do I need to use?"... As it turns out, the axises you need to project against are simply the normal vectors for each side of your 2D object. Lets look at a little python code that does this...

Code Example: 1.0
# This is a 10x10 rectangle centered at the origin.
points = [[-5, 5], [-5, -5], [5, -5], [5, 5]]

axises = [] # an empty list at the moment

# We loop through the edges of the objects...
# which just so happens to be the same as
# the number of points.
for p in range(0, len(points)):
  if p == len(points)-1:
	edge = [points[p][0] - points[0][0], points[p][1] - points[0][1]]
	edge = [points[p][0] - points[p+1][0], points[p][1] - points[p+1][1]]
  # Now that we have the edge, we need to find it's normal... There're actually TWO
  # normals you can use, depending on if you use the left handed or right handed
  # normal. For the most part, it doesn't matter which you use, as long as you're
  # consistent.
  # I'm going to use Left Handed normals....
  norm = [edge[1], -edge[0]] # Or... (y, -x)... it's that simple.

  # At this point we've found our normal, which is more or less our axis. I say
  # "more or less" only because, for simplicity, our axis should be a UNIT vector.
  nlength = math.sqrt((norm[0]**2)+(norm[1]**2))
  axis = [norm[0]/nlength, norm[1]/nlength] # <--- That's our axis for this edge!
  axises.append(axis) # and we add it to our list of axises for this object.

HEY! HEY! You're example uses a rectangle and creates FOUR axises! When you were talking to us about projection, you said rectangles only have TWO!!!
Ummm... well, yeah, sort of. Because the rectangle has four sides, it technically has four axises in which to test... however, two of those axises parallel the other two. In essence, it's like we have the same axis twice (even though they may both be going in to different directions). To solve this problem, you can change the last line of code above to...

Code Example: 1.1
AddAxis = True

# We need to loop through our existing axises.
for a in axises:
  # Calculating the dot product of the two axises...
  dp = (axis[0]*a[0]) + (axis[1]*a[1])

  # Now we get the arc-cosine of the dot product. If the two axises are parallel
  # then the value of acos will be either a 1.0 or a -1.0  ... so we check the
  # absolute value of the acos to see if we get a 1.0. If we do, we DON'T want
  # to add the axis to the list, since a similar one already exists.
  if abs(math.acos(dp)) == 1.0:
	AddAxis = False

if AddAxis:

Yes, it's a bit more complicated and eats more CPU cycles, but, depending on the complexity of your shape, it shouldn't effect you too much and doing the above would cut down on the number of tests you need to do in the upcoming examples.

One important thing to keep in mind is, we need to calculate the projections of BOTH objects over BOTH objects' axises! We'll see this in Code Example 3.0

Calculating Projections:
So... now that we have our axises in which to test against, how do we calculate out the projection of the object over an axis?
Well... we take the dot product of each point in our object against our axis, storing the minimum and maximum values.

Code Example: 2.0

# These are our minimum and maximum projection values.
# Initially, we don't have any.
proj_min = None
proj_max = None

# We loop through each point in our objects.
for p in points:
  # Calculating the dot product.
  # NOTE: While the axis should be normalized (as we did in Code example 1.0),
  # we don't need to, nor should we normalize the point.
  dp = (axis[0]*p[0])+(axis[1]*p[1])

  if proj_min == None:
	proj_min = dp
	proj_max = dp
	if dp < proj_min:
  	proj_min = dp
	if dp > proj_max:
  	proj_max = dp
projection = [proj_min, proj_max]

Keep in mind, we would have to do with for ALL axises from BOTH objects ON BOTH objects.
I'll explain next...

Putting it All Together... Simply:
So now you see how we get our axises to test upon and how to calculate out projections... let's put it together!

Code Example: 3.0
# obj1 and obj2 are assumed to be a list of points like used in Example Code 1.0
def collides(obj1, obj2):
  # Assume the CalculateAxises function does the same as Example Code 1.0
  # and returns the axises list.

  # Calculate the axises for the first object
  o1axises = CalculateAxises(obj1)
  for axis in o1axises:
	# Assume the CalculateProjection function does the same as Example Code 2.0
	# and returns the [min, max] projection.

	# Get the projection of obj1 over the axis.
	o1proj = CalculateProjection(axis, obj1)
	# Get the projection of obj2 over the axis
	o2proj = CalculateProjection(axis, obj2)

	# Assume the Overlaps function returns true if the two projections
	# overlap and false otherwise.
	if not Overlaps(o1proj, o2proj):
  	# As soon as ONE pair of projections DON'T overlap
  	# we KNOW there's no collision. Done.
  	return False

  # NOPE! Not done yet. We now have to do the SAME THING for the axises of the
  # OTHER object.

  # Calculate the axises for the second object and repeat the same as we did above.
  o2axises = CalculateAxises(obj2)
  for axis in o2axises:
	# Assume the CalculateProjection function does the same as Example Code 2.0
	# and returns the [min, max] projection.

	# Get the projection of obj1 over the axis.
	o1proj = CalculateProjection(axis, obj1)
	# Get the projection of obj2 over the axis
	o2proj = CalculateProjection(axis, obj2)

	# Assume the Overlaps function returns true if the two projections overlap and false
	# otherwise.
	if not Overlaps(o1proj, o2proj):
  	# As soon as ONE pair of projections DON'T overlap
  	# we KNOW there's no collision. Done.
  	return False

  # We've now looped over all axises for both objects. If we're still here, then
  # We've COLLIDED!
  return True

And now you know, using the Separate Axis Theorem, whether or not the two objects collide.
Of course, you usually want to know a little more than that... like, if they've collided, how do you break OUT of the collision? Turns out, that's not too much harder than what we've already done.

Putting it All Together... MTV Style:
No... not the TV station. In this case, MTV stands for Minimum Transition Vector... or, more simply... What's the quickest way out of here!!!

What we want is a vector showing us the way to non-collision safety. All we need for that is axis in which the minimum overlap was found. Lets go to code, shall we?

Code Example: 4.0
def collides(obj1, obj2):
  # These will hold the information we need to find our MTV.
  # For now, they're None... meaning we didn't find anything yet.
  MTVOverlap = None
  MTVAxis = None

  # Calculate the axises for the first object
  o1axises = CalculateAxises(obj1)
  for axis in o1axises:
	# Assume the CalculateProjection function does the same as Example Code 2.0
	# and returns the [min, max] projection.

	# Get the projection of obj1 over the axis.
	o1proj = CalculateProjection(axis, obj1)
	# Get the projection of obj2 over the axis
	o2proj = CalculateProjection(axis, obj2)

	# We're getting rid of the Overlaps function from before, and using the
	# Overlap function (we dropped the 's'). Overlap will return a scalar
	# value equal to the amount of overlap between the two projections.
	# If there is no overlap, then Overlap will return a 0.0
	ol = Overlap(o1proj, o2proj)
	if ol == 0.0:
  	# We have no overlap... meaning we have no collision... meaning
  	# we have NO MTV. We're done.
  	return None

	# Here's where we do some new stuff...
	if MTVOverlap is None:
  	MTVOverlap = ol
  	MTVAxis = axis
	elif ol < MTVOverlap:
  	MTVOverlap = ol
  	MTVAxis = axis

  # Calculate the axises for the second object and repeat the same as we did above.
  o2axises = CalculateAxises(obj2)
  for axis in o2axises:
	# Assume the CalculateProjection function does the same as Example Code 2.0
	# and returns the [min, max] projection.

	# Get the projection of obj1 over the axis.
	o1proj = CalculateProjection(axis, obj1)
	# Get the projection of obj2 over the axis
	o2proj = CalculateProjection(axis, obj2)

	# We're getting rid of the Overlaps function from before, and using the
	# Overlap function (we dropped the 's'). Overlap will return a scalar
	# value equal to the amount of overlap between the two projections.
	# If there is no overlap, then Overlap will return a 0.0
	ol = Overlap(o1proj, o2proj)
 	if ol == 0.0:
   	# We have no overlap... meaning we have no collision... meaning
  	# we have NO MTV. We're done.
  	return None

	# Here's where we do some new stuff...
	if MTVOverlap is None:
  	MTVOverlap = ol
  	MTVAxis = axis
	elif ol < MTVOverlap:
  	MTVOverlap = ol
  	MTVAxis = axis

  # Ok... we've gotten this far, which means all projections overlap between
  # the two objects, so we want to return the MTV. We've already captured
  # the MTV, so we return it as a single vector...
  return [MTVAxis[0]*MTVOverlap, MTVAxis[1]*MTVOverlap]

And we're done... Yeah.. ummm... for the most part...

MTV Directionality:
This little bit caught me for a while when I was figuring this out. I had done everything right, but, when I tested two objects as certain angles, instead of the MTV moving the objects out of collision, it'd send them further IN! It had occurred to me, after a couple hours of frustration, that... What is the MTV was pointing in the same direction as the colliding object.

First thing I had to realize is that the winding of my object's points were important. Meaning, where they clock-wise or counter-clock-wise. For instance, for Code Example 1.0, the points in the "points" variable are counter-clock-wise. There's probably ways to determine this programatically, but, for simplicity, just say all objects must be drawn in the same winding. In my case, I was drawing in a CCW direction as well, so...

I thought to myself... "self", I said, "during the collision, one object has to be moving and the other not" (simple situation). So, I decided that I would calculate the vector between the two objects...

vector = collideeObj.position - colliderObj.position

...and normalize it...


Then I would get a normal vector of my MTV...
MTVNorm = MTV.normalize(returnCopy=True)

... find the dot product between my direction vector and my MTV vector...
dp = vector.dot(MTVNorm)

... and, for CCW winding...
if dp < 0.0:
  # This inverts the vector. Same path, different direction
  MTV = -MTV

... and finally, reposition the collider by the MTV
collider.position += MTV

And there you have it! OBJECTS COLLIDING PROPERLY!!

Like I said, this works for N-sided objects. I didn't even look at rounded objects because I wasn't focusing on those (I was pressed for time). Also, the objects MUST be CONVEX objects, but that's more a caveat with SAT than my code. Lastly, there's no compensation here for fast moving objects nor complete inclusion (one object totally within another).

If you want to do concave objects, simply create a group of convex objects and treat them as one object, except during collision testing.

I hope at least someone finds this useful... but, at the very least, I can always look this back up if ever I need to code up SAT objects again. If anyone would like, I could post up a simple example program (in python), but for now, I need to eat dinner. :)

4X development and holding on Archetype

Posted by , in Archetype Engine, Linux, Personal Side, Python 20 March 2011 - - - - - - · 574 views
4x, python, Archetype, galaxy and 5 more...
[BLURB:] Working on a 4X game, and the Archetype Engine is on hold thanks to the flipping camera! Also, my job goes from part time to full time and I've been exhausted!

[DEVELOPMENT: Galaxy vs Archetype]
It's a bit of a bad habit of mine. I'll work on a project for about a month or two, then I want to try something else. Actually, this only happens with my own personal projects, thankfully, and not those I do for work, but still, it's annoying.

In terms of the Archetype engine, my VBOs have kicked my butt and now my camera... which I had thought was rather stable... turns out to be far from. Having spent a solid week trying to get it to work right, I'd decided to put Archetype on hold for a little while and switch over to a new project that, in time, should easily be mergible with the Archetype project. Ok, so I'm legitimizing the switch by thinking to myself that I'm just working on another aspect, but whatever...

To anyone that reads this journal, you may have remembered one of my last posts saying how I was looking at playing some 4X games, but couldn't find one to satisfy me. To that end, I have started working on a project called "Ships"... weak title, I know... which will serve as part one of my 4X development. What Ships will be, is the "ship designer" portion of the 4X game. When the game starts, players will be presented with a ship designer and a starting sum of Production Points in which to assemble a fleet. The player will be allowed to design as many ships as they want, but their fleet would be limited to the number of production points available. Once the player as designed their ships and/or assembled their fleet, they then choose another player's fleet to compete against. At this point, the game will switch to the tactical portion of the 4X game, in which the two fleets do battle.

At the moment, I've been poking at the game for about a week. I have written a custom config loader and a language string loader (for internationalization of the application). I'm currently working out in my head how I want to handle error handling and logging. I'm pretty sure I'm going to use Python's logging module, just not sure exactly how I want to integrate it.

Oh... silly me... Ships is the name of the demo/game that is the first part of my 4X project... Galaxy is the name of the library I'm writing for the 4X game(s). Galaxy contains the currently developed config loader, language loader, and component manager currently developed. I'll be uploading the git repo of the game(s) to gitorious soon.

[BUT WHY?!:]

Like I said, I had a powerful hankering to play a 4X game, and there's so few for linux. Ok, to be fair, I wanted to play a 4X SPACE game, and there are so few of those. I looked into FreeOrion, but, sadly, the forums almost seem dead. The game runs fine, but seems empty of any actual life. More like a tech demo at the moment. Again, to be fair, this tends to be the case for a lot of unfunded open source games... and mine may even end up that way itself... but still. I tried playing some 4X games from Windows through wine, but, between incompatibilities with wine and a current dislike of microsoft at the moment, I couldn't play any of those.

And so... I try to write my own. Still hard because I really want to PLAY the game. Eventually, I hope that'll be the case.

[Personal Side:]
Development on any of my projects has also taken a bit of a hit recently because as of mid February my part time job as database developer turned into a full time job as a database developer. I'm very happy about that, but the new hours are tiring me out by the end of the day. Once I'm home I usually just want to veg on the couch and watch TV or play XBox (yes, I know that's a little hypocritical after my previous statement about not liking Microsoft, but sue me, I'm human). Even on the weekends, once I've finished the errands I need to do, I'm ready to just relax and let my mind drift.

I'm sure I'll adjust to the new schedule eventually and be able to get a little more personal project development in as time goes by, but still... things are a little slow at the moment.

Holy moley! You're still reading this? Ha! Thank you.
I hope to have more interesting news as time goes by. Catch everyone next time!

Textures and Blenders

Posted by , in Archetype Engine, Python 24 February 2011 - - - - - - · 441 views
Textures, OpenGL, Blender, OBJ and 1 more...
[BLURB:] Ummm... Yup. I have textures and I export from Blenders :D

[DEVELOPMENT: Archetype Engine]

Ok, so I haven't been saying very much this month. I had a bout where I REEEALLY wanted to play a good space based 4x game, but failed to find one that fit my desire. After that, I tried X2: The Threat on Linux. Fun game, but a little too pricey at the moment for me to buy. This lead me to Freespace2 Open. FUN Game. Which just lead me back to wanting to continue my engine. Every false start I had in finding a game to play just kept me saying "well, I'll just make one, then"!

I have a few new ideas kicking around in my head. My original idea is still a goal of mine, but I have new side realms to venture into with my engine as I develop it. Heck, nothing wrong with multiple projects. Anyway... A couple of days ago, I finished writing my first Blender exporter for 3D models. Nothing fancy yet. All it exports are the basics (verts, tex-coords, norms, and faces) and exports them into a OBJ-ish plain text format (I do seem to love adding ISH to all my stuff). Ironically, I haven't written a loader for my engine to load the model file yet because I'm still ironing out the details on how the graphic submodule (which I'm now calling "occular" instead of "view") is going to be organized.

Along THAT line, I finally added textures. The demo I wrote it VERY simple. It creates a basic one color texture. I'll probably expand on that as time goes on, but image loading DOES work.

And... that about wraps up this update.

Gah! Almost two weeks!

Posted by , in Archetype Engine, Personal Side, Python 09 February 2011 - - - - - - · 409 views
4X, Python, Archetype, RPG, VTT
[BLURB:] Not dead yet!


Ok, I haven't worked on Archetype for almost a week because my favorite RPG table top group suddenly finds itself GMless and I decided to try giving the job a go. Not that I've actually started GMing. It's an online group that used a virtual table top (VTT) and I've been spending a week organizing, to the best of my abilities, stuff for my campaign. With any luck, it'll be worth the time put in.

On top of that, I've suddenly developed a hankering for Space Opera 4X gaming again and, while MOO2 has been helping, I've really developed an urge to try my hand at writing a 4X game. Gah! I hate when my brain does this. But, if I don't sidetrack a little, I'll loose all concentration for any project (the "run and hide" way of dealing with things), so, I figure working on 2 code projects is worth trying. Besides, the code from the Archetype engine could be used for the 4X I'm thinking of... if not in whole, then in part.


Which leads to a question I've been pondering. Thus far I've been working on Archetype's graphic system. Currently, there's nothing about the graphics system that makes it unusable by any style of game. As such, I've been wondering if I should split out my graphics from Archetype into another library, or just copy the graphic code from Archetype and past it into whatever 4X engine I decide to write. Of course, this question may mean that I have a flimsy idea, over all, on what exactly an "engine" is and what makes it different than a "library" or (in Python terms) a "module".

In any case, I'm still hacking away at my code.

Possible VBO Victory!

Posted by , in Archetype Engine, Python 30 January 2011 - - - - - - · 579 views
Python, pyopengl, OpenGL and 3 more...
[BLURB:] I think I may have successfully discovered how to integrate VBOs into my library!

[DEVELOPMENT: Archetype Engine]

Having gone round and round and round the google merry-go-round in regards to VBOs with pyopengl, I FINALLY figured out how to get my hands on glGenBuffers and why my tests for always failed! Ok, it seems my drivers (both for my modern ATI and generations old NVidia) do not support glGenBuffers directly. Making the following call...
... would always return False for me. Ok, so, I must have to use the ARB version of the call. However, every test I made to find a valid implementation of glGenBuffersARB would, likewise, fail! I took this to mean I did not have access to the extension for vertex buffers.

Here's where my mistake was (or seems to be)...
My tests involved calling up the python console, importing the modules, and testing for the existence of the functions I wanted. What I didn't realize is, what I needed to find the extensions in the first place was a VALID CONTEXT!!! More or less, when I was running python in the console, I was never creating an OpenGL context, so all of my tests would fail because none of the extensions would load. Once I did my tests with a context created, I was able to find an implementation of the glGenBuffers function...
from OpenGL.GL.ARB import *

Unfortunately, I've been under the weather the last couple of days and haven't been able to concentrate real well on coding, so, all I've managed to do was start a shell of a VBO class. When done, my VBO class will match my VAO class, allowing me to use either interchangeably, allowing me to adapt the engine for systems that may not support VBOs at all.

May the force be with me! And also with you :D

ATI hate me, I think.

Posted by , in Linux, Archetype Engine, Personal Side, Python 27 January 2011 - - - - - - · 733 views
ATI, NVidia, OpenGL, pyopengl and 6 more...
[BLURB:] A choice made 5 years ago is not effecting my 3D ENGINE!!! Grrrrr.... Have to put VBO development on hold! Grrrrr.... Vertex Array Object works like a charm... YAY!

[DEVELOPMENT: Archetype Engine]

Ok, I busted my mental hump trying to figure out VBOs. For PyOpenGL, most documentation on the subject is almost three years old and given as a code snippet at this website. The problem is, when I tried using that code, glGenBuffers would fail. It's either claim I was passing 2 arguments when it only wanted 1, or that the function didn't exist at all! Grrrrrr!!!!! After well over five hours of painful googling (all hail the Google) AND upgrading my copy of pyopengl from 3.0.0 to 3.0.1 I have generally narrowed the issue down to my ATI drivers... or, at least I believe that to be the case.

See... I'm running on Linux; Ubuntu 10.04 to be exact, and, in general, ATI doesn't think very much about us Linux people. Arguments for the ATI mentality aside, the result is, the ATI drivers for Linux are not as good or as up to date as those on Windows. As such, I wouldn't be surprised if the implementation for VBOs wasn't completed in the Linux ATI driver and that is what's giving me my issue. I could be wrong, but I can't think of an alternate reason at the moment.

So what does that mean over all? Does that mean I cannot code VBOs into my engine? HELL NO it doesn't mean that! It just means I have more research to do. I'll have to look into the extensions method for vertex buffer objects and do something like:

if not bool(glGenBuffers):
	glGenBuffersARB(1, buff)

Not to mention having to deal with the case of whether or not the extension exists or not. There's ways around it, I suspect, but to get VBOs up and running, I have a lot more reading to do.


Open Hardware! We have open source software and open hardware exists to a degree (gumstixfor instance). I would LOVE to see an open hardware graphics card! I know, I know... that's a hugely tall order, but think of the total win factor such a device (and the company that produces it) would have if it were done! A hardware device that could be plugged into any computer (mac/windows/linux/other) and have drivers available. If drivers aren't immediately available, the specs are open for driver developers to plunge right in and code some up! No more half-assed features from one OS to another.

Yes... before anyone decides to flame me for what I'm saying, I'm well aware that this is more a dream than anything that could be set into motion. I'd love to take a crack at it, but I am so completely not a hardware guy. Not even to mention ATI and NVidia are so far ahead of the game in terms of graphic processing hardware that any small time company looking to start would be entering with hardware, more than likely, a couple generations behind (or more) and would more than likely collapse due to the imbalance of those who would buy the hardware to support it and the ideals, and those that wouldn't because it wouldn't be able to run the top tier games.



Thank you for playing, please come again :D

Working the "view"

Posted by , in Archetype Engine, Python 25 January 2011 - - - - - - · 479 views
Archetype Engine, OpenGL, Python
[BLURB]: Studying VBOs and trying to determine the best method for rendering.

[DEVELOPMENT: Archetype Engine]

Yes, to be perfectly honest, I've been a little lazy the last few nights. Not that I haven't done any work, but it's been light; reordering classes and files, mostly.
That said, some of the reason I've slowed is I'm trying to wrap my brain around a decent method for rendering geometry. Ok, it's a little more detailed than that, so, perhaps I'll break down the dilemma... I want to keep my "data" and my "renderer" separated, that's just good programing, but there are some points where it gets a little fuzzy on how to do that. For instance, 3D models. Obviously the model loader doesn't need to know anything about the renderer, but the data it loads (vertex, normal, color, tex, etc, etc) is, almost exclusively data used by the view. As for as the logic of the engine is concerned the geometry information doesn't exist. Yet, I know I want to setup a difference between the model data and an "instance" of the model, allowing, for example, two instances to share the same base model, but have two different animations running. When I think of this, it sounds like I should make the "base" model part of the "data" of my engine and the instances part of the "view", but, still, the base model would only be for the view's use, so should it also be part of the view?

This leads to other issues in which I'm trying to do a bit of homework and, as such, has slowed down my work. The slow down is for the better, I suppose. Nothing worse than diving right in then finding I'd need to completely rewrite the engine because I missed something. On the other hand, I hear it's better to just get something working, and worry about refining it later... I mean, tons of developers find they have to start over a few times. Ah well, I'll figure this out eventually.

If anyone has any suggestions I'm more than willing to hear them out! :D

Short post... no screen shots... ahh well.

Bug fixes... and a Screenshot Part Duex

Posted by , in Tutorials and Explanations, Archetype Engine, Python 21 January 2011 - - - - - - · 440 views
OpenGL, LookAt Matrix and 2 more...
[BLURB]: GOT YA! My camera works, finally! I fixed the rendering of the camera too, so it LOOKS like a camera. Nailed an interesting bug in my vector classes, and all is right with the world... oh yeah, another boring screen shot!

[DEVELOPMENT: Archetype Engine]

The blurb basically sums up the massive part of my work. Basically, the camera was screwing up on me. You have ANY idea how much of a PAIN it is to get the horizontal and vertical angles between two objects in 3D space?! Suuure... the arc tangent of the cross/dot products for each of the two planes the objects are sitting on... except one of my objects was sitting at the origin, and, the dot and cross products in that case BOTH come out to zero, so BOTH angles were coming out to zero.

Before anyone points it out, yes, I know that method is actually for two VECTORS not 3D coordinates (well, I know that now, anyway... sue me, my math is a little rusty), but even treating the vectors as two 3D points, I get one accurate angle but the other (the vertical angle), which should be ZERO, flip flops between zero and 180 depending on the quadrant the non-origin object is sitting. Technically, that flip-flopping is mathematically legit, but NOT useful at all!

I wanted to use these angles to generate rotations that I would then enter into a quaternion to generate a rotation matrix... lol, laughable, I know! Then, it hit me... how does gluLookAt generate it's matrix. Soooo... all hail the Google, I looked it up and found a simple formula to generate a rotational transform matrix given an eye, a target, and an up vector (HEY! That sounds like what gluLookAt wants!! Why yes, good sir or madam, it is, that's not the point, moving on please). I will post the method at the end of this entry just for those programmers green enough (as I am) to not know the method by heart, because I know the pain of looking for the answer and you seem sooo close and then the jack-a-mole website you find doesn't tell you!

Anyway, here's a new screenshot of the camera demo...
Posted Image
The demo actually works too! The redish objects are the cameras. Both cameras are set to look at the white cube in the middle. Pressing "W" or "S" will orbit camera A around the cube, while "A" and "D" will orbit camera B around the cube. Very fun... very exciting... will add more depth to this demo over time.

As always, anyone who's interested in downloading and working with the code can get their hands on it here at gitorious... I'm actively working on the development branch, so, if you're looking in the master branch and wondering where everything is, it's still all in the development branch :D

[TUTORIAL: "LookAt" 4x4 Rotation Matrix Method]

Assuming you have 3 3D vectors, eye, target, and up, where eye is the position of your camera, target is where you want your camera to look, and up to the upward vector of your world, then...
NOTE: up vector should be normalized

vec3d zaxis = normalize(target - eye)
vec3d xaxis = cross(up, zaxis)
vec3d yaxis = cross(zaxis, xaxis)

matrix = xaxis.x, yaxis.x, zaxis.x, 0, # Row1
xaxis.y, yaxis.y, zaxis.y, 0, # Row2
xaxis.z, yaxis.z, zaxis.z, 0, # Row3
0, 0, 0, 1 # Row4

NOTE: For the matrix above to work in OpenGL, the array containing the data is in column order...
Array Index: 1, 5, 9, 13, # Col1
2, 6, 10, 14, # Col2
3, 7, 11, 15, # Col3
4, 8, 12, 16 # Col4

Hope that's useful to someone. Forgive me if it's a little confusing, I'm tired and not thinking with all synapses.

Bug Fixes... and a Screenshot!

Posted by , in Archetype Engine, Python 19 January 2011 - - - - - - · 354 views
Archetype, demo, screen-shots and 1 more...
[BLURB]: What can I say? Bug fixes... and a screen shot of a BROKEN demo :)

[DEVELOPMENT: Archetype Engine]

Still a number of bugs to clean, but I fixed enough of them to get something drawn on the screen now, and it's easier to see the two viewports. Camera's still a LOT funky, though, so a bit of work needs to be done. I DO have a screen shot, however, since someone wanted to see one. Not impressive, but...

Posted Image

Hope you enjoy! :D

Technically... a demo is written... errr....

Posted by , 18 January 2011 - - - - - - · 325 views

[BLURB]: Viewports and camera and demos... OH MY! Ummm... but demo doesn't work yet... lol!

[DEVELOPMENT: Archetype Engine]

Nothing major to talk about this blog, but I felt I should keep anyone who's still watching this journal apprised... I not have a "viewport" class that handles viewport setup for rendering. It does a little more than simply opening a view port. It can be configured to use "relative" positioning and sizing, and handles the "VIDEORESIZE" event. As such, one can create a viewport that should appropriately adapt it's dimentions and, even position relative to a resized window. Note that I said position... multiple viewports are supported and can be placed in "relative" locations using a 0.0% to 100.0% location scale. Also, position can be based on the center of a viewport.

Of course, that all sounds spiffy, but the one demo I have written now shows a blank, empty blackness (no, it's not suppose to be blank). Therefore, bugs are still abound in my code. However, seeing as I've been writing everything into the library without time to test each unit (horrible of me, I know), I'm actually happy I was able to get a runnable demo at all... yes, it's runnable. A window of the correct dimensions appears and when you press the escape key it closes, as it should. I just need to figure out why my camera wire frames aren't appearing. Ahhh well. Next couple of days I should know.


Just want to thank anyone still reading. Long way to go in general.

January 2017 »

151617 18 192021

Recent Comments