Jump to content

  • Log In with Google      Sign In   
  • Create Account

Trienco

Member Since 22 Aug 2001
Offline Last Active Yesterday, 11:21 PM

#5190084 weird header behavior in gcc and llvm

Posted by Trienco on Yesterday, 11:21 PM

Header guards do exactly zero to help with circular includes. In fact, they are causing the problem in the first place (kind of, otherwise you'd get endless recursion and are still screwed). You use them to prevent getting multiple declarations of the same stuff for one source file. You have the opposite problem where your circular includes result in one header trying to use something from the other header before it was ever declared (no matter which order you include them).

 

A says "copy everything from B to here, because I need it declared before my stuff", then B says "copy everything from A to here, because I need it declared before my stuff". But A already declared the header guards and nothing is included. You end up with a file in the order B - A - source. B is trying to use stuff from A that is only declared further down and you get errors.

 

The two steps when you have circular includes is a) ask yourself if you screwed up the design when you introduced circular dependencies in the first place and if your answer is "no" then b) break them with forward declarations.

 

Okay, technically you should prefer forward declarations anyway (at least if you just need a single class or two... but then, if you find yourself needing declarations for dozens of functions from somewhere else in a header file, you probably got bigger problems).




#5189335 Error: unique_ptr constructed with null deleter pointer

Posted by Trienco on 26 October 2014 - 10:45 PM

Since the error is about the default constructor, I'd blame it on the map creating a default constructed object if you call the [] operator with a new key. Are you getting the same error for simpler containers like a vector or if you try using a shared_ptr? Maybe some detail about the operator [] implementation is screwing you over and tries to copy a default constructed unique_ptr?

 

emplace is definitely more likely to work than insert. Does the error move somewhere else if you comment out the code in add_resource? If not, the problem really seems to be limited to adding it the proper way. If it does, the problem is probably more fundamental than that.




#5187575 What a web I Weave !

Posted by Trienco on 16 October 2014 - 10:04 PM

Once you reduced the size of a file from 3.5MB to 2.5MB by replacing space indent with tab or simply appreciating the fact that you can set the tab width in your editor according to your own preference, you will start wondering why anyone in their right mind would even consider spamming spaces to indent stuff.

 

"But then it won't look the same in all editors". Yes. Exactly. I can tailor the readability to my personal preference without impacting anybody else.

 

"But then stuff on different lines might not be properly aligned anymore". Well. True. Except we're writing code, not ASCII art. So stop creating those neatly aligned variable declaration blocks (unless you really ARE still using an ancient C compiler that enforces bad programming practices).

 

Now, mixing tabs and spaces is just awful, horrible and completely ruins your formatting pretty much everywhere except in the editor of origin...




#5185448 Lines of code language comparisons

Posted by Trienco on 06 October 2014 - 10:34 PM

Well, here's an empirical fun fact I basically get to observe every day: a bad programmer solves trivial problems in less time and with more lines of code than a good programmer. Why? Because rather than putting some thought into it, he simply brute forces it. Because he doesn't bother with refactoring his result for better readability and maintainability. Because rather than refactoring, he just copy/pastes existing blocks of code all over the place.

 

So by producing way more code in less time, he's clearly more productive, right? If your answer is 'yes', you are probably a project manager...




#5183240 Source control with git hub/lab?

Posted by Trienco on 26 September 2014 - 11:04 PM

Really? A new branch for every change? Never heard anyone doing that.

 

That's pretty much the basic rule when using git. You could even go as far as saying "master is for merging, not for developing". Just make it your goal that master is always in a decent state, builds and isn't a messy construction site.

 

Of course the usefulness of heavy branching varies. If you're working alone and have a habit of finishing on thing before you start working on something else, then branching is somewhat pointless. If you work on a team or keep working on multiple things at once, then you absolutely should get into the habit of using on branch per "thing" (if you say "feature", keep in mind that a bug fix for something that was already merged is a "feature" as well).

 

We're using Gerrit at work, which requires all changes that get pushed to be reviewed before they get merged to master (plus, a build is automatically started to verify the project still compiles... in the future, we might make unit tests still passing a requirement as well). Since every commit turns into a review, you will quickly learn to appreciate keeping every feature separate and tidying up your branch history with interactive rebases before pushing. Of course some people just dump several changes into one, creating an absurd number of changed files, making reviews seriously annoying (because you never know which changes actually belong together) and then complain if they need to fix something, because it's all just one big mess.

 

If you find working (and especially branching) with git unwieldy, I'd suggest GitExtensions. It lets you do most tasks without needing a command line and gives you a very good overview of your repository structure. Alternatively, SourceTree looks extremely similar.




#5181188 reading float from binary file (endian problem?)

Posted by Trienco on 17 September 2014 - 09:39 PM

Even if you're now looking at the correct container, all these "if's" look like a horrible idea. At this point your code should abort and return an error, not happily continue on to create a corrupt and broken file, so you can then spend days debugging your file reading function or wonder about endian issues.

 

Alternatively, at least write some kind of marker that will tell your reading function if a block exists or not.




#5179004 C++ starter

Posted by Trienco on 08 September 2014 - 09:38 PM

Somewhere in Visual Studio there's the well hidden property manager and from there you can find property sheets for your user. That's where I dump all paths to headers and libraries I use a lot (boost, etc.). In some Express versions it's hidden even more behind first having to change to some "expert view".




#5178795 How difficult(or not) do you find these C++ tests?

Posted by Trienco on 07 September 2014 - 10:15 PM

Is it weird that my answer to most questions about the output of the program was: "the responsible programmer losing his job"?




#5174919 Destructor in vector called too often

Posted by Trienco on 19 August 2014 - 10:12 PM

There was a known bug when using the initializer list for containers (especially visible when storing smart pointers) which always screwed up the first element. If you didn't already, make sure you have the latest updates installed (I'm relatively certain that the problem was fixed in one of them).

 

Not necessarily your problem, but I spent all afternoon debugging why it's always the first element in my map that was invalid immediately after it's definition. Turned out plenty of other people saw similar bugs with other container types.




#5161412 OpenGL Camera Concept

Posted by Trienco on 18 June 2014 - 10:24 PM

Hehe yeah oké smile.png thanks for clarifying. I'll make sure to add some extra statements nevertheless since it's a good insight that an FPS camera is not an all-round camera system with eular angles.

 

Well, I guess it would work for third person as well. Pretty much any situation where your side to side rotation is always around the global y-axis should be safe and the look-at approach is fine if the rotation around x never goes to or beyond +/-90°.

 

Btw. there is one downside to storing the orientation as a matrix (or quaternion): floats suck. After a bunch of rotations, the vectors that should be will be no longer normalized and in the case of a matrix, the rotation part will be no long orthogonal on top of it. So every once in a while, the matrix will need to be re-orthonormalized (basically 2 cross products and 3 normalizations. With a quat, that should be only a single normalization.

 

While this sounds like a great advantage:

-it only needs to be done every once in a while.

-even if done once per frame, it's nothing compared to all the other things going on

-unless your pipeline can natively use quats, you'll still have to convert them to a matrix every frame (so you don't really win anything)

-if you need info from the camera (like view direction for bill boarding), simply reading the 3rd column of the matrix is easier than having to calculate it by transforming 0,0,1 by your stored quat




#5159198 OpenGL quaternions

Posted by Trienco on 09 June 2014 - 12:32 AM

As long as you keep scaling out of it, the only thing to really understand is what each column of your matrix means: right, up, forward and position (assuming your model is created with x/y/z as right/up/forward). You shouldn't need to figure out any axis (like "what direction is up"), since they are right there in your matrix. Understanding what these columns (ie. vectors) are usually makes the difference between "I want my object to face point B, how do I figure out the axis and rotation to make it point that way" and "I'll just set the matrix to have it point that way" (generally this also involves embracing the cross product, since this will give you the third vector when you already know two, like "right" when you already know "up" and "forward").

 

The other important thing is that it makes a huge difference whether you multiply your matrix from the right or left, because it means the new transformation either happens before or after every transformation you applied so far. This also neatly translates to global vs. local. In other words, whether you want to rotate around your current "right" or the worlds "east", you always create a rotation matrix around "x" (1,0,0). The only difference is multiplying it from the left or right.

 

But since you keep talking about your view matrix, please keep in mind that the view matrix is usually the inverse of your imaginary camera's transformation. If the camera moves up, your view matrix will transform everything down. If it rotates left, the matrix rotates everything right. The easiest way is to handle the camera like any other object and only invert the matrix to get the view matrix (again, keep scaling out of it and inversion is trivial compared to a generic matrix inverse).

 

Visually it helps to stick one pencil in your ear, one in your mouth and imagine a third sticking out of your head (I'd advice against actually doing so). Those three pencils and the location of your head are exactly what a transformation matrix is.




#5159013 OpenGL quaternions

Posted by Trienco on 07 June 2014 - 09:42 PM

If you are still dragging three angles around and keep rebuilding your rotation from scratch by doing three rotation in a fixed order, then yes, you probably achieved nothing but tons of head ache and overhead.

 

The key to avoiding gimbal lock isn't using magical fairy dus.. quaternions, but to stop using Euler angles. Do not store angles, period. Any order of rotation is lost if you just wildly sum up angles. When something rotates, apply the rotation directly to the matrix or quaternion. When using matrices, multiply either from the left or right, depending on whether you rotate around a global or local axis.

 

It doesn't matter if you store your rotation as quaternion or matrix. They are completely equivalent and just two ways to represent the same thing. Which one is "better" depends on what you do with it. For a single camera, neither memory nor performance is an issue, so matrices are usually a lot more intuitive. If you need to store a huge number of rotations or need to concatenate lots of them per frame (skeletal animations for example), then quaternions are probably a better choice.




#5149289 math problems

Posted by Trienco on 24 April 2014 - 10:06 PM

 

Wouldn't this actually be more complicated? I would need to create regular greed and rotate it 45 degrees, and than additionally transform mouse coordinates. Seems interesting but I am not quite sure how I would handle data in this case. Would I save out all data as if it was square greed and transform it on run-time?

 

 

You need to separate the internal logic of your game and how you visualize it. When your characters move from tile to tile, you don't think "iso". When you determine line-of-sight, you don't think "iso". The iso perspective only exists on your screen and the only time you should give yourself an iso-head ache is for rendering and mouse input.

 

I'm not saying "draw a rectangular grid and transform it", I'm saying "think of the non-rotated top-down view as much as you can".

 

How are you storing your grid in memory?




#5149100 math problems

Posted by Trienco on 23 April 2014 - 10:30 PM

If your map is diamond shaped and all tiles are flat and regular, the easiest way is to just convert from world to tile coordinates without fancy look ups or unnecessarily generic point-in-geometry tests.

 

const int tile_x = x/192 + y/96;
const int tile_y = y/96 - x/192;
 
x and y are world coordinates in relation to the rectangle around your map (so mouse coordinates need to be adjusted for scrolling and zooming). 
 
Or just base your math on the simple idea that your map is a rectangular grid rotated by 45° and 60°, transform your mouse coordinates accordingly and you should get the same result (essentially the above).
 
Getting a feeling for this mapping/transformation also helps if you want to combine 3D objects with a 2D iso map or visualize internal 3D info for debugging. For example, the internal data used in Jagged Alliance 2 for line of sight etc. (video)



#5145843 What it's like to be a software engineer (video)

Posted by Trienco on 09 April 2014 - 10:01 PM

 


I don't think it's fair to make this about engineers vs. non-engineers, though.
It's just people who know the field versus people who don't. It would be exactly the same if the positions were reversed (the engineer calling the shots on marketing and asking a marketing expert to do the impossible).

 

 

True, but one of those things constantly happens in the real world, while I've never ever heard about the other.

 

My "favorite" exchange so far was something like this: "We need you to add this functionality."  "That's technically impossible."  "Well, you better make it possible, because we already sold it to the customer."

 

In fact, I got a little bit of naive hope that with reversed roles, engineers would be more likely to approach things by asking "would it be possible", rather than "do it, we don't care how" or "I don't want to hear about problems, I want solutions".






PARTNERS