Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Those operations are very order-dependent though. Unless you mean "it builds one transformation matrix by overwriting values, not multiplying". In which case, that's easy-to-specify and easy-to-implement but mostly useless behavior.

Adbot
ADBOT LOVES YOU

Max Facetime
Apr 18, 2009

Scales are commutative with other scales, moves are commutative with other moves and rotates are commutative with other rotates (using quaternions, I think). So you can accumulate like with like and then when applying them all use the order that's the most intuitive. The customer working with the API shouldn't ideally even perceive that some particular order was chosen.

Another thing I'd like to highlight that I think was overlooked previously: the use of units. Why is it that being in a frame where one meter is two meters or only half a meter long feels all kinds of wrong but drop the units from your values and now no-one seems to bat an eye? Someone explain that to me, please!

Bizarro Buddha
Feb 11, 2007
The problem is that your order-independent construction of transformations is pretty useless in practice. Things in games very rarely want to move directly in world space. They want to move in their current frame of reference e.g. the way the character is pointing. If you construct a transformation system where things can only move "forward", "left", and "up" then all you're doing is pushing the complexity of deciding how to generate those three values from the actual desired movement onto the API user.

That Turkey Story
Mar 30, 2003

Grocer Goodwill posted:

And, honestly, rightly so.
:|

Grocer Goodwill posted:

This kind of "abstraction" is not helpful. To begin with, it doesn't really save you having to understand the underlying math. You still have to understand for example what a transformation is, what a dot product is, and when and why to use them. All this kind of wrapper code does is save you from having to know how to do a matrix multiplication or how to form a quaternion, which is a minor gain at best and dubious one at that.
Your line of reasoning is as short-sighted here as it is when applied to most other abstractions. For instance, you could use the same exact rationale to disregard container types -- just change out "matrix multiplication" with "red-black tree." Believe it or not, people don't need to know the underlying details of a red-black tree in order to understand how to use a std::map or a "dictionary" or whatever your language calls it in order to use these containers properly. In fact, I'm willing to bet that most users don't understand the underlying details (or at the very least don't always think about the details), and yet it doesn't impact their ability to properly use the type. All you actually need to know are the high-level ideas that the concept represents and the complexity and semantics of their associated operations. It does help to know further details about the implementation to really optimize usage, and if you need to do that you still can, but it's generally not necessary. Abstracting away the details and providing a unifying concept with other container types makes the container more useful, not less. "Matrix multiplication" or "quaternions" are not an exception to this with respect to their interpretation as spatial transformations.

Besides that, I disagree with your statement about dot product -- with high level abstractions, you really don't need to think about dot product for many situations where a dot-product is used underneath the hood, including those that are extremely common to games (I.E. accumulating transformations can imply many dot-products underneath the hood in the form of the inner product of rows and columns of underlying matrices, but we aren't explicitly thinking about that all of the time). It certainly helps to know what the dot product is, especially if you want to work with types of operations that aren't already abstracted away, but it's not necessary to understand what a transformation is and how to utilize one. Again, using simply the notion of "Transformation" and basic, intrinsic operations, you can describe relative spaces, the accumulation of transformations, the complete navigation of complex scene graphs, and more, without delving into matrices. This isn't anything new and you shouldn't be under the assumption that I'm saying something controversial here (though given some responses I've seen, you'd think I'm a 9/11 truther). Game programmers just tend to not apply it to programming. I'm also not saying that matrices shouldn't be used if you encounter a situation not yet abstracted away, just that you shouldn't have to default to populating and multiplying matrices when all you're doing is creating a few, very common kinds of transformations that are well understood and even well-known by higher level names. You should be able to simply start with transformations, jumping down to explicitly working with matrices only if you have to, just like you'd do with any abstraction.

As an aside, in the real world, I've explained spatial transformations to people in this manner plenty of times, and I'm sure you probably have too. When describing to a non-programmer, non-mathematical friend how transformations work in 3D games I will not once mention matrices or matrix multiplication unless they want to know further details about how certain transformations are performed by the computer. If when talking to a layman they ask "how do you go from a 3D representation of data in a game to a flat image on the screen," I would not start with "well, first you need to understand homogeneous coordinates...". If you think that doing so somehow makes things more clear to the person that you are explaining things to, then I don't know what to tell you. Perhaps if you want to impress someone with 'sperginess you will try to get as technical as possible upfront, but if you actually want to communicate or get things done, that's not the approach that you take.

Grocer Goodwill posted:

Useful abstractions are at a much higher level than this -- things like "look at", or "move to", or "follow".
"Look at" is a kind of spatial transformation, you do understand that, right? Are you saying that because I call "look at" a "Transformation" and implement it as one instead of a function that returns a matrix or a function that modifies a matrix, or what-have-you, it is somehow worse, or are you saying that it's okay for "look at" to be called a "Transformation" but it's not okay for "translation" to be called a "Transformation" because the math is a little bit more complicated? Why do you think "look at" is so much better to be described in more abstract terms than "projection" or "scale" or "shear" or "reflection." Everything mentioned is a worthwhile abstraction, all are transformations, and in practice you're probably going to refer to them in such a manner verbally. There's no reason why you shouldn't be working with them directly using those terms in code, either. The benefits are there regardless of how "simple" an implementation is or can be, especially when you want to reason about them in a similar manner.

And I know I've pointed this out before, but the idea of a "matrix" is not in any way, shape or form intrinsic to understanding what a transformation is. I'm not sure why people think this. Perhaps it's because, for most game programmers, they learn most of the math involved from the low-level abstractions provided by certain graphics libraries and tutorials associated with them, which simply don't go beyond matrices. Matrices in this case, when used as spatial tranformations, are just one way to represent a very specific kind of transformation -- linear mappings between spaces, not even all kinds of mappings. They are just the low-level implementation of how we achieve the more common kinds of transformations dealt with in graphics.

Grocer Goodwill posted:

Secondly, compile times and debug build speed are real issues. Adding a ton of template boilerplate to nearly every source file is nowhere near worth the small gain in genericness you're getting. And that genericness isn't even that useful. You pick a handedness, orientation, and row/column convention and stick with it. Being able to swap those around on the fly makes things more confusing, not less.
If you've decided that you don't want to use a certain library because of something like compile-times, then go right ahead, but understand that this is entirely orthogonal to the arguments that you and others have presented. Don't conflate the inefficiencies of a compiler or a poor library implementation with the robustness of its abstractions.

Grocer Goodwill posted:

This kind of expression template stuff is interesting in an academic sense, but I wouldn't want anything like it anywhere near any actual engine code I was working on.
Whether or not expression templates are used is dependent on the underlying "default" implementation (you can use the library without a default implementation as well, you just aren't able to explicitly create instances of tensors or transformations, you're only able to pass yours in to functions like transform). One intent is that this makes it easy to use implementations such as Eigen underneath the hood that utilize expression templates, but you don't have to use such a backend if you don't want to or if the license is incompatible with your project. Right now, all I have is a basic, naive implementation (fast compile, not expression templates, with the very open Boost Software License) and a partially developed backend that uses Eigen, but ideally, once everything is done and well-tested, that will mean that you can safely and easily just change a single command-line option to your compiler to switch between a quick-compiling implementation and a more complicated one. That way, you can get fast iteration of builds when that's important, only switching to a more complicated backend for testing and a final build.

Win8 Hetro Experie posted:

That really is the sticking point: transform( scale( width = 2.0, height = 4.0 ), translation( left = 0.5 * meters ), position); versus transform( translation( left = 0.5 * meters ), scale( width = 2.0, height = 4.0 ), position);

One of those is what I want, the other one is completely wrong. The value of having a higher-level API should be in the API making it obvious what I need to do to get what I want. Or failing that, having some clues that help me figure out which one is which.

Agreed, that's why I'm looking for some options here, without having to make an overly-verbose name for the function.

Win8 Hetro Experie posted:

Here's a slightly changed version with the goal of sidestepping the problem:

C++ code:
  auto const transformed_point
    = transforms( scale( width = 2.0, height = 4.0 )
                , move( left = 0.5 * meters )
                , rotate( roll = 60.0 * degrees )
                ).apply_on( position );
}
I like this kind of approach. I already have an "accumulate_transformations" function -- if I just make it return a Transformation that also has an "apply_on" function, this would eliminate the need for a separately named transform function all together.

Win8 Hetro Experie posted:

The word transforms implies an order-independent list of transformations, which are all applied conceptually at the same time. This means move always does what it says, like it should.

Implementing fuller support for going between frames of reference is left as an exercise for the author :)
Here's my issue: the entire point of the function is to provide a simple syntax for the order-dependent operation exactly so that it's not an exercise for the author. Also, "move" or "translate" or however you call it still does what it says in the accumulated form, just in the new reference frame. Specifying the operation your are describing isn't really a problem and that can be represented as a single, composite Transformation type, assuming that the transformations aren't conflicting with one-another.

Win8 Hetro Experie posted:

Scales are commutative with other scales, moves are commutative with other moves and rotates are commutative with other rotates (using quaternions, I think). So you can accumulate like with like and then when applying them all use the order that's the most intuitive. The customer working with the API shouldn't ideally even perceive that some particular order was chosen.
Rotations are not generally commutative. Order does matter.

Win8 Hetro Experie posted:

Another thing I'd like to highlight that I think was overlooked previously: the use of units. Why is it that being in a frame where one meter is two meters or only half a meter long feels all kinds of wrong but drop the units from your values and now no-one seems to bat an eye? Someone explain that to me, please!
I'm not sure what you're asking. When changing reference frames, things like this happen. Everything is relative.

Bizarro Buddha posted:

The problem is that your order-independent construction of transformations is pretty useless in practice. Things in games very rarely want to move directly in world space. They want to move in their current frame of reference e.g. the way the character is pointing. If you construct a transformation system where things can only move "forward", "left", and "up" then all you're doing is pushing the complexity of deciding how to generate those three values from the actual desired movement onto the API user.
Precisely.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
So, That Turkey Story, I want to point this out to you. You wrote this, right?

http://stackoverflow.com/questions/13200264/how-does-the-boost-binary-macro-parse-spaces

These people are mystified by your code. They literally cannot understand how it works. There's one guy who spent around three hours trying to figure it out and couldn't.

This is the kind of library you want to introduce to the game development world. A world where deadlines are extremely important, and the "Death March" is a thing. If you introduce this into a big studio in a big engine, people are going to waste around 100 hours debugging your code, even if it's 100% correct, simply because they can't find the problem anywhere else and they see a giant chunk of complex code that's absurdly complex and the problem must be there because where else could it be who is "Matthew Calabrese" why is he haunting me make it Stop PLEASE OH GOD WHY!!

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
So, with the dumb drama post out of the way, there's two parts to this: 1) clever metaprogramming shenanigans, 2) new representations of transforms that don't require knowledge of low-level implementation details.

One doesn't necessitate the other, and please don't conflate the two. I'm against 1), and I'm skeptical of the utility of 2). But let's make things interesting. I'm willing to count 1) to personal disagreements, so I won't hold it against your library.

Along with my "easy to debug" principle, I also have another well-held principle about development libraries / platforms: they are useless unless they are pulled out of a working application. I don't know any popular framework or library that was not pulled out of an existing use.

Therefore, I have a challenge for you, TTS: Make an actual game using your library. Doesn't have to be complex, and hell, I'll stretch the definition of "game" to include a Minecraft clone voxel engine if you want to make that, but actually make a complex system that shows the value of this in a real-world project. If you do this using the principles in your library (no low-level knowledge of math, just high-level concepts), I'll gladly accept defeat and consider you the king of CoC or whatever.

That Turkey Story
Mar 30, 2003

Suspicious Dish posted:

So, That Turkey Story, I want to point this out to you. You wrote this, right?

http://stackoverflow.com/questions/13200264/how-does-the-boost-binary-macro-parse-spaces

These people are mystified by your code. They literally cannot understand how it works. There's one guy who spent around three hours trying to figure it out and couldn't.
You know, I already went over this when you tried to champion this as some amazing point in the other thread, but I'll go over it again here. That's what ends up happening when you are limited by language support for a particular task. Believe it or not, we do not just say "let's go and make something that's difficult to implement." In this case, you're limited by the fact that the language standard doesn't have direct support for binary literals and the fact that the preprocessor can pretty much just concatenate and expand tokens (and also, at the time that the macro was developed, there weren't variadic macros, so a comma-based interface wasn't even able to be used, which would have made for a much simpler implementation).

The issue is, using binary literals is still very useful -- your other options are things like using decimal literals or hex literals or octal literals, despite the fact that you are trying to represent a number in binary, which is extremely common. The conclusion you should be drawing from this is not "I don't understand the implementation, therefore I won't use the tool," it should be "I'm glad that this tool exists, is well-tested, maintained by someone other than myself, and went through peer review," or perhaps "the language should be improved so that the implementation doesn't have to be so complicated." C++11 made this a little bit better thanks to variadic macros and user-defined literals, and C++14 will make it completely trivial by directly supporting binary literals (they were already accepted for the next standard).

Edit: I will also point out the test results for the utilities in Boost, including the BOOST_BINARY macro. Do you test your own code on this many systems? Do you write tests for your utilities and containers or whatever, or do you just write code and then rely on testers for everything?

Also note that in that thread, people weren't particularly upset that they didn't understand exactly how it works. You should be comfortable with that. Do you never use libraries that are compiled and that you don't even have the option of seeing how complicated the implementation is or is not? Do you even care about that, or do you just care that it correct and efficient? What about languages with direct features like garbage collection? You often won't see exactly how it was implemented and yet people rely on it all of the time. I'd consider the case of garbage collection much more controversial and also much more complicated than this!

Suspicious Dish posted:

This is the kind of library you want to introduce to the game development world. A world where deadlines are extremely important, and the "Death March" is a thing. If you introduce this into a big studio in a big engine, people are going to waste around 100 hours debugging your code, even if it's 100% correct, simply because they can't find the problem anywhere else and they see a giant chunk of complex code that's absurdly complex and the problem must be there because where else could it be who is "Matthew Calabrese" why is he haunting me make it Stop PLEASE OH GOD WHY!!
No, in the real world of video games we each maintain our own, in-house containers that are completely loaded with bugs and whose original developer isn't at the company anymore anyway, we swear off language features because of things we heard 20 years ago, and spend the extra years during development on fixing bugs in code that wouldn't be there at all had we used existing and even free tools. If you think using a well-tested library that you don't completely understand is a bigger problem than making something entirely from scratch then go right ahead and do so. That is the reason the game industry is as hosed as it is -- it's not a fault of these "horrible libraries" you are talking about that you don't even use.

That Turkey Story fucked around with this message at 19:30 on May 12, 2013

Tres Burritos
Sep 3, 2009

Paniolo posted:

I wrote this about a year ago when I was toying around with a terrain engine. It's 3d and voxels so a bit more complex than what you're asking for but the basic concept of starting with simple mathematical terms and combining them to get increasing complexity is the same pattern.

http://code-freeze.blogspot.com/2012/04/rebuilding-world-one-iteration-at-time.html

Hey thanks, that's perfect!

That Turkey Story
Mar 30, 2003

Suspicious Dish posted:

So, with the dumb drama post out of the way, there's two parts to this: 1) clever metaprogramming shenanigans, 2) new representations of transforms that don't require knowledge of low-level implementation details.

One doesn't necessitate the other, and please don't conflate the two. I'm against 1), and I'm skeptical of the utility of 2). But let's make things interesting. I'm willing to count 1) to personal disagreements, so I won't hold it against your library.
Alright.

Suspicious Dish posted:

I also have another well-held principle about development libraries / platforms: they are useless unless they are pulled out of a working application. I don't know any popular framework or library that was not pulled out of an existing use.
That's exactly how generic programming works. You take existing implementations and lift out commonalities. In cases like this that are purely mathematical it's easier because we already have a well-understood, proven taxonomy meaning that we don't have to do the lifting of concepts ourselves. It's already been done by mathematicians. I didn't "invent" abstractions like these, I'm just applying them.

Suspicious Dish posted:

Therefore, I have a challenge for you, TTS: Make an actual game using your library. Doesn't have to be complex, and hell, I'll stretch the definition of "game" to include a Minecraft clone voxel engine if you want to make that, but actually make a complex system that shows the value of this in a real-world project. If you do this using the principles in your library (no low-level knowledge of math, just high-level concepts), I'll gladly accept defeat and consider you the king of CoC or whatever.
I already have a simple, working game that I use to play with ideas in the libraries as they are introduced. It's just a Dr. Mario clone, so it's not 3D or anything and isn't taking specific advantage of a lot of transformation accumulation aside from some trivial stuff. The code is very concise. Apart from this, I hope to eventually have side-by-side comparisons of the code used in tutorials written for things like DirectX and OpenGL, which is what I'd really like to do first before developing a complicated game with it.

Rottbott
Jul 27, 2006
DMC
TTS, your library sounds interesting and I'd like to try it out. No idea whether I like it.

Grocer Goodwill
Jul 17, 2003

Not just one kind of bread, but a whole variety.

That Turkey Story posted:

Your line of reasoning is as short-sighted here as it is when applied to most other abstractions.
My line of reasoning said nothing general and was entirely specific only to the code you posted. I don't know how you got "all abstractions are useless" from my saying "this abstraction is not helpful".

That Turkey Story posted:

Besides that, I disagree with your statement about dot product -- with high level abstractions, you really don't need to think about dot product for many situations where a dot-product is used underneath the hood
Yeah, actually you do. It is true that instead of saying "what's the projection of this vector on this other one?" you could say "Okay, give me the angle between these two vectors, I'll take the cosine and then multiply that by its length" and you'd be saying effectively the same thing, but now we're introducing trig functions for no reason. We do this sort of thing all the time, all over the place. It's pointless to pay that cost just so that someone doesn't have to learn what a dot product is.

That Turkey Story posted:

When describing to a non-programmer, non-mathematical friend how transformations work in 3D games I will not once mention matrices or matrix multiplication
Fine, but we're talking about a library used by programmers, here.

That Turkey Story posted:

"Look at" is a kind of spatial transformation, you do understand that, right?
I meant continuously, as the target is moving. My examples all involved something more than just spatial transformations, like time.

That Turkey Story posted:

And I know I've pointed this out before, but the idea of a "matrix" is not in any way, shape or form intrinsic to understanding what a transformation is
Not intrinsic, but it is equivalent. Saying "concatenate these transforms" and "multiply these matrices" for any kind of transform/matrix encountered in games programming are exactly equivalent. Yes, technically the matrix is the representation of the transform, which is an abstract thing, but they are completely equivalent. All you're doing is just choosing not to use the term matrix anywhere. Your abstraction isn't any more general than any other math library. I mean people don't say float trans[16] and manually plug in values, you know.

That Turkey Story posted:

Don't conflate the inefficiencies of a compiler or a poor library implementation with the robustness of its abstractions.
I'm not conflating the two. They are two separate and equally important considerations.

That Turkey Story posted:

you can safely and easily just change a single command-line option to your compiler to switch between a quick-compiling implementation and a more complicated one.
Why on earth would I want to do this? You are solving a problem that does not exist.

That Turkey Story posted:

No, in the real world of video games we each maintain our own, in-house containers that are completely loaded with bugs and whose original developer isn't at the company anymore anyway
So your solution is to introduce another one?

That Turkey Story posted:

That is the reason the game industry is as hosed as it is -- it's not a fault of these "horrible libraries" you are talking about that you don't even use.
There are many problems with the games industry, but a lack of C++ template wankery is not one of them.

That Turkey Story
Mar 30, 2003

Rottbott posted:

TTS, your library sounds interesting and I'd like to try it out. No idea whether I like it.

Thanks. I'll try to get things up on github or something sooner than later. I doubt it'll be for everyone, as is clear by this thread, but I really do believe the underlying premise is an important and useful one that people shouldn't avoid working toward. It does have a huge drawback right now, though, that is very limiting -- all of the tests currently only compile in Clang (GCC can't even handle some things, yet) and I'm probably not going to worry about making workarounds for other compilers until it's really feature complete, well documented, and I have a couple of backends fully up and running. I'm sure very few people are using Clang as their primary compiler for games right now, particularly on windows, so at this point it's mostly just for dicking around and fantasizing about the future.

Max Facetime
Apr 18, 2009

That Turkey Story posted:

Here's my issue: the entire point of the function is to provide a simple syntax for the order-dependent operation exactly so that it's not an exercise for the author. Also, "move" or "translate" or however you call it still does what it says in the accumulated form, just in the new reference frame. Specifying the operation your are describing isn't really a problem and that can be represented as a single, composite Transformation type, assuming that the transformations aren't conflicting with one-another.

Maybe I'm misunderstanding the motivation for the API. I got the impression that the purpose of the API was at least in part to provide a higher-level abstraction over matrix transformations, but if the purpose is to normalize different conventions when applying linear algebra without raising the level of abstraction then my concerns here and before don't apply.

That Turkey Story posted:

Rotations are not generally commutative. Order does matter.
Right, I knew that, or at least I should've from reading the API.

Is the order of parameters here order-dependent as well:


rotation( roll = 60.0 * degrees, pitch = 45.0 * degrees, yaw = 15.0 * degrees )


Because my first intuition is that the parameter order of functions is just a stylistic choice of the author. Especially in something like C++ where

code:
void rotate(float roll, float pitch, float yaw);
void rotate(float pitch, float roll, float yaw);
isn't valid.

That Turkey Story posted:


I'm not sure what you're asking. When changing reference frames, things like this happen. Everything is relative.

The meter is the length of the path travelled by light in vacuum during a time interval of 1/299 792 458 of a second. The second is the duration of 9 192 631 770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the cesium 133 atom in its ground state at a temperature of 0 K.

It is not relative.

Here's the problem, as I see it when writing code:

code:
npc.move_forward(1.0 * meter)
   .active_powerup() // is maybe .scale(0.5) in disguise
   .move_forward(1.0 * meter);
To me the first meter is the same length as the second meter, because they are both in my frame of reference, which I want to be the NPC's frame of reference as well. If the frame of reference changes in the middle it should be apparent in the code. It could also fail to compile if the API can't figure out what the length of the meter is.

Hughlander
May 11, 2005

That Turkey Story posted:

I'm sure very few people are using Clang as their primary compiler for games right now, particularly on windows, so at this point it's mostly just for dicking around and fantasizing about the future.

Other than everyone doing iOS? (And yes we do C++ 11 with it. Even lambadas.)

That Turkey Story
Mar 30, 2003

Grocer Goodwill posted:

My line of reasoning said nothing general and was entirely specific only to the code you posted. I don't know how you got "all abstractions are useless" from my saying "this abstraction is not helpful".
What I'm asking you to do is explain the difference between the two scenarios that makes one a "useful" abstraction and one not. As you currently have explained it, the same explanation can be applied to other abstractions that I'm sure plenty of people find useful (containers just being one example). I'm sure you might have some more precise, underlying reason that you can put into words that differentiates the two, but you haven't really expressed it yet. If this particular abstraction isn't useful, I want to know exactly why you think that's the case.

Grocer Goodwill posted:

Yeah, actually you do. It is true that instead of saying "what's the projection of this vector on this other one?" you could say "Okay, give me the angle between these two vectors, I'll take the cosine and then multiply that by its length" and you'd be saying effectively the same thing, but now we're introducing trig functions for no reason.
"What's the projection of this vector on this other one" is exactly the type of operation that you can directly support. You don't have to say "dot product" explicitly because that's all just going on behind the scenes. If you are attempting to perform some operation that can be implemented easily with a dot-product and there isn't a function already for it, there's nothing to stop you, personally, from using the dot-product in your own code. Just because I attempt to provide useful, abstract functionality doesn't mean you can't drop down and use lower-level operations if you want/need to. For a quick example, as I said earlier, the types of transformations I currently expose all happen to be linear transformations. Models of this concept are required to support a "to_matrix" function, so given any of these transformations, you could always just call "to_matrix" and work with a matrix representation if you wanted to. Doing so is potentially less-efficient, since many operations don't require dealing with the concept as a matrix (such as translations, which can be directly applied to points as vector addition, and similarly, combined with other translations in such a manner). In my graphics library code, I have a function render that works like this:

code:
render( your_render_target, your_transformations_go_here..., your_objects_go_here... );
Behind the scenes, the implementation just recognizes the accumulated linear transformation, converts it to a matrix since that's what the given backend ultimately requires, and issues draws. If you want, you can pass matrices as transformations (since a matrix is a valid linear transformation), or just use high-level Transformation objects such as translations and rotations. Even though the backend requires matrices, they don't have to appear in user code and the user isn't really losing anything.

Grocer Goodwill posted:

Fine, but we're talking about a library used by programmers, here.
We're talking about domain-specific information. Not all programmers have the mathematical background necessary to properly implement this kind of stuff, nor should they be required to have such a background just to perform simple transformations.

Grocer Goodwill posted:

I meant continuously, as the target is moving. My examples all involved something more than just spatial transformations, like time.
I don't see how this is at all incompatible with such a notion. How does a programmer directly using matrices make something like that any easier?

Grocer Goodwill posted:

Not intrinsic, but it is equivalent. Saying "concatenate these transforms" and "multiply these matrices" for any kind of transform/matrix encountered in games programming are exactly equivalent. Yes, technically the matrix is the representation of the transform, which is an abstract thing, but they are completely equivalent. All you're doing is just choosing not to use the term matrix anywhere. Your abstraction isn't any more general than any other math library. I mean people don't say float trans[16] and manually plug in values, you know.
Having higher-level representations of transformations makes dealing with and reasoning about those transformations easier. For instance, let's say your are dealing with the specification of a reference frame associated with some game object. You can first represent it explicitly as a single matrix. This will work, but it doesn't directly convey information about what kinds of transformations are being used, that you are even dealing with what is to be interpreted as a spatial transformation, and it makes it more difficult to examine and to modify the individual "parts" of that transformation such as a rotation and a translation. Alternatively, you can represent the rotation part, and the translation part, etc. in separate objects or a single composite object with a more appropriate interface that lets you pull out and modify the rotation part and the translation part individually. People often already do the latter in their own code because they recognize that it is a useful abstraction to have. This library just provides that abstraction to them upfront so that they don't have to roll one on their own, and it turns those ideas into first-class objects so that they can be worked with and passed around directly rather than being implicit to an interface.

Further, a general "transformation" cannot be represented by a matrix, only linear transformations can be. The name and syntactical change is a bit more than just superficial since it implies a generalization that works with other kinds of transformations. If you don't care about that, then that's fine, you're not losing anything. It's a lot like algorithms that deal with iterators. If you only ever deal with arrays, then you can go ahead and deal with algorithms written specifically for them and disregard the fact that iterators are exposed. You don't have to take advantage of the abstraction if it's there, even though it opens you up to the world of algorithms that exist in the STL and Boost, etc.

Grocer Goodwill posted:

Why on earth would I want to do this? You are solving a problem that does not exist.
It does exist. It's one of the few reasons, expressed even in this very thread, for why programmers often don't use expression-template matrix libraries in games! Long compile times conflict with fast iteration, which really is an important concern. You don't want to have to wait through long compile times for simple changes. I don't even suggest that you should always use expression template linear algebra libraries in practice because of that, and I'm a huge advocate of expression templates. Realistically, for games specifically, it's unlikely that this would be a bottleneck, so using an expression template library isn't that important. However, when you have the ability to simply switch between expression templates and non-expression-templates by changing a command-line option, the problem of compile-times is extremely diminished since you can just use a non-expression-template version for the bulk of the development process (though you'd probably want to test occasionally along the way if switching to one is your definite, ultimate goal). Easily switching between the implementations without changing any of your own, written code means that you can test performance differences between the two and not have to make as many low-level backend decisions at the start of development, which is, of course, before you ever have a chance to do profiling in the completed project.

If it all works out, you'll potentially get a more-efficient product out of it, and if not, you haven't lost any performance since the abstraction is purely a compile-time one. Nowadays, it's pretty much impossible to say what the potential gains are since expression templates are nixed right off the bat. Overall effects don't have a chance to be considered because of the upfront cost in compile-times and complexity when debugging that is associated with expression templates.

Grocer Goodwill posted:

So your solution is to introduce another one?
No, the solution I'd like to put up is to produce open source, generic libraries that are well tested and documented and that are open to the community in general rather than to a single team whose primary concern is to complete their current game as opposed to maintain tools. It works for projects like Boost and I see no reason as to why it can't work for games. There are a lot of subdomains involved in game development that come together to form a complete product and you shouldn't have to be an expert in the underlying implementation details of each one of them to be able to produce a high-quality game. This is especially true for small, independent developers that don't have years of in-house code to rely on, regardless of its quality, and that don't have a bunch of programmers with extensive domain-specific experience employed.

Win8 Hetro Experie posted:

Maybe I'm misunderstanding the motivation for the API. I got the impression that the purpose of the API was at least in part to provide a higher-level abstraction over matrix transformations, but if the purpose is to normalize different conventions when applying linear algebra without raising the level of abstraction then my concerns here and before don't apply.
The latter is a welcomed byproduct of the former. "Transformation" is a more abstract notion than a matrix. Not all transformations can be expressed as matrices, but matrices and matrix multiplication can be used to express some kinds of transformations. A high-level transformation associated with a "translation" or a "rotation" also tends to be easier to reason about than a matrix multiplication, especially for those who do not study mathematics. Any layman knows what a rotation is and can talk about one at a high level. That doesn't mean they know or have to know that you can represent the idea in the form of a matrix. Similarly, when writing code, you're usually only concerned about the high-level concepts, with a notable exception being at the boundary with a lower-level API, such as Direct3D. A library that exposes different kinds of transformations as first-class objects means that you are able to deal with that abstraction directly in code.

Win8 Hetro Experie posted:

Is the order of parameters here order-dependent as well:


rotation( roll = 60.0 * degrees, pitch = 45.0 * degrees, yaw = 15.0 * degrees )


Because my first intuition is that the parameter order of functions is just a stylistic choice of the author.
Right now I simply don't allow that single, combined call to "rotation" and I'm undecided as to whether or not I will allow it in the future. I likely will, or something like it but with a better name, since that's a common kind of transformation. If I do allow it, though, it would definitely produce a transformation that is equivalent to accumulate_transformations( rotation( roll = 60.0 * degrees ), rotation( pitch = 45.0 * degrees ), rotation( yaw = 15.0 * degrees ) ). In other words, it's an ordered, accumulated transformation. The reason why is that if, instead, you were to assume that each rotation affected the "source" space, applied in a some certain, underlying order, then readers of the code would need to be aware of that order if they were to be able to comprehend what the code is doing. There is no need to memorize such an arbitrary convention when the rotation is accumulated directly at the call-site with the order represented right there in the top-level code.

Win8 Hetro Experie posted:

The meter is the length of the path travelled by light in vacuum during a time interval of 1/299 792 458 of a second. The second is the duration of 9 192 631 770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the cesium 133 atom in its ground state at a temperature of 0 K.

It is not relative.
Not that I was referring specifically to relativity or units defined in relativistic terms, but I'll point out that because time is relative and because the unit's definition is dependent on time, the unit of distance, too, is relative. It's called length contraction. Anyway, that's well beyond the scope of things people would use the library for and is not even what I was referring to. I'm just talking about simple transformations here, in this very particular case, linear transformations such as translations and scales that don't even deal with velocity. In these cases, simple transformations such as scales still do transform units with respect to the original space.

If you don't immediately see why the units work out the way that that they do, perform dimensional analysis on the multiplication of matrices that represent homogeneous transformations. To get you started, this is what the units look like in 3-space as applied to such a matrix, where 1 means no unit and U means the associated unit, such as meters:

pre:
1    1    1    U
1    1    1    U
1    1    1    U
1/U  1/U  1/U  1
A "mask" of units over matrices like this is idempotent with respect to matrix product as well as additive operations, just as you'd expect. If that's not immediately apparent, watch what happens when you perform a multiplication of matrices with these units, writing it out explicitly if you have to.

The underlying point is that you use the same written units while you accumulate transformations. It is perfectly valid to have such scaling operations transform the meaning of units when observed from a different frame of reference. This is expected and correct.

Win8 Hetro Experie posted:

Here's the problem, as I see it when writing code:

code:
npc.move_forward(1.0 * meter)
   .active_powerup() // is maybe .scale(0.5) in disguise
   .move_forward(1.0 * meter);
To me the first meter is the same length as the second meter, because they are both in my frame of reference, which I want to be the NPC's frame of reference as well. If the frame of reference changes in the middle it should be apparent in the code.
Perhaps it sounds unintuitive at first, as much math and physics often does, but the use of units is, in fact, proper. If you are using scale operations with respect to your frame of reference, the transformation of units really is what you should expect to happen.

Edit: Here is a quick, practical explanation using your "power-up."

You are saying that after the operation that "scales" the player, you still want movement of 1 meter to happen. If you are just accumulating matrices in a scene graph (not even talking about my library), what you have shown will cause your second "move_forward" meter units to be scaled as well. If that is not what you expect to see, then it is because you are applying the effect to the wrong frame of reference. To be clear, the operation that would transform the second "move_forward" units corresponds to a scaling operation that affects "player_transformation" in the following graph:

pre:
      (World)
         |
player_transformation
If you don't want the scale operation to affect the movement (such as if you want the player's representation to "grow" without changing his velocity), then the correct graph of reference frames would actually be:

pre:
        (World)
           |
 player_transformation
           |
powerup_transformation
Now, your powerup would only affect the powerup transformation (in this case a scale operation), but movement is still in "player_transformation" space, so the character doesn't move faster with respect to world space, he just looks larger.

Edit2:

A similar situation that's a little bit more complicated can be seen in Orzo's game, and he has a video so it's a bit easier to explain -- here he wanted to have transformations that affect a parent object but not child objects. For instance, he wants to be able to have an object be able to change size without affecting the size of objects that circle around his player (very similar to your scaling power-up). This is his approach, including a video:

http://superobelisk.blogspot.com/2013/03/entity-hierarchies.html

Skip to about 45 seconds into the video to see an example of the interesting reference-frame situation. What he does to accomplish these transformations is he has two differently named functions that change scale. One is called "size" and only affects the current object and the other is called "scale" and affects the current object and its children. Realistically, this type of "only affect this object and not children" type of thing can be applied to all kinds of transformations, not just scaling. He has chosen to provide a separately named function to do this, but equivalently, if he wanted to he could have just explicitly represented the graphical representation of that object as its own subobject, directly stemming from the same parent object (in this case the torch) just as other subobjects already do. In other words, rather than having separate functions for scale and size, he could have used a scale transformation in the parent object to affect everything including children and graphical representation, or alternatively used a scale transformation in the graphical representation subobject to just affect that and not other children of the torch. The relationship between the torch's space and the space of its graphical representation is sort of hidden away here because of the interface, but these distinct reference frames still exists if you analyze the way objects are affected by the transformations. The point is, when you are accumulating transformations, scaling really does affect the units of further transformations. If it appears as though it doesn't, it's because the relationship between reference frames is a little bit more complex than you realize.

Hughlander posted:

Other than everyone doing iOS? (And yes we do C++ 11 with it. Even lambadas.)
This makes me very happy!

That Turkey Story fucked around with this message at 16:26 on May 13, 2013

Posting Principle
Dec 10, 2011

by Ralp
oops nvm

Grocer Goodwill
Jul 17, 2003

Not just one kind of bread, but a whole variety.

That Turkey Story posted:

If this particular abstraction isn't useful, I want to know exactly why you think that's the case.
Because it's not any more general than using matrices. It adds compile time and run time cost for no benefit over matrices. All you've done is made the syntax different.

That Turkey Story posted:

"What's the projection of this vector on this other one" is exactly the type of operation that you can directly support. You don't have to say "dot product" explicitly because that's all just going on behind the scenes.
That's not "what's going on behind the scenes", that's what a dot product is.

That Turkey Story posted:

We're talking about domain-specific information. Not all programmers have the mathematical background necessary to properly implement this kind of stuff, nor should they be required to have such a background just to perform simple transformations.
Yes, they should. All game programmers need to have at least a basic understanding of vector algebra. No exceptions. This is a fundamental, pervasive activity in game programming, not a "low-level detail". And it's really not that hard to understand. More complicated things like projections can remain the domain of graphics programmers, but any programmer can learn the basics of this stuff -- vector additions, dot and cross products, orientations and bases, and basic transformations -- in an hour.

That Turkey Story posted:

I don't see how this is at all incompatible with such a notion. How does a programmer directly using matrices make something like that any easier?
It doesn't. My point is that if you're trying to create useful abstractions for game developers, that's the level you should aim at.

That Turkey Story posted:

You can first represent it explicitly as a single matrix. This will work, but it doesn't directly convey information about what kinds of transformations are being used
That's the point! I bake all of the transformations down to a matrix so I don't have to know or care about the path I took to get there. If, for some reason, I really care about e.g. a set of Euler angles, or something, I will store those instead. And if really, really had to, for whatever reason, decompose a matrix into constituent translation, scale, and rotation factors, that's trivial to do.

That Turkey Story posted:

Further, a general "transformation" cannot be represented by a matrix, only linear transformations can be.
Those are the only kind of transformations we care about in games.

That Turkey Story posted:

It does exist. It's one of the few reasons, expressed even in this very thread, for why programmers often don't use expression-template matrix libraries in games!
Why would I want to swap at the back end at all? The only back end implementation I would ever want is one that compiles down to the same machine code I would have gotten by dealing directly with matrices.

The overall point here is that all this trickery with objects and templates is that it comes with a cost, either run-time or compile-time or both. If I'm going to give up efficient code gen and/or fast compile times I better be getting some major benefit out of it, especially for a math lib which is going to be used everywhere. Handling non-linear transforms and having a C++-looking syntax is not nearly enough to make the trade off worth it. And the idea that game programmers should not have to understand anything about vector algebra is wrong-headed to begin with, and your approach doesn't really accomplish it anyway.

edit: If I'm sounding harsh, it's only due to the amount of work that this kind of thinking has caused for me personally. In the mid 2000's, the industry was expanding rapidly, and a lot of companies hired new, junior devs out of college, whose heads were full of boost and Java. Those of us who care about or were responsible for the performance of our games had to undo a lot of damage that they caused. In every single case, the counter argument was made "Oh, that way of implementing it was too slow, but the idea is sound!". After a few cycles of this, you realize that some abstractions are good, and some are not. Premature abstraction is the real evil.

Grocer Goodwill fucked around with this message at 01:43 on May 13, 2013

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Grocer Goodwill posted:

Yes, they should. All game programmers need to have at least a basic understanding of vector algebra. No exceptions. This is a fundamental, pervasive activity in game programming, not a "low-level detail". And it's really not that hard to understand. More complicated things like projections can remain the domain of graphics programmers, but any programmer can learn the basics of this stuff -- vector additions, dot and cross products, orientations and bases, and basic transformations -- in an hour.
I'm not sure about this. You can make a decent game in Unity these days without understanding any of those things. Any professional game programmer being employed as a game programmer should understand those things, but indie games are increasingly made by artists rather than programmers.

Of course, making C++ transformation math more abstract with the complexity that is template syntax (and understanding templates!) isn't contributing to those people either - for them you need your abstractions at a much much higher level. And that already exists with physics engines which largely hide all the math from the developer.

That Turkey Story
Mar 30, 2003

Grocer Goodwill posted:

Because it's not any more general than using matrices. It adds compile time and run time cost for no benefit over matrices. All you've done is made the syntax different.
I've explained numerous times that neither of these points are true. I'm not going to repeat myself yet again.

Grocer Goodwill posted:

That's not "what's going on behind the scenes", that's what a dot product is.
I refuse to believe that you don't understand what abstraction away of details means and that you don't comprehend the benefit of higher-level functions.

Grocer Goodwill posted:

Yes, they should. All game programmers need to have at least a basic understanding of vector algebra. No exceptions. This is a fundamental, pervasive activity in game programming, not a "low-level detail".
:rolleyes: It is only necessary because that is the level of abstraction that most current libraries expose. I believe I have a fairly good understanding of linear algebra especially as applied to games, perhaps more-so than many peers, but I still appreciate and welcome the abstraction away of many details. I in no way am under the impression that such low-level knowledge should be necessary for someone to make a game, just that it currently is required due to the state of the abstractions that we have (or rather don't have) readily available. You've made it clear that you simply don't agree, so whatever. I can't argue with that beyond what I've already presented. Just don't use the library if you've made up your mind already.

Grocer Goodwill posted:

Those are the only kind of transformations we care about in games.
No, they're not, and even if they were, again, it's not hurting you at all that you're able to use vocabulary that directly takes that into account. It's not any more difficult. Since you so easily write off these transformations as never being useful with games, a quick example of such a transformation in games that's nonlinear is the type of transformation done when dealing with an image rendered by an Occulus Rift. Here you're not doing the transformation in C++, but rather in a shader, but the point is that these nonlinear transformations genuinely do come up in practice and yes, even in games. If you personally don't care then that's fine, you don't care, and I doubt I'll change your mind no matter what I say. That the library is general enough to handle this simply doesn't impact you. It's no extra effort on my part to support it, it's just a side-effect of the abstraction.

Grocer Goodwill posted:

Why would I want to swap at the back end at all? The only back end implementation I would ever want is one that compiles down to the same machine code I would have gotten by dealing directly with matrices.
I'm not sure what you are trying to say here. Expression template libraries deal with matrices as well, as do non-expression-template libraries that just take explicit advantage of a processor's vector instructions. These different implementations are more or less efficient for different situations and have different trade-offs, both at run-time and compile-time. A simple, hand-rolled vector/matrix library is not going to be as fast as something like Eigen, and without being able to easily switch between them, you are stuck with whatever choice you made at the project's onset, which is before you've ever had any chance to do profiling and at a time when fast iteration outweighs overall performance. Perhaps you personally don't understand this, but others do.

That Turkey Story
Mar 30, 2003

roomforthetuna posted:

Of course, making C++ transformation math more abstract with the complexity that is template syntax (and understanding templates!) isn't contributing to those people either - for them you need your abstractions at a much much higher level. And that already exists with physics engines which largely hide all the math from the developer.
Yeah, that's the biggest problem I see and agree with -- the complexity of utilizing templates. Ultimately, I personally think it's a shift of complexity worth making, since an understanding of the language is applicable to any development that you do in that language, whereas the understanding of the details of a particular domain is only applicable to that particular domain. Also, thanks to C++11 features like "auto" and "decltype," a lot of the complexity that you used to imagine when you thought of templates is no longer there. There are still places where things leak through a bit, such as the declaration of class members (as auto isn't really applicable here), but even that isn't horribly hairy due to the way I present things. Regardless, if you are anti-template, you're not going to want to use this.

Also, in case it wasn't clear, I'm not targeting people that don't know the language (I.E. I'm not targeting artists that simply want to dabble in game development). If you don't know C++, a complicated project in it is probably not your best bet and a lack of understanding of linear algebra is only one of a long line of problems you might encounter. On the other hand, if you are a programmer who wants to make a game and you aren't already familiar with the details of how we deal with transformations as matrices, or if you are thoroughly familiar with them and you simply expect a higher-level interface, then this kind of library is probably much more ideal.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Yeah, I think that's a lot of the resistance you're encountering here - while templates are useful in any C++ domain, transformations are useful in almost any game domain. So your thing may be useful for C++ programmers who want to dabble in games, but it's counterproductive for game programmers who want to dabble in C++ - either they already know their transformation math, in which case they don't need the abstraction and would be learning something extra for little if any benefit, or they don't already know their transformation math, and would be better off learning that because there's a decent chance they'll end up making games using C# or Python or HTML5, where the math will still apply and the templates won't.

(And most people who are neither a C++ developer nor a game programmer, who are interested in making a game, are aiming to fall into the latter category.)

That Turkey Story
Mar 30, 2003

roomforthetuna posted:

Yeah, I think that's a lot of the resistance you're encountering here - while templates are useful in any C++ domain, transformations are useful in almost any game domain. So your thing may be useful for C++ programmers who want to dabble in games, but it's counterproductive for game programmers who want to dabble in C++ - either they already know their transformation math, in which case they don't need the abstraction and would be learning something extra for little if any benefit, or they don't already know their transformation math, and would be better off learning that because there's a decent chance they'll end up making games using C# or Python or HTML5, where the math will still apply and the templates won't.

(And most people who are neither a C++ developer nor a game programmer, who are interested in making a game, are aiming to fall into the latter category.)
Understood. I agree that most existing libraries in other languages don't expose anything higher level than matrices and so if you are jumping around between languages with limited libraries, it can help to understand things at the lowest level possible. The problem I see is that if you are using this as a rationale to not include higher levels of abstraction when designing a new library in a specific language, you will simply never make progress toward higher level libraries at all. At some point, programmers just have to try and push the boundary.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
When you build something more serious than a Doctor Mario clone that literally does not use any part of the functionality provided by your patented transform engine, I might stop laughing at you.

That Turkey Story
Mar 30, 2003

Suspicious Dish posted:

When you build something more serious than a Doctor Mario clone that literally does not use any part of the functionality provided by your patented transform engine, I might stop laughing at you.
When you have any worthwhile criticisms, I'll listen. I'm sorry that I don't have Half-Life 3 ready and waiting for you already implemented in a library that I'm developing.

Also, it does use this functionality, I just don't have a big, explicit scene graph that you might expect to see in a more complicated game.

That Turkey Story fucked around with this message at 04:49 on May 13, 2013

Bizarro Buddha
Feb 11, 2007
I think the biggest problem with your testbed being a Doctor Mario clone is that the use of transformations in 2D games is a lot simpler, so you won't be encountering the complexities that might crop up using your library in a 3D context.

seiken
Feb 7, 2005

hah ha ha
Yeah, Turkey Story; I dig templates and I'm writing a C++ game that uses templates and metaprogramming wherever it's appropriate, and I think your library sounds interesting. But to show it off properly and convince people it's worthwhile you should really have at least a simple 3D game that uses it -- ideally one that involves lots of transformations, for instance a spaceship dogfighter kind of game. 2D math is kind of trivial anyway (and does Dr Mario even need rotations?).

That Turkey Story
Mar 30, 2003

Bizarro Buddha posted:

I think the biggest problem with your testbed being a Doctor Mario clone is that the use of transformations in 2D games is a lot simpler, so you won't be encountering the complexities that might crop up using your library in a 3D context.
Maybe it's my fault for not being more explicit earlier, but it's literally the same exact code inside of the library. All of the functions you've seen are the same implementation with the same name in 3D, you just pass functions like "translation" an extra parameter. Nothing is qualitatively different in 3 dimensions over two except that for orientations you often want to use abstractions over quaternions instead of individual rotations through exactly two dimensions like "yaw," "pitch," and "roll." All of the translation, scale, rotation, shear, reflection, etc. code that I've shown or talked about isn't specific to 2D at all. It's metaprogrammed (this is the part that I assumed would be scary to other game developers, not me simply calling a "rotation" a "rotation" instead of a matrix, but I guess you discover new things every day). I don't even switch to a different partial specialization behind the scenes for 2D instead of 3D -- it's all the same, generic, written code. The majority of my tests are even written for 3D.

seiken posted:

Yeah, Turkey Story; I dig templates and I'm writing a C++ game that uses templates and metaprogramming wherever it's appropriate, and I think your library sounds interesting. But to show it off properly and convince people it's worthwhile you should really have at least a simple 3D game that uses it -- ideally one that involves lots of transformations, for instance a spaceship dogfighter kind of game.
Again, the top-level code wouldn't push the libraries much if at all more, the difference would just be quantitative on my part when developing the example. I'm doing all of this in my spare time, primarily as an exercise for myself as it's something that I would like to use and an approach that I would like to experiment and work with. If someone doesn't "get" it, then oh well. I'm not going to drop everything to make people a big game while everything is still in its infancy. I've already wasted enough time just writing up gigantic replies explaining basic linear algebra and dimensional analysis to people who, ironically, champion working at a low level. Maybe after I finish the libraries, if I ever even do, I'll make a big, complicated game for people to look at and dick around with, but at this point I don't know if I'll get there. At this point it's still a playground of ideas.

seiken posted:

2D math is kind of trivial anyway (and does Dr Mario even need rotations?).
Sure it does, that's one of the few things that you can do. You move and rotate pills. Anyway, as I said earlier, the math and code in the spatial library is the same in 3D and it's all just metaprogrammed. For instance, a translation is no different in 3D, a scale is no different, even things like yaw, pitch, and roll are no different. All of these just correspond to matrices with more rows and columns with the exact same amount of trigonometry being used (I.E. even a yaw rotation matrix in 3D is exactly the same as a rotation matrix in 2D only that if you explicitly represent it in 3D you have an extra "identity" row/column, of all 0s and a 1). Accumulation of transformations is still just equivalent to matrix multiplication, regardless of how many dimensions you are working in. If you happen to be using a yaw/pitch/roll system for your particular game in 3D, the only thing more complicated mathematically is that you're combining more of these transformations together. One of the only major qualitative differences concerning transformation that comes up in practice when in 3D rather than 2D is that, again, in 3D you often won't have orientation represented as yaw/pitch/roll and instead deal with something like quaternions for orientation.

That Turkey Story fucked around with this message at 16:20 on May 13, 2013

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Yes, it's the same math. That doesn't say anything for whether your high-level don't-think-about-it API is good for 3D or not. You're designing an API for 3D transformations without having anything that uses the API. Nobody knows if it's a good API yet, because nobody has used it.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
When you build something more serious than a Doctor Mario clone that literally does not use any part of the functionality provided by your patented transform engine, I might stop laughing at you.

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?
Ok, seriously, both of you - take it off-forums.

That Turkey Story, I still question the applicability of your library. I would suggest that the response you're getting here is the response you're going to get everywhere / you appear to be making a product to fill a non-existent niche. BUT. You're still welcome to keep posting about it. It's a potentially cool project whether or not it has applications anywhere (much like hobby raytracers, etc).

The back-and-forth bickering, however, needs to end. Now.

Shalinor fucked around with this message at 17:29 on May 13, 2013

seiken
Feb 7, 2005

hah ha ha

That Turkey Story posted:

Anyway, as I said earlier, the math and code in the spatial library is the same in 3D and it's all just metaprogrammed. For instance, a translation is no different in 3D, a scale is no different, even things like yaw, pitch, and roll are no different. All of these just correspond to matrices with more rows and columns with the exact same amount of trigonometry being used (I.E. even a yaw rotation matrix in 3D is exactly the same as a rotation matrix in 2D only that if you explicitly represent it in 3D you have an extra "identity" row/column, of all 0s and a 1).

I'm totally aware the math generalises pretty straightforwardly from 2D to 3D, but that certainly doesn't mean the library would be just as impressive used in a 2D game as it would be when used in a 3D game. The actual doing things in practice doesn't generalise nearly so neatly, if you're working at the matrix level. Anyone can kludge together a 2D game with iffy math; you're not going to get far in 3D without understanding things properly. This is why showing a 3D game with code as simple as a 2D game would be the perfect defense of your library's utility.

Yaw, pitch and roll, for instance, are totally different, because there's three of them, instead of just one, and they're not independent. 3D games tend to depend a lot more on the order in which successive transformations are built up, multiple reference frames, and so on. In 2D you can pretty much always get away with just scaling and rotating a sprite, and then translating it directly to the correct place in camera co-ordinates, even though it might not be the best idea.

I'm not saying you need to have some incredible masterpiece thing, just something that actually shows off how the abstractions make things simpler. That's why I suggested a dogfighter, or even something like a 2D vector game that makes use of all sorts of different accumulated transformations to make neat animations, or whatever.

seiken fucked around with this message at 23:43 on May 13, 2013

a slime
Apr 11, 2005

Shalinor posted:

Ok, seriously, both of you - take it off-forums.

That Turkey Story, I still question the applicability of your library. I would suggest that the response you're getting here is the response you're going to get everywhere / you appear to be making a product to fill a non-existent niche. BUT. You're still welcome to keep posting about it. It's a potentially cool project whether or not it has applications anywhere (much like hobby raytracers, etc).

The back-and-forth bickering, however, needs to end. Now.

The "back-and-forth bickering" is pretty enlightening, despite the unnecessary hostility. This entire argument over the last few pages (high level language features versus gamedev) is very relevant, and I see no reason it shouldn't be had in this thread. There is a definite bias in the gamedev community against abstraction and code reusability, and it is really interesting to see people try to argue against it.

TJChap2840
Sep 24, 2009

a slime posted:

The "back-and-forth bickering" is pretty enlightening, despite the unnecessary hostility. This entire argument over the last few pages (high level language features versus gamedev) is very relevant, and I see no reason it shouldn't be had in this thread. There is a definite bias in the gamedev community against abstraction and code reusability, and it is really interesting to see people try to argue against it.

The hostility is getting out of control though. I think that is Shalinor's main concern. I get excited when I see 10 new posts in here but recently it's just been passive aggressive attacks back and forth.

One thing I have learned from this discussion is that I forgot everything I learned once I graduated after passing Linear Algebra my final semester in college.

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?

TJChap2840 posted:

The hostility is getting out of control though. I think that is Shalinor's main concern. I get excited when I see 10 new posts in here but recently it's just been passive aggressive attacks back and forth.
Bingo. That's the part that needs to go. I'm just skeptical that can go without the bickering going entirely.

Yodzilla
Apr 29, 2005

Now who looks even dumber?

Beef Witch
As a newbie games programmer I'm absolutely fascinated by the back-and-forth in this conversation.


I will say from my limited experience that I do agree with Grocer Goodwill's remark that all game developers need to have some notion of vector algebra. Unless you were making some sort of text-based adventure or MUD or something else that's just a command line if you're going to have parts that move you're going to need to understand and create that movement.

DrMelon
Oct 9, 2010

You can find me in the produce aisle of the hospital.
I've been hard at work making my first ever game in Actionscript for University coursework; it's a simple little shmup, still unfinished as yet although the deadline is Friday. I'm pretty happy with it so far, here's a test build:
http://www.doctor-melon.com/courseworksem2.html


Currently on the todo list: give the boss some weapons and an introduction, make a title screen and allow the player to reset the game and so on.

I would have used Flixel but the coursework specification stated that external libraries should be kept to a minimum, and not used at all if possible. As such, there's quite a few ropey things going on here and there.

e: Whoops, that wasn't quite the latest build. Uploading a new one, it'll be up in a minute. Clear cache and refresh (Shift+F5) if the boss dies in one hit.


After the coursework is done, I'm thinking of maybe making it into a summer project by porting it to Haxe to make it run on Android and stuff, after some polishing. Fun!

DrMelon fucked around with this message at 03:36 on May 14, 2013

xgalaxy
Jan 27, 2004
i write code
I see haxe getting mentioned a lot lately and awesome screenshots like this have driven me to look into it a bit more. It's pretty easy to get going but the only IDE with good haxe support seems to be FashDevelop. What are people doing on OSX?

Video of the above screenshot. Good god that looks awesome.
https://www.youtube.com/watch?v=q1ywDZvJ3tY

xgalaxy fucked around with this message at 05:32 on May 14, 2013

Chunderstorm
May 9, 2010


legs crossed like a buddhist
smokin' buddha
angry tuna
Goons, I come to you in my time of need.

I'm trying to make little damage popups in a turn-based battle system, like this:


I've tried getting the position of the gameObject using WorldToScreenPoint and WorldToViewportPoint and displaying it in GUI, and I tried fiddling with GUIUtility.ScreenToGUIPoint, but neither has yielded any success. Anyone got experience with this?

e: The conditions for displaying it are in place, the actual displaying is the problem

superh
Oct 10, 2007

Touching every treasure
Does *something* display, just in the wrong spot, or does nothing display at all?

If it's the former, the math finding the screen point is probably wrong. If it's the latter, you might have the math right but you're not creating the element correctly.

Can you make damage numbers pop up at a fixed point in the GUI successfully, independent of where they're "supposed" to spawn?

Adbot
ADBOT LOVES YOU

Chunderstorm
May 9, 2010


legs crossed like a buddhist
smokin' buddha
angry tuna
Well, I DID have the problem of it not showing up, which I managed to fix. Now the math is just wrong.

e:
code:
GameObject battlecam = GameObject.Find("Main Camera");
Vector2 showDamageHere = battlecam.camera.WorldToScreenPoint(staticVariables.attackTarget.gameObject.transform.position);
float screenX = showDamageHere.x;
float screenY = showDamageHere.y;
screenY = Screen.height - screenY;
GUI.Label(new Rect(screenX, screenY, 50, 20), damageString);
Fixed code above. I'm sure there's a better way to do this, but oh well.

Chunderstorm fucked around with this message at 16:48 on May 14, 2013

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply