|
roomforthetuna posted:Given that you're apparently wanting it to be possible for an object to be halfway pushed through a portal, how do you intend to resolve the gravity for that object? Just switching as its center of mass goes through, or would it have gravity acting in two directions on it such that it might start spinning? Just a center of mass switch - my concept doesn't require that something will be pulled in two separate directions simultaneously by gravity. Think of it more as you start on the floor, walk through a portal, and now you're walking on the ceiling. To the player it should seem as if they just walked through a door, so having gravity apply conflicting forces would actually break that feeling. I'm not sure I understand entirely what you mean - have the game create a second object on the other side of the portal if one is in the process of passing through but hasn't actually "teleported", so that it will appear on the other side as it intersects the rendertexture, or is there some way to get the engine to actually render an object simultaneously in two places? If the latter works that would be ideal. One solution I've been thinking about is to have a mobile "transition" room that sits at each doorway. It would have a rendertexture on the far wall of the small room that would display the other side of the portal, and instead of having the player pass into the portal to teleport, the transition room and everything in it will swap positions with another transition room to deposit the player at the actual location the rendertexture depicts, with the transition room spun around so that the area the player is viewing is now the actual main room, and the rendertexture is displayed behind them, showing the area they just came from. The main reason the whole room is moved rather than just the objects in it is because this would allow objects the player is pushing along to transition more smoothly, since the room would only move when the PLAYER crosses the threshold. Presumably this implies that the room would have to be large enough that an object fits neatly in the room as the player enters (the rendertexture on the far wall could also teleport objects and projectiles if they collide with it and the player has not entered the transition room, since the teleporting would be less noticeable when the player is farther away). It would be a smoother transition, but it would require every doorway to be unusually deep in order to fit the player, and it might cause issues with any physics objects that are straddling the edge of the room when it moves. I would still prefer a solution that allows for smooth portal behaviour without having to kludge it together.
|
# ? Jun 26, 2011 02:50 |
|
|
# ? May 18, 2024 06:58 |
|
The Cheshire Cat posted:I'm not sure I understand entirely what you mean - have the game create a second object on the other side of the portal if one is in the process of passing through but hasn't actually "teleported", so that it will appear on the other side as it intersects the rendertexture, or is there some way to get the engine to actually render an object simultaneously in two places? If the latter works that would be ideal. But yes, making it into two objects while it passes through a portal was also an option I was thinking of when suggesting that, if the engine can't do it any other way.
|
# ? Jun 26, 2011 03:30 |
|
This is all to recreate the final scene out of Labyrinth, isn't it? To stay on the game dev topic, any people here familiar enough with flixel to give me some help on how to do things like pixel perfect terrain collisions and different types of terrain (like water for swimming)?
|
# ? Jun 26, 2011 03:59 |
|
I have a rather puzzling problem relating to constructing an AABB tree and its peformance, it seems to be far too slow. Firstly some information about the tree. It is a binary tree and built by inserting element one at a time. Data is only stored in leaf nodes, all other nodes just bounding boxes. When inserting an element, if the current node is not a leaf node, the current nodes bounding box is enlarged so it is big enough to contain the element being inserted. Then one of the two child nodes is chosen by checking if the inserted element is inside the bounding box of one of the two child nodes, if it is it gets sent down the respective node. If it is not inside either but it is intersecting then it chooses the one it intersects. If it does not intersect either of the nodes then it calculates the manhattan distance between the centre of the child nodes bounding box and the centre of element to be inserted bounding box. If the distance is greater it chooses the node with the greater manhattan distance. For whatever reason this seems to give better performance than checking if it is less. The performance does not seem to be very good overall. There is, up until around 14000 elements in the tree, better performance simply by comparing a given AABB against every other AABB. Even then it is only a ~100ms difference of ~700ms vs ~800ms. I am assuming there is something wrong with how I insert things into the tree. Anything I can find on building AABB trees is either how to build them if you already have all elements in advance (not in this case), or the algorithm given is similar to what I already do, but chooses the child node based on some mysterious unexplained cost function. One suggests manhattan distance but as I have said it strangely gives better performance choosing the further node. Thoughts anyone? edit: found and fixed a bug to do with the manhattan distance check, which (sort of) explained why at the time choosing the further distance made it faster. Now it is checking which is closer instead of further away, which is obviously correct. The time is now down to ~400ms vs 800ms. I still think it could be faster. It seems that having a good cost function is key to performance. FlyingDodo fucked around with this message at 18:37 on Jun 27, 2011 |
# ? Jun 27, 2011 18:19 |
|
Have you tried outputting any data on the tree? You want to have a look at how deep it is, and how many entities each leaf node contains. Generally you want to have your entities spread fairly evenly throughout the leaves, since your tree does very little good if 90% of your entities are all in the same leaf. Also, if you have a malfunction building the tree, you may end up with a tree thousands of layers deep (also bad).
|
# ? Jun 27, 2011 21:40 |
|
I've recently come across this problem: (Please ignore the temporary textures, ty ) The back/lower side of the mountain is "clipping through" for what I think is culling or the Z-buffer are getting thrown off. I recently added the skybox, but I've turned it off/on just to check, but no go. Even while it was on, the old terrain never clipped through itself. I actually glue'd in my previous terrain generation/vertex creation code and it still didn't work. So, I'm looking for suggestions and ideas on whats up. (Coded with XNA) I swear I had this problem before, but forgot what I did to fix it then... dereekb fucked around with this message at 01:49 on Jun 28, 2011 |
# ? Jun 28, 2011 01:29 |
|
It looks like alternate triangle strips are having issues. Are you using the same windings throughout? It's hard because the shots are so dim, but maybe you are reversing the normals every row somehow?
|
# ? Jun 28, 2011 02:00 |
|
e: nevermind, I can't read apparently.
PDP-1 fucked around with this message at 03:09 on Jun 28, 2011 |
# ? Jun 28, 2011 03:05 |
|
Er, yea, sorry about the bad lighting. The attached file should be easier to see. Apparently it's called Z-fighting, but I've done what was recommended and no change. Luckily I have an entire copy of the project from last week saved, so I'll have to go through it and see what I changed. At this point I'm thinking it has something to do with the camera, but then again its possible that I enabled/disabled something when calling draw(). dereekb fucked around with this message at 05:58 on Jun 28, 2011 |
# ? Jun 28, 2011 03:54 |
|
Well, actually... My Backups now throw graphics errors when trying to play them.quote:Direct3D9: (ERROR) :Unsupported mag filter. Seems like part of the puzzle though. I was "unplugging" the DirectX SDK from my project so, maybe there were some side effects... Or they're unrelated. vv Edit: Got everything back to working, although the original cause is still unknown... To get the quoted error to go away, I removed the magfilter from the shader (no change in looks, so...), and had to impliment the following code in the HLSL file the terrain uses: quote:ZEnable = True; dereekb fucked around with this message at 06:12 on Jun 28, 2011 |
# ? Jun 28, 2011 04:34 |
|
Gerblyn posted:Have you tried outputting any data on the tree? You want to have a look at how deep it is, and how many entities each leaf node contains. Generally you want to have your entities spread fairly evenly throughout the leaves, since your tree does very little good if 90% of your entities are all in the same leaf. Also, if you have a malfunction building the tree, you may end up with a tree thousands of layers deep (also bad). By design each leaf contains only one element, and for the ~14,000 element test the maximum depth was 65. It's not excessively deep but still seems a bit too deep for the number of elements in it. edit: average (mean) depth for ~14,000 element test is around 25. FlyingDodo fucked around with this message at 06:53 on Jun 28, 2011 |
# ? Jun 28, 2011 05:59 |
|
FlyingDodo posted:By design each leaf contains only one element, and for the ~14,000 element test the maximum depth was 65. It's not excessively deep but still seems a bit too deep for the number of elements in it. I guess what's happening then is that the nodes in the graph are overlapping too much, so when you check an AABB against the tree it ends up checking a few thousand nodes instead of the 50 or so it would in perfect conditions? Looking at the algorithm you describe for building the tree, I can see why that would happen and I'm not really sure there's a way of fixing it; it sounds as if the type of binary tree you're using simply isn't suited to the task, due to either having too many elements, having the elements too densely packed together or both. Have you tried letting the system put more than one element in each leaf? That would simplify the tree structure and may cut down on unnecessary AABB checks. Failing that, you might have more luck with a quad tree, like the one described on this page. He's using 1 element per node, but considering the number of test elements you have I'd have 5-10. Edit: Now that I think about it, with either of these tree structures a leaf should be able to store at least as many elements as a node can store children. i.e. With your binary tree it's better to have a leaf containing two elements than a node containing two leaves, each of which contains one element. The leaf with two elements gets 2 AABB checks (one for each element), where the node with two leaves gets 2-4 (2 to check each leaf and up to 2 to check the elements in the leaves). Similarly a quad tree leaf should be able to store at least 4 elements before splitting. Gerblyn fucked around with this message at 09:43 on Jun 28, 2011 |
# ? Jun 28, 2011 09:16 |
|
dereekb posted:Apparently it's called Z-fighting, but I've done what was recommended and no change. Try to keep the far plane at a sane distance and don't use ridiculously low near plane distances. Depth values scale hyperbolically so as your near plane starts approaching zero, the depth range reserved for near values goes through the roof and everything else suffers.
|
# ? Jun 28, 2011 13:18 |
|
Gerblyn posted:I guess what's happening then is that the nodes in the graph are overlapping too much, so when you check an AABB against the tree it ends up checking a few thousand nodes instead of the 50 or so it would in perfect conditions? Looking at the algorithm you describe for building the tree, I can see why that would happen and I'm not really sure there's a way of fixing it; it sounds as if the type of binary tree you're using simply isn't suited to the task, due to either having too many elements, having the elements too densely packed together or both. Have you tried letting the system put more than one element in each leaf? That would simplify the tree structure and may cut down on unnecessary AABB checks. I think I will stick to an AABB tree for now, but I will try different numbers of elements stored in each leaf. You said that you can see why the algorithm I'm using for building tree is a problem, is there a better way of building the tree? Or a better way to choose which child node to send an inserted element down? Hopefully increasing the number of elements stored in a leaf will help, perhaps have no limit but instead limit the depth of the tree. Only one way to find out.
|
# ? Jun 28, 2011 16:09 |
|
OneEightHundred posted:In a case like this (where the surfaces aren't close), it's probably happening because your depth range is too large for the Z-buffer resolution. My Z-Plane is at 10000, and near plane is at 1. Once again, everything was fine prior to tonight, so I'm not sure what I did to set it off, heh. I did play with those settings just to check again though, but even a far plane of ~1000 or so still had the fighting.
|
# ? Jun 28, 2011 16:51 |
|
FlyingDodo posted:I think I will stick to an AABB tree for now, but I will try different numbers of elements stored in each leaf. You said that you can see why the algorithm I'm using for building tree is a problem, is there a better way of building the tree? Or a better way to choose which child node to send an inserted element down? I believe part of the problem comes from the fact that the algorithm is growing the AABB of a node when an element is placed into it, to make sure the element completely fits. This is causing the nodes to overlap with their siblings, which increases the chance that an AABB check have to search down both siblings, rather than just one of them. This is just speculation on my part, but given what you've said so far it's the only thing I can think of that makes sense. One possible solution is to have the root node encompass the entirely game world. Then, instead of dynamically shaping the child nodes, you just split a parent node in half, guaranteeing that sibling nodes never overlap. If an element intersects both child nodes, you add it to a list of elements in the parent, rather than trying to re-size one of the children so it fits. Essentially, you do what they guys does in the page I linked in my previous post, except you use a binary tree instead of a quad tree. This should lead to a more balanced tree, and should make your check search the tree more efficiently. The downside is that your elements won't be as evenly distributed between leaves, so if you have elements that are very clustered up around each other, it might actually make things worse (though having lots of elements clumped up together is going to gently caress up most spatial partitioning algorithms anyway). First though, I think limiting the depth and allowing multiple elements per node is definitely a good place to start, it may fix the issue outright.
|
# ? Jun 28, 2011 16:52 |
|
I recall awhile back asking about collision detection for a character doing something like a melee attack. One suggestion was to generate a bounding sphere in front of the attacking character at a certain point. I'm trying to figure out how to do that right now. I can set things up so that during a certain frame range I have some stuff active, but I can't figure out between Irrlicht and Bullet how to create an invisible volume that can report back to with what it collided. I assumed Bullet would have some capability for this. The problem is that the volume has effect on the surrounding objects no matter what. So it's knocking stuff around while it's active, and everything tries hard to keep from occupying each other's spaces. However I want this to be a space that could be occupied--that is really the whole goal. Does anybody using Bullet for physics have an idea on how to set it up to do these kinds of tests? Edit: I guess what I need are Bullet's "ghost objects." The wrapper I'm using doesn't support them so I'm trying to write a wrapper for them. Rocko Bonaparte fucked around with this message at 15:30 on Jun 29, 2011 |
# ? Jun 28, 2011 17:12 |
|
dereekb posted:My Z-Plane is at 10000, and near plane is at 1. Once again, everything was fine prior to tonight, so I'm not sure what I did to set it off, heh.
|
# ? Jun 28, 2011 19:00 |
|
Gerblyn posted:I believe part of the problem comes from the fact that the algorithm is growing the AABB of a node when an element is placed into it, to make sure the element completely fits. This is causing the nodes to overlap with their siblings, which increases the chance that an AABB check have to search down both siblings, rather than just one of them. This is just speculation on my part, but given what you've said so far it's the only thing I can think of that makes sense. I thought about too many nodes being visited, the 14,000 element test visited ~350 nodes on average. Too many? Maybe it is time to throw out the code I have and re-write it from the start, taking into account thing you've said.
|
# ? Jun 29, 2011 19:06 |
|
dereekb posted:My Z-Plane is at 10000, and near plane is at 1. Once again, everything was fine prior to tonight, so I'm not sure what I did to set it off, heh. Not sure on this, but did you add anything involving a spritebatch? When used, it switches renderstates and disables your z-buffer.
|
# ? Jun 29, 2011 21:54 |
|
FlyingDodo posted:I thought about too many nodes being visited, the 14,000 element test visited ~350 nodes on average. Too many? Maybe it is time to throw out the code I have and re-write it from the start, taking into account thing you've said. It's hard to say really, it does sound like a lot, but you need to take into account the size of the AABB that you're checking with. If you're saying something like: 1) I have a 1000x1000m field 2) I have 14,000 elements in that field, each 1m squared in area 3) I'm searching for all elements in a 100x100 meter box Then having the system check 350 nodes (assuming that includes leaves, and you have only 1 or 2 elements per leaf) sounds pretty good. If your check box is only 10x10, however, then that sounds like too many. How long does the check take? Also, I assume when you wrote 800ms earlier, you meant microseconds, not millisends, right? As a general opinion, assuming you have the patience and time, it's never a bad idea to rewrite an algorithm like this to try out a new approach or to implement ideas you thought of while writing the new one. It's not like you have to throw away the old code if your rewrite sucks, and the chances are your second attempt will be much better than your first (not just because of my advice, more because you have a clearer idea of what you're doing). Before you get too disheartened with what you have though, these kinds of algorithms are very fiddly, and you may find changing certain parameters, such as max elements per node and maximum tree depth have big effects. Also, 14,000 elements IS a lot, I'm guessing this is a stress test and when the system is in use, you'll usually have far fewer elements? Just because the tree performs badly with 14,000 elements doesn't mean it'll be bad with only 1000. Gerblyn fucked around with this message at 23:09 on Jun 29, 2011 |
# ? Jun 29, 2011 22:33 |
|
Out of curiosity, how are you allocating your nodes when you build the tree?
|
# ? Jun 29, 2011 23:02 |
|
Just using new. However I don't think this is relevant to the speed of querying the tree as nothing is allocated/deallocated when searching. The only allocation that might happen is a re-sizing of an std::vector which collects the results. edit: for more information; the test data is ~14,000 brushes from a quake3 level. The tree is created from those then each one is sent through the tree to find any brushes bounding boxes that touch the bounding box of the test brush. All 14,000 brushes are tested in this way. Checking all 14,000 with the tree takes ~300-400 milliseconds. Testing without the tree takes ~700-800 milliseconds. So one query using the tree takes on average ~0.021-0.028 milliseconds per query. Without the tree it is about double the time. FlyingDodo fucked around with this message at 16:33 on Jun 30, 2011 |
# ? Jun 30, 2011 16:25 |
|
FlyingDodo posted:Just using new. However I don't think this is relevant to the speed of querying the tree as nothing is allocated/deallocated when searching. The only allocation that might happen is a re-sizing of an std::vector which collects the results. It's not allocation overhead I'm thinking about, it's cache thrashing. I'd try allocating the nodes from a pool of contiguous memory and see how that affects performance; it may not end up being a big deal, but it could help a lot. If nothing else you'll save a lot of memory. Also, if you're using STL containers at any point in the querying, make sure you're either building in release mode or disabling checked iterators because those can add a pretty enormous performance penalty. Paniolo fucked around with this message at 16:40 on Jun 30, 2011 |
# ? Jun 30, 2011 16:35 |
|
It is compiled in release mode and I don't think it has to do with std::vector, if I comment out anything to do with it and just traverse the tree during search without collecting the results it still takes just as long. Point noted about memory allocation, something possible add to do in a re-write. However I'm thinking it's just a bad data structure/algorithm. I supposed I better get to work on something new rather than screwing around with what I have.
|
# ? Jun 30, 2011 17:12 |
|
FlyingDodo posted:It is compiled in release mode and I don't think it has to do with std::vector, if I comment out anything to do with it and just traverse the tree during search without collecting the results it still takes just as long. Point noted about memory allocation, something possible add to do in a re-write. However I'm thinking it's just a bad data structure/algorithm. I supposed I better get to work on something new rather than screwing around with what I have. Yeah, I think that a binary tree is really not the right kind of algorithm to use in this case. The differing sizes of the brushes, how they're arranged and how densely they're packed, are all absolutely horrible for the algorithm you've chosen. It's almost guaranteed to make a tree with lots of overlapping nodes that will really hurt performance. You want to use an octree for this (i.e. a quadtree in 3D).
|
# ? Jun 30, 2011 17:26 |
|
Hi guys, first time posting in Cavern of COBOL, I'm working on shaders for a game, and I need to implement a bump-mapping shader that reads in the texture, a normal map and use the alpha channel of the normal map as a specular map. So far, it seems to work okayish: You might notice the specular effect is banded in lines across the surface in an unusual manner. This is deliberate and reflects the specular map we are using at the moment (its a grid to make it more obvious when it works). However, I am getting unusual weirdness: the light seems to swim across the surface in a bizarre manner, and can be seen clearly when the demo is running: the sphere rotates on the spot and thus, the specular should always stay in the same location as the sphere turns. It doesn't however, and travels in a weird manner that I can't quite describe. I have the vertex and fragment shaders at hand, if you would be kind enough to examine it and see where I am going wrong. I apologise in advance for poor quality code, I am still coming to grips with shaders. Vertex: code:
code:
PiCroft fucked around with this message at 18:11 on Jun 30, 2011 |
# ? Jun 30, 2011 18:06 |
|
What's the fastest way to prototype some simple 2D games? I'm using C# as my primary language (it's what we use at work, etc) so I know I could use XNA but even that requires a bit of work to display sprites, menus, etc. Ideally I'd like something extremely high level (for .NET?) that I can create menus and then move some sprites around, etc. (Maybe my best bet is Windows Forms and GDI?)
|
# ? Jun 30, 2011 19:12 |
|
Use something like Stencyl, Game Maker, or Unity for prototyping.
|
# ? Jun 30, 2011 19:15 |
What's the best way to make a birds-eye 2D isometric game, like RollerCoaster Tycoon, SimCity, or Ceasar?
|
|
# ? Jul 1, 2011 22:25 |
|
I can't speak for SimCity, but I'm pretty sure the best way to write RollerCoaster Tycoon is x86 assembly.
|
# ? Jul 1, 2011 22:50 |
|
Internet Janitor posted:I can't speak for SimCity, but I'm pretty sure the best way to write RollerCoaster Tycoon is x86 assembly. For an actual answer, most games of that nature were done using sprites that are just drawn in positions so as to look isometric, by positioning them on a hexagonal/triangular grid (moving half a square across and half a square down with each row, rather than one square down as you would for a flat view). You can also move one square up for vertical positioning if your isometric game is having a third dimension. The advantage of doing it that way is it's pretty easy to code, you can make the graphics with Paint, and everything's on a grid so all collision detection and stuff is a piece of cake. The disadvantage is that you have to draw many things twice or four times (if a thing can face any direction then drawing twice gives you northwest and southwest, then you can mirror it for northeast and southeast. If the thing can face any direction and isn't symmetrical then you can't mirror it and must draw it four times.) So the way that sort of thing is frequently done now is to use 3D rendering and just have an isometric view/projection. Advantage, only make things once. Disadvantage, it's harder to make 3D things and you can't make things pixel-perfect. Additional advantage: you can also make things face directions that aren't cardinal directions without making any extra art. Another way isometric things have been done is using 3D rendering with lots of anti-aliasing and even manual touching up, while making the game, to make the sprites, which you then render the old-school way in-game. You get the "make things once" advantage and the "pixel perfect" advantage, you still lose the "face arbitrary directions" and "make the art easily" abilities. So the actual answer to the question is "there isn't an inherently best way, what's best depends on your goals and abilities." (And all this is assuming the question was about this low-level stuff rather than "what language/libraries should you use?")
|
# ? Jul 1, 2011 23:06 |
roomforthetuna posted:(And all this is assuming the question was about this low-level stuff rather than "what language/libraries should you use?") Oh... that's actually what I wanted to know. Is FIFE (http://www.fifengine.de/) a good choice?? Shameproof fucked around with this message at 00:27 on Jul 2, 2011 |
|
# ? Jul 1, 2011 23:50 |
|
Shameproof posted:Which was an incorrect assumption... that's actually what I wanted to know. Is FIFE (http://www.fifengine.de/) a good choice?? I don't think that snidely dismissing the person who actually took the time to try and help you is going to win you many friends here. Maybe you could explain what exactly you need from an engine, and what kind of experience you have with making games?
|
# ? Jul 2, 2011 00:26 |
Gerblyn posted:I don't think that snidely dismissing the person who actually took the time to try and help you is going to win you many friends here. Sorry, didn't mean to come off that way. I'd like an engine where I can import my sprites and have them get drawn in the proper order in a 2D plane. Tile-based... I don't have very much experience with games but I know the basics of how they work.
|
|
# ? Jul 2, 2011 00:30 |
|
The FIFE engine looks like a good place to start, it has the features you want and is apparently geared towards making isometric games. It looks like you'd be writing all the game logic in PYTHON, with the engine handling most of the fiddly stuff for you, which is very handy if you don't have much experience. If you want something even higher level, you could try out things like GameMaker and RPGMaker.
|
# ? Jul 2, 2011 00:49 |
|
What's the best way to clamp an angle within an arc, snapping to the closest arc edge if out of bounds? This is the best method I've come up with so far. It works fine but I'm wondering if there's a more elegant or efficient solution. My math skills are subpar at best. code:
code:
Spatial fucked around with this message at 03:48 on Jul 4, 2011 |
# ? Jul 4, 2011 03:05 |
|
Spatial posted:What's the best way to clamp an angle within an arc, snapping to the closest arc edge if out of bounds? This looks shorter. code:
code:
shrughes fucked around with this message at 03:33 on Jul 4, 2011 |
# ? Jul 4, 2011 03:29 |
|
Thanks for the help, I'll try those out.quote:Edit: Uh, what's with your dividing arc by 2 and using arc2? That doesn't meet the spec. Edit: Gave it a whirl. On average your first function is 1.5x faster than mine, and your second is more than twice as fast. Thanks again. Spatial fucked around with this message at 04:36 on Jul 4, 2011 |
# ? Jul 4, 2011 03:48 |
|
|
# ? May 18, 2024 06:58 |
|
I re-wrote my bounding volume hierachy, so it is more like a kd-tree now. There is the ability to put limits on tree depth and the number of elements in a node. So the algorithm/data structure is now as follow. Each internal node has an axis aligned splitting plane. When something is inserted into the tree if the node is internal and the inserted element spans the splitting plane it stays at that node. If it's in front, goes to the front child node, if back goes to the back child node. This repeats until it either spans the plane and stays in the internal node or hits a leaf node. If the node is a leaf node the element is inserted into that node. If the number of elements in a leaf node reach a set limit the node is split by a plane at the centre of the bounding box of that node. The plane is axis aligned, the axis chosen by mod 3 of the depth. Leaf nodes can go over the limit of number of elements if max depth has been reached, and internal nodes don't have a limit because all elements stored in an internal node cannot be split as they span the splitting plane. Despite this re-write it actually seems to be slower than my previous attempt, even though there can't be any overlap of nodes and there is a limit on depth and allowing for multiple elements per node. It seems like both ways I have tried only reduce the number of bounding box checks by about 60%, still leaving a huge amount.
|
# ? Jul 5, 2011 19:47 |