Jump to content

  • Log In with Google      Sign In   
  • Create Account

haegarr

Member Since 10 Oct 2005
Offline Last Active Yesterday, 12:39 PM

#5247392 Quaternions for FPS Camera?

Posted by on 18 August 2015 - 08:37 AM


Right now I'm just playing with the camera. I've added it to the scene at 0, 0, 0. I've gotten it to rotate using camera.rotation.x/y. From what I've seen, other people seem to implement a vector that the camera "looks at" (using the .lookAt function). [...]

The look-at function is useful to align the camera once or tracking an object. It is just one possibility to control the camera.

 

IMO you should understand it so: The camera is an object in the world similar to a game object. It has a placement (position and orientation) and additionally field of view and other view related stuff. The camera by itself does not change its placement. Then you can apply the functionality of objects like LookingAt or Tracking or Parenting or … to control the placement in part or totally. That way gives you maximum flexibility.

 

 


[…] Really I just want to create a camera that allows me to look around in the scene. I put a cube at 0, 0, 5 and just want to be able to move the camera around and look at the cube from different angles. For the development I'm using Threejs (threejs.org).

Well, that sounds not like a FPS camera but a free camera perhaps with a tracking constraint control.
 
As said, I'd implement this as a camera object with a placement. The placement should be able to provide a matrix that stores the "local to global" spatial transform. The placement should provide an API for setting and altering position and orientation separately. Then I'd implement a camera control that processes input, generates movement from it, and applies it to the attached Placement (which, of course, belongs to the camera in this case).
 
I'd further implement a control Tracking that is to be parametrized with (a) a Placement that is to be tracked (its position, to be precise) and (b) a Placement that is the target to be altered (its orientation, to be precise). The math is so that the difference vector from the Placement.position of the target to the Placement.position of the tracked placement is used (after normalization) as forward vector of the typical look-at functionality. What need to be done then is that the control is invoked every time the Placement.position of the target object has been settled after being altered.



#5247371 How to revert the scale of a matrix?

Posted by on 18 August 2015 - 06:28 AM

It depends. In general you cannot reconstruct the history how the one available matrix was generated from the matrix alone. You can just decompose the matrix into an equivalent translational and scaling transform (letting rotation aside as mentioned in the OP), replacing the transform of interest with its desired substitute, and re-compose, so that the translational part is not effected. But if the composition was done so that the position was effected by a scaling (as e.g. in S1 * T * S2), then you cannot eliminate scaling totally (AFAIK).

 

So in your case decomposition is relatively easy, because in a homogeneous 3x3 matrix without rotation there is an embedded 2x2 matrix that is effected by scaling only but not by translation. You get this sub-matrix if you strip the row and the column where in the 3x3 matrix the homogenous "1" is located. The resulting sub-matrix must be a diagonal matrix, e.g. only the values at [0][0] and [1][1] differ from zero. Those both values are in fact the scaling factors along x and y axis directions, resp. Hence setting both these values to 1 will do the trick.




#5247335 Quaternions for FPS Camera?

Posted by on 18 August 2015 - 02:43 AM

Well, on the lowest level you just need setters for the camera's placement as usual for any game object. However, it is the camera control where all the nasty math really happens. As a 1st (or 3rd) person camera, the placement of the camera is bound to the player's game object by parenting. This is also standard stuff, well solved by concatenating matrixes. There usually is some freedom in rotation so that the player can look up / down and left / right relative to the orientation of the game object. On the other hand the rolling is often constraint to zero. This together would give the local orientation. The local position may be fixed for 1st person camera (as opposed to 3rd person cameras). There may be additions working on the local position like camera shaking or bobbing (a controversial topic though), depending on given circumstances. Without knowing how the camera should actually behave, giving tips for its implementation (besides the standard placement) is almost meaningless. So could you (the OP) describe us what exactly you want, how your general game object placement works, and what you have so far?




#5246668 My graphic objects (Gfx)

Posted by on 15 August 2015 - 05:35 AM

What do you think, please?  :-o

Well, I haven't got the clue what you want to do really. Honestly, "graphic objects are vectors of vectors of graphic objects" sounds to me not to be a sane concept. It appears to me that you mix several aspects (at least game object composition, its graphical representation, its world placement, its rendering parametrization, visibility culling result and even its temporal coherency) into a single object. That highly violates the single responsibility principle.

 

There are named constructors for each special type.

I never heard of "named constructors" and "untitled constructors" … where does that came from? Usually the term "constructor" is used for what you name "untitled constructor", and those others are usually called "factory methods" or perhaps "generators" or "creators".

 

2) Collections of direct objects work pleasantly faster than pointers.

Not necessarily. Swapping pointers is definitely more efficient than swapping any non-POD objects.

 

4) Unions is a way to not just alternate data types, but also name members in appropriate, readable way. (This is not intended union usage though)

Well, your usage of unions in the OP's code snippet is mostly meaningless because (a) you use anonymous unions and so they do not add to variable names, and (b) include a single variable only. The only case where the latter is not the case is with the union that includes "map" and "gfx_container". However, the factory method for sprites hint at the usage of both "map" and "base" for sprites, so that would corrupt your union data though!

 

BTW: All of your factory methods are incomplete because they actually do nothing. They further are specified to return a pointer but do return nothing at all.

 

Let's say, I planned 10 possible rendering orders, so my vector consists of 10 vectors.

What exactly is a "planned rendering order"?




#5245931 The best way to manage sprite sheet animations?

Posted by on 12 August 2015 - 04:03 AM

Any inherent complexity to a problem cannot be removed. What we used to do is to partition a complex problem into couple of less complex problems that are interconnected. When I look at the code in the above post I see that decision making, state control, animation playback as well as transitions all is handled at the same place. Moreover, the approach is less data driven then it can be. Don't get me wrong: There is no silver bullet that makes this kind of thing a breeze; one ever will have to run a bunch of condition checks in the one or other form as long as complex situation handling is wanted. And of course we want to please the players, don't we?

 

a) In this code snippet

 if (left_down)
 {
    if (facing == FACE_LEFT) { animationPlayer.PlayAnimation(rollForwardAnimation); velocity.X = max_speed.X * -2; }
    if (facing == FACE_RIGHT) { animationPlayer.PlayAnimationBackward(rollForwardAnimation); velocity.X = max_speed.X * -2; }
    rolling = true;
    jump_type = 1;
 }

because "rolling" is set regardless of the value of "facing", I assume that "FACE_LEFT" and "FACE_RIGHT" are the only both possible values. Even if not, the hint I want to give is valid anyway. Well, the inner distinction is made purely to be able to invoke a forward playback or else a reverse playback (the other stuff in the statement block is identical). Now having a 3rd variant of API invocation like

void AnimationPlayer::play( AnimationID selection, bool reverse )

would unify both cases by introducing an additional variable (data instead of code), so that an invocation like

 if (left_down)
 {
    animationPlayer.play(rollForwardAnimation, facing == FACE_RIGHT);
    velocity.X = max_speed.X * -2;
    rolling = true;
    jump_type = 1;
 }

would be sufficient.

 

b) Another issue with the above example is that the code implements a behavior (oh, we want to roll forward / backward) and knowledge about the animation details (oh, we do not have an animation for backward rolling, so we need to playback forward rolling but in reverse order). Why isn't there a definition for a rollBackwardAnimation clip, where the details of what frames and playback direction are hidden in the definition of the animation clip? 

 if (left_down)
 {
    animationPlayer.play(facing == FACE_LEFT ? rollForwardAnimation : rollBackwardAnimation);
    velocity.X = max_speed.X * -2;
    rolling = true;
    jump_type = 1;
 }

.

c) Now, how often is AnimationPlayer::play(…) invoked in a single run through the if-then hell? If it is more than once then obviously some wasting happens. IMHO, however, even 1 invocation is too much, with a similar reasoning as above: Decoupling. If possible the controller should not know about the animation system. From a logical point of view the animation happens later in the game loop when all controlling has been done already.

 if (left_down)
 {
    movement = facing == FACE_LEFT ? rollForwardAnimation : rollBackwardAnimation;
    velocity.X = max_speed.X * -2;
    rolling = true;
    jump_type = 1;
 }

.

d) There is some redundancy in the data here. We have "facing" with 2 possible states, "movement" with 3 possible states (including neither forward nor backward rolling), and velocity.X with 2 possible states (if reduced to be either less than 0 or to the left, greater than 0 or to the right, or equal to 0). Oh, and also "rolling". I do not know all the nitty-gritty of the implementation, but from what can be seen it seems me that 

 if (left_down)
 {
    movement = rolling;
    velocity.X = max_speed.X * -2;
    jump_type = 1;
 }

would be sufficient here.

 

e) Often abstracting the "physical" input is also beneficial. For example, the "left_down" and "right_down" variables smells like physical input for me. If this would be converted in advance into something along

bool actionRequested = left_down || right_down;
int direction = left_down ? -1 : right_down ? +1 : 0;

then the example would come down to

 if (actionRequested)
 {
    movement = rolling;
    velocity.X = max_speed.X * 2 * direction;
    jump_type = 1;
 }

and would already include the original if(right_down) branch. 

 

Of course, now the animation control has to look at the kind of movement and the velocity to be able to pick the correct animation clip. But notice that this stuff is moved out of the character control code, and hence we've followed the problem partitioning principle: We've divided up the complexity, one part is handled in the player control code and the other in the animation control code. Each one has noticeably less complexity than the overall problem.

 

The above example may not work well as substitute in your exact real project, but it should just show a way of how to approach such a problem in principle. Hopefully it helps :)




#5244605 Resource management questions

Posted by on 05 August 2015 - 02:05 AM

1. Obviously each resource is loaded separately and works differently, so I'm not sure if I have to create a generic cache class for all of them. I'm talking about something like this:

  Cache _soundCache;Cache _meshCache;Cache _textureCache;

Also some people say I should have a "ResourceLoader" class that manages loading from disk. The thing is that some resources like meshes and images are loaded from disk with a different library. For PNG images for example I use libpng, which manages loading .png images by itself. How am I supposed to encapsulate this inside a ResourceLoader class?

In a more sophisticated solution (for a game runtime, not for an editor) resources would not be loaded using generic file formats but by using a format that is more suitable for game runtimes (what means basically that it does not enforce recoding of the data, and even reduce interpretation at this level to a minimum).

 

If you don't have such a file format but several ones then you should also think about several loaders. Lordadmiral Drake has shown this in the pseudocode above. 

 

2. My second and more important question should be pretty simple but I find it very hard to answer.
Say I have this final GameEngine class. Where do I to put all the resource caches? Do they need to be private data members in GameEngine?
If the answer is yes, then obviously a Mesh resource will need a pointer to the Texture cache, because it loads textures. That means I have to pass pointers through classes all day long.
What options do I have here? What's the most viable approach?

IMHO: The approach you describe here does not separate the concerns enough. This probably is the reason of your problem.

 

A mesh resource should not load textures because its purpose is to define a shape. A mesh should not even load itself. A mesh should not even name textures so that a loader can load it. Instead, a (say) model resource should be available that serves as a declaration of which components the model need to be useable (like a bill of materials). When the model is about to be instantiated in the world, the scene management requests it from the content management. The content management requests all listed resources from the resource management. Any addressed resource manager then requests its associated cache and eventually instructs its associated resource loader(s) to load the resource data. The content management returns the instance for the model as soon as all resources (that are marked as mandatory) are available (or, if supported, at least surrogates are available).

 

So, when the game loop runs, it periodically enters a phase where the scene is managed w.r.t. the living instances. Here (somewhere before input and AI control happens) spawning and removal is done. Part of spawning is to make a new instance for the model, and hence requesting all belonging resources. This is the place where the content manager need to be accessed. The content manager hides the fact that each kind of resource has its own resource manager. Further, the resource managers hides the fact whether / how caching and loading are done.

 

BTW: I use the term "manager" with the meaning of a front-end that decides and delegates the actual tasks to attached helper objects. Well, that's the way managers work, isn't it? ;)




#5244600 Curved and sloped 3D tiles

Posted by on 05 August 2015 - 01:11 AM

Tiles need not be flat, also not at its perimeter. Make sure that neighbored tiles have the same kind of edge at the common seam, i.e. they use the same sequence of intermediate vertex positions. If you do this in the manner of module assembly you still have a limited set of shapes what probably makes the level design easier.

 

Some details to be considered are:

 

* There need to be a height information for every point where a dynamic game entity can be placed.

* In dependence on the camera height and pitch as well as the modeled slope, depth test and/or backface culling may be needed.

* The camera height need to be adjusted if the player character impends to leave the upper display edge.

* The simple top-down texture mapping looks ugly if the slope gets stronger due to texel stretching. You may support extra texture tile sizes.




#5244504 Collectable Items, Persistence and ECS Architectures

Posted by on 04 August 2015 - 09:17 AM


Is this is a sensible approach? Is this something that should sit outside of the ECS? [...]

IMHO your approach is fine because it allows the level designer to deal with the problem in a consistent way (assuming that s/he is familiar with ECS, of course ;) ) and it seems to fit smoothly into the technical point of view, too.

 

The only issue I personally would have with that particular solution is that the term "persistence" is broader. I.e. if I would hit a Persistence component I would understand it as a (perhaps even) collection of attributes that persist a room switch. It seems not clear why "persistence" 

 


[...]How have other people tackled this problem?

Well, I do not have this exact problem because in my engine the overall state is persistent anyway. So it includes the persistence but without the need of an explicit Persistence component. A spawn point that is never disabled and triggered on a "entering room" signal then will spawn each time, and one that is disabled does not.




#5244457 Normal map, height map, bump map... are all the same thing?

Posted by on 04 August 2015 - 03:04 AM

Most things are already mentioned in the posts above. Well, I think there need perhaps to be a little more accentuation on the difference of a map as a parametrization and the mapping as the applied technique.

 

A height map is an array of pixels with a single channel (hence it appears as grayscale image), where each of the pixels denote an elevation height w.r.t. a reference surface. It can be used with the bump mapping technique (and hence the map itself is also called a bump map) to simulate bumps and wrinkles on a surface without changing the geometry of the surface, not even temporarily. It can also be used for the displacement mapping technique where geometry is actually changed. Because a height map has only one channel, the displacement is restricted (usually along the normal of the surface onto which the mapping is applied). When applied to terrain (originally a flat horizontal surface), the bump map is sometimes also called an elevation map.

 

A full displacement map can be used, too, so that 3 channels are available, e.g. one for each of the directions normal, tangent, and bi-tangent to the surface.

 

A normal map is a map similar to a full displacement map, but instead of an displacement offset there is just a direction stored in the 3 channels. It cannot be used for displacement, because it lacks a distance. It can. however, be used to simulate surface bumps and wrinkles with the normal mapping technique. In fact, when doing bump mapping you need to compute the normal distortion from the gradient of the bump map pixels, and hence more or less convert the bump map into a normal map on the fly.




#5244247 OpenGL- Render to texture- a specific area of screen

Posted by on 03 August 2015 - 01:24 AM


does i still have to work with projection matrix?

Yes, you still have to do a projection. In this concern an FBO is not different from the default framebuffer. Moreover, you also need to find the suitable view matrix.

 


can you give me some trick how to do so and which way should i follow exactly?

As already mentioned, you need the full MVP matrix. You can take the situation as an own scene, i.e. the sheet of paper is the only object in the world. That allows to set the camera to a standard position and orientation and to place the object somewhat in front of i onto the z axist. As a result both M and V are easy to build, where V is just the identity matrix or perhaps just some scaling.

 

Regarding P you need to know the left, right, top, bottom, near and far planes of the view volume, all this in view space (which is, if following the above, the same as the world space perhaps with the exception of scaling). Now you can build P by either setting element by element (see e.g. here for details), or use one of the usual glm or OpenGL / GLU routines. 

 

Its not clear to me how far you have progressed, and which kind of projection you use. In which co-ordinate system have you calculated the red borders?

 


im sorry for my Novice questions.

There is nothing that need to be excused here :) 




#5244157 Simple inheritance

Posted by on 02 August 2015 - 09:34 AM

what shouldn't be happening?
he said, " It only sees the implementation if I include the .cpp file of the class A" that had the definition. No surprise there.

The reported linker errors shouldn't happen, and including an implementation file from an implementation file should not be done in general. It hints at a wrong project set-up. Either the sense of partial project compilation is lost, or else (legitimate) linker errors occur as soon as the base class is inherited from more than 1 derived class.

 

probably looking for something like this.
B myB;
myB.A::foo();

Although this is a valid invocation, doing like so is (a) not necessary for the given problem situation, and (b) hides a potential problem. Such invocation states explicitly that A::foo should be invoked even in the case that B::foo exists! That implies that the client has a deep understanding of the inner working of the class hierarchy; woe betide anyone who does this invocation without good reason. The situation that B does not override A::foo is definitely not a good reason alone. So mentioning this kind of "solution" should be done with the respective warning what actually happens.

 


and btw, when you implement a derived virtual, it doesn't 'overwrite' the base implementation. It will still be there.

With respect to the C++11 keyword, an allowed term would be "overriding".




#5243895 Hierarchy of meshes and entities

Posted by on 31 July 2015 - 03:02 PM

I'm not particularly familiar with Ogre, so I'm not necessarily a good reference here. To be honest, looking at the interfaces of Ogre::Entity and Ogre::Mesh, for example, does not make me happy from an architectural point of view.

 


I guess that Entity holds its own hierarchy of nodes and sub-meshes attached to them [...]

Perhaps, but it may be different. Normally a sub-mesh is defined as a separate set of vertexes for which another material is used, so this leads to another draw call. A weapon, on the other hand, is an own entity: It may be held in a hand but also dropped down onto the floor. This is different from a sub-mesh.




#5243793 OpenGL- Render to texture- a specific area of screen

Posted by on 31 July 2015 - 08:03 AM

You have to set the projection and view matrices so that "your camera sees what you want to render" into the texture. You have to use glViewPort and perhaps glScissor to which area of the texture rendering goes. 




#5243792 Hierarchy of meshes and entities

Posted by on 31 July 2015 - 07:57 AM


Why does it matter? I thought it will be more easy for the "engine user" to refer and work with just names and not indices.

It matters because string comparison costs around an order of magnitude more performance. If you want strings at runtime, then you can compute the hash of the string once and hand over both the string and the hash value for example in a "Name" structure.

 

BTW: Hashes are not indices.

 


It is recursive. Here's are the implementations:

It is not a mistake or so, but it tastes curious that "findSceneNode" checks the own node's name. Personally I'd let the routine test only child nodes and that directly.

 


Also what are node paths and why would I need them?

Each node need to be uniquely addressable. Because your search is recursive you need names not only unique within the couple of direct child nodes but over the entire scene graph. One possibility is to mimic what hierarchical file-systems do: Using a path like "/root/child_at_1st_level/child_at_2nd_level/my_node_of_interest". That would be a node path, because it addresses the node of interest using the names of the parents instead of constructing a name like "my_node_of_interest_with_a_super_long_and_hence_hopefully_unique_name". Notice that especially naming sub-nodes would be close to impossible as soon as several instances of a model are set into the scene if not using a path like scheme.

 


[...]The logic behind having more than one mesh attached to a SceneNode is for attaching swords to hands, MAGs to tanks etc., so when the hand rotates so will the sword.[...]

That would not be possible. Such things need to be child nodes because they need their own transform (local-to-parent transform) which is definitely part of the node but not the mesh.

 


Why would I care about adding order of child nodes?

As said: Its okay the way you do it as long as you do not need an order. I just wanted to hint at that.

 


Where else can I load the data from storage?

The resource management should have a loader object for this kind of thing.

 


I actually have Caches of materials inside Mesh. Like Cache etc.

Well, if your mesh class is actually a model then it is probably okay besides that another name should be chosen. (An actual mesh should not need to know about materials.)




#5243342 From openGL to various 3D format

Posted by on 29 July 2015 - 02:53 AM


1)in my code i'm using some Glut built-in methods and function to create object such as glutSolidTeapot() , glutSolidCube() etc .. I would like to know if i can "export" them to one of the formats named up above. If not , should i build my own functions to display them , so i can have the vertices position and save them in the files.

I do not know a way to ask the models from OpenGL besides interception. You can download a GLUT source code from internet, e.g. here, and extract the mesh data (consiering any copyright, of course).

 

But I also do not see what this should be good for. Generating a cube is easy, and the teapot (like any hundreds of other meshes) can be loaded from the internet (e.g. here as OBJ).

 


2)i'm already done with the obj parsing , but i have no clue on how the PLY and VRML files behave , i could use a little help here please , thanks !

The specifications can be found on the internet, e.g. here for PLY. What exactly do you want to know?

 

However: I'm surprised of your intent.

a) Does PLY really play a role nowadays?

b) VRML is superseded by X3D. Besides that … VRML / X3D is a beast! 

c) OBJ and PLY are both supported by AssImp for both import and export.






PARTNERS