Jump to content

  • Log In with Google      Sign In   
  • Create Account


Game Design Questions (low level-ish)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
19 replies to this topic

#1 Jossos   Members   -  Reputation: 207

Like
0Likes
Like

Posted 02 April 2013 - 01:23 AM

I'm not sure if this is really a beginner topic or not, but since I'm not really experienced, I thought I'd post in beginners section just to be safe from ridicule.

 

I'm writing some practice applications and am having a blast. I'm wanting to build some neat game-apps (mostly just experimenting right now) and I do want to get some good game design in whatever I do. These are questions I have, and any answers would be great!

 

Question 1: Animation

Is it possible to export animations from 3ds Max? Also, how would this work? I've messed around with .obj files, and I can load in an object with textures into my application, but I am unsure how to do animation. Do I need some kind of bone system - or perhaps a bunch of .obj's with difference vertex positions for each frame? I prefer the vertex positions per frame, as the bone stuff seems like it might make the computer do a little more math than I'd like it to.

 

Question 2: Data Structure(s)

I'd like to make a RTS, which means I need a lot of "Units" (I'd likely make unit objects) and I'd like a lot of these, hundreds, maybe thousands. As you can tell, I have no grasp on what's feasible here, in terms of how it's usually done in games, so I'd like to know if I'm way off, or if there's a special way to do it.

In all honesty, I plan to have all units contained in a <vector> and loop through each one, progressing its state forward a frame (like walking, or attacking)

 

Question 3: Visual Studio - DLL's and .libs

I'm quite use to having a bunch of .h and .cpp files all in a project, and compiling the whole thing into an exe (with .obj's and png's in the same directory). Should I have bunches of my code put into a seperate file and export as DLL? I haven't done this before, so is there anything I need to know about this? (I think exporting a dll is pretty easy, just have to change a setting)

 

Question 4: Input to Logic

- Solved

 

Question 5: Mouse/screen coords to the 3d world

- Solved

 

 

Question 6: Mouse/screen projection is off

So I got the program to cast a ray from the mouse into the 3d world - However it's off by a few pixels, and this seems to occur in the actual 3d world.

 

The cyan-Hlighlighted square should be directly underneath the mouse.

 

Below I have drawn the mouse position into this screen capture of my program (because printscr doesnt copy the cursor)

 

myappnotworking.jpg

 

As you can see it's off by a fair margain, but it's pretty damn close. I mean, I can use this program and it's quite nice, but the offset doesn't make any sense.

 

Here's the code to convert mouse coords into 3d world coords

vector3d GetOGLPos(int x, int y, float z)
{
GLint viewport[4]; // contains x, y, width and height
GLdouble modelview[16]; // modelview matrix information
GLdouble projection[16]; // projection matrix information


glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);


GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;


winX = (GLdouble)x;
winY = (GLdouble)viewport[3] - (GLdouble)y;
winZ = (GLdouble)z;


    gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);


    return vector3d(posX, posY, posZ);
}

 

 

it's used like so:

 

// mousePosNear and mousePosFar are of type "vector3d"

mousePosNear = GetOGLPos(m_mouseX, m_mouseY, 0.0);
mousePosFar = GetOGLPos(m_mouseX, m_mouseY, 1.0);

 

I'm not sure if I should provide other details, such as the rayplane function that these values are used in. Let me know if you want that code aswell to help solve this

 

Question 7: Deciding what tiles to draw

 

Actually this problem seems like it should be relatively easier Since I already have the rayplane function done, but I can't figure out how to do this in 3d (the 3d math just does my head in)

 

I figured It would be something like casting a ray from each corner of the screen and getting the returned tile... and then I don't know what to do from there.


Edited by Jossos, 05 April 2013 - 04:28 AM.


Sponsor:

#2 Ashaman73   Crossbones+   -  Reputation: 7235

Like
0Likes
Like

Posted 02 April 2013 - 03:24 AM

Question 1: Animation

Is it possible to export animations from 3ds Max? Also, how would this work? I've messed around with .obj files, and I can load in an object with textures into my application, but I am unsure how to do animation. Do I need some kind of bone system - or perhaps a bunch of .obj's with difference vertex positions for each frame? I prefer the vertex positions per frame, as the bone stuff seems like it might make the computer do a little more math than I'd like it to.

.obj files are really easy representation laking animation and more advanced topics. Either use collada or FBX as export format and take a look at libraries such like assimp to get the files into your game.

 

Vertex blending/animation is only useful for a very limited area of animation (most often facial expressions), so there's not really a way to avoid skeletal animation system when doing animations in 3d.

 

Question 2: Data Structure(s)

I'd like to make a RTS, which means I need a lot of "Units" (I'd likely make unit objects) and I'd like a lot of these, hundreds, maybe thousands. As you can tell, I have no grasp on what's feasible here, in terms of how it's usually done in games, so I'd like to know if I'm way off, or if there's a special way to do it.

In all honesty, I plan to have all units contained in a and loop through each one, progressing its state forward a frame (like walking, or attacking)

That's a good way to start, but eventually you need to utilize other data structures which will be more suitable for special cases (e.g. sweep'n'prune for physics, oct-tree for rendering etc.). If you are a beginner, start small and don't target too high (e.g. start with 20 units instead of 20k). You will be surprised at how powerful modern computers are, so if you don't have too much experiences, start, make errors and learn from them, this is a very important process.



#3 Jossos   Members   -  Reputation: 207

Like
0Likes
Like

Posted 02 April 2013 - 04:34 AM

so there's not really a way to avoid skeletal animation system when doing animations in 3d.

 

I was thinking maybe I could do all the animation inside 3ds max with bones and ik's etc, and then just export the end result (vertex positions) of each frame. I don't know if this is possible, but I don't see why not.


Edited by Jossos, 02 April 2013 - 04:35 AM.


#4 Juliean   GDNet+   -  Reputation: 2454

Like
0Likes
Like

Posted 02 April 2013 - 06:58 AM

I was thinking maybe I could do all the animation inside 3ds max with bones and ik's etc, and then just export the end result (vertex positions) of each frame. I don't know if this is possible, but I don't see why not.

 

There is a number of reasons. If you have a look at how big a high (and even low) poly model file can get, you'll see why. For a 10 second animation â 60 frames it would take an enormous amount of memory. Not talking about loading time - you would have to load the whole model for every step of the animation, which eigther takes up gigs of ram for each model or requires loading data from the disk every frame, which is a very bad thing to have and will make your game virtually unplayable.

 

Next thing, you want smooth interpolation based on the target PCs frame rate - if you'd e.g really export a 10 second character animation the way you wanted to do, just think about how you would (not be able to) handle animation on one PC that runs the game at 500 FPS and another one that only has 15 FPS. Skeletal animation takes (almost) automatically care of this, while with your approach this would be nearly impossible/even harder to achieve than just implementing SA.

 

If thats not enough, think about if you have a standard walk animation and then want your character to turn his head on one occassion. SA you can blend different animations. but with the way you suggested, you'd have to dublicate the walk animation with his head turned exactly at the right moment - stepping back to the memory workload I talked about earlier, I suppose you plan on shipping your game on a 1 TB HDD? ;)

 

Short answer - no, this is not at all possible, even if modeling software would support it (which it, fortunately, in my knowledge doesn't).



#5 Ashaman73   Crossbones+   -  Reputation: 7235

Like
0Likes
Like

Posted 02 April 2013 - 07:01 AM

I was thinking maybe I could do all the animation inside 3ds max with bones and ik's etc, and then just export the end result (vertex positions) of each frame.

It is often a performance/memory issue. Take a 3k character with 1000 animation frames and 100 bones.

 

1. bone version:

100 bones * 1000 frames = 100 * (1x quaternion + 1x position) * 1000 = 100k * (7 floats) = 100k * 28 bytes = 2.8m bytes

 

2. vertex version

3000 vertices * 1000 frames = 3000 * (1x position) * 1000 = 3000k * 12 bytes = 36m bytes

 

Factor ~12x

 

Besides the memory consumption, which scales really badly with the number of vertices (current gen main characters often have more then 10k vertices), you would need to upload the modified vertices to the GPU each frame (slower then just uploading 100 bones) or you would need to store all the vertices on the GPU.

 

This should only be an option if you target really low-poly, low animation models (like the minecraft creeps).


Edited by Ashaman73, 02 April 2013 - 07:04 AM.


#6 Kristoffer   Crossbones+   -  Reputation: 839

Like
0Likes
Like

Posted 02 April 2013 - 07:27 AM

Question 2

 

Just use a vector and you should be fine, one really simple trick in your case then is to flag destroyed objects as killed

instead of removing them from the vector and then replace them when you create new ones instead of adding to the end

 

Question 3

 

Making use of DLL is not as easy as just changing the project options because you must make export functions and create interfaces if you want to use

classes for example

 

Just keep everything in one project until you get a better idea of how you can separate the things in your game

One project is gets you really far anyway just harder to make use of what you did in future projects but do not think too much about that.


Blekinge Institute of Technology
Twitter @devmoon
Homepage http://devmoon.se
Stream http://twitch.tv/devmoon

#7 Norman Barrows   Crossbones+   -  Reputation: 2058

Like
0Likes
Like

Posted 02 April 2013 - 12:44 PM

Question 2: Data Structure(s)
I'd like to make a RTS, which means I need a lot of "Units" (I'd likely make unit objects) and I'd like a lot of these, hundreds, maybe thousands. As you can tell, I have no grasp on what's feasible here, in terms of how it's usually done in games, so I'd like to know if I'm way off, or if there's a special way to do it.
 
this question should be answered first,  as the answer affects the answers to the other questions.
 
what's feasible?    Total War titles routinely have 4000 units in combat at once, all on the screen at once.
 
no special trick, they just don't spend a lot of clock cycles drawing individual units.
 
I would probably use a target list of some sort (IE a database), with an active field in each record. this serves the same purpose as a "killed" flag in a vector.
 
special data structures could be used as needed for sweep & prune, octree drawing, etc, if required.
 
i would probably implement it as a flat file database: a static array of structs, or an array allocated on the heap at program start. this eliminates all malloc, free, new, and dispose type overhead, as well as the possibility of memory leaks, null pointers, etc. It also eliminates the overhead of traversing trees and linked lists, and/or chasing object pointers. IE keep it simple as possible. simple = fast. if you eventually want to do lots of units, you'll want fast.
 
 
 
 

Question 1: Animation
Is it possible to export animations from 3ds Max? Also, how would this work?
 
4 ways to go here (there may be more):
 
1. export skinned mesh and skeleton animation from 3dsmax to some format and then into your game and use it. here i'm talking about 3rd party tools and custom code. apparently a number of developers do this, as they are dissatisfied with the build-in animation capabilities of their graphics library (directx).
 
2. export to .x format, and use directx routines to load and draw, as per the directx skinned mesh demo and tutorials found online. if you want a list of the skinned mesh tutorials, i just found them yesterday.
 
3. slice unit models into separate limb meshes and use a limb animation system. this will let you draw more units at the same level of detail, with the downside of no blended seams between limb meshes. careful modeling of limbs can minimize this. if you want lots of units, and you never see them really close up, this may be a good option. In my experience, a limb system is typically 7 times faster than a skinned mesh system.   so if you can draw 100 units at a decent frame rate using skinned meshes, you can draw about 800 limb based models at about the same frame rate.
 
4. render 3d models (including animation frames) to sprites, and draw units using sprites. this is the absolute fastest method. the downside is you only have a finite number of viewing angles in your sprite sets. but the renders can be arbitrarily complex.
 
in cases 1, 2, and 3, we're talking VERY low poly models. When Total war switched from sprites to 3d models, each unit has something like 50 to 100 triangles each.  how many triangles per unit you can do will be a function of the total number of units, skinned mesh vs limb system, the speed of your code, how much other stuff you draw, and how much simulation your game does.
 

Should I have bunches of my code put into a separate file and export as DLL?
 
DLLs are primarily intended for code sharing. they can also be used as a means of code reuse and easy updates in the field. its unlikely you'll have 2 copies of the game running at once, so no code sharing. you only have one project so far, so no need for reuse.  and you're not about to release, so no concerns about easy updates in the field.  so DLLs are an unnecessary complication at this stage.
 
code reuse can also be gotten in easier ways, if you don't need update in the field capability.  perfect example, i sliced the built-in modeler and animation editor in my main project into its own .cpp and .h file. now i link it into all my titles and have a built-in modeler and animation editor in each of them.
 
as for easy updates in the field, you're talking about downloading and installing a zipped DLL vs a zipped EXE. not much of a difference there.
 
DLLs seem to be one of those things that everyone thinks they need when they don't really understand their intended purpose, which is to save ram when 2  apps use the same chunk of code.  instead of linking the same code (such as msvb runtime) into two apps, and having two copies of that code in memory at once when both apps happen to be running at the same time, they both use the same DLL in ram. as a game, odds are only things like MSVB runtime will be good candidates for DLLs in your app. and there, if you statically link, it loads faster, and its one less file to deal with on the user's PC (can't get erased, corrupted, overwritten due to name collision, etc). the cost is the additional ram footprint of the DLL in question. but again, you're a game, not a regular app, so odds are you'll be the only open app most or all of the time, so again, not much opportunity for code sharing.
 
many things in the computing world (like DLLS) seem neat and make sense - except for games, due to the unique nature and requirements of games vs apps.
 
 
 
 

Question 4: Input to Logic
I'd like to have all of my logic and graphics separate from Input. How should I do this?
 
your example looks just fine.
 
for input, you'll be checking the state of keys, buttons, mouse position, etc.
 
"separate" can mean a couple things here.
 
1. i check input in one place, and  act on it in another place.
2. keyboard / mouse button bindings.
 
case 1:  i check input in one place, and  act on it in another place.   i've never been able to see a clear advantage to this.     it requires you to store the results of your input checks for later use.    unless the checks are slow, its usually easier to simply perform them as needed when needed, and get and process input all at once.
 
case 2: keyboard / mouse button bindings.   you have a lookup table that assigns keys (such as W) to actions (such as move forward).  when you need to process input, instead of checking for "W", you check for "key assigned to move_forward".

Edited by Norman Barrows, 02 April 2013 - 12:48 PM.

Norm Barrows

Rockland Software Productions

"Building PC games since 1988"

 

rocklandsoftware.net

 


#8 Ludus   Members   -  Reputation: 970

Like
0Likes
Like

Posted 03 April 2013 - 12:56 AM

Just as a small observation, what you're calling "logic.cpp" is in fact the input portion of your program. This would run in the input function of your game loop, while logic is a separate function of the game loop that would run after the input.



#9 cardinal   Members   -  Reputation: 866

Like
0Likes
Like

Posted 03 April 2013 - 01:36 AM

If thats not enough, think about if you have a standard walk animation and then want your character to turn his head on one occassion. SA you can blend different animations. but with the way you suggested, you'd have to dublicate the walk animation with his head turned exactly at the right moment - stepping back to the memory workload I talked about earlier, I suppose you plan on shipping your game on a 1 TB HDD? ;)
 
Short answer - no, this is not at all possible, even if modeling software would support it (which it, fortunately, in my knowledge doesn't).

While I agree that skeletal animation is the best way to go about this (and all your reasons why are valid), interpolating between keyframes of the model was a common way of doing 3D animations in the early days of 3D. In these days the poly count and number of animations was minuscule compared to today's standards so the memory problems could be worked around.

Some games even animated different body parts separately and stitched the models together (to enable combining animations such as looking a different direction while walking). I believe I read somewhere that the first Tomb Raider did this. One of the problems with this method though is that it creates seams in the model that were sometimes visible depending on the situation (while not specifically mentioned I would imagine that clothing would be used to hide the seams as best as possible.

#10 Juliean   GDNet+   -  Reputation: 2454

Like
0Likes
Like

Posted 03 April 2013 - 04:03 AM

While I agree that skeletal animation is the best way to go about this (and all your reasons why are valid), interpolating between keyframes of the model was a common way of doing 3D animations in the early days of 3D. In these days the poly count and number of animations was minuscule compared to today's standards so the memory problems could be worked around.

 

Interesing to know, I though keyframe interpolation was only used for e.g. technical mechanisms etc...

 

 

Question 5: Mouse/screen coords to the 3d world

So I've kinda done some of the harder work already. Here is my application so far:

myprog.jpg



A ray is cast from the camera in whatever direction it's pointing and highlights whatever tile it hits. In a way, you could imagine that the mouse pointer is always in the centre of the screen.



How would I add to this code to instead have the mouse highlight the tiles(as in, wherever the mouse is on screen, translate that into the 3d world). I can already get the mouse coords on the screen using an SDL function, just need to know the math.

-Also, if I've not provided sufficent information for this problem (like if you want to see my rayplane function) please let me know. I'm not sure what information is relevant here.



Some Info:



class smCamera
{
private:
vector3d loc;
float camPitch, camYaw;



the vector3d loc is just the camera location. It has floats x, y and z



camPitch is the up and down rotation, and camYaw is the left and right rotation. These are applied graphically like so:



glTranslatef(0.0, 0.0, -(player->cam->getCamY())); // Distance up from the ground
glRotatef(player->cam->getPitch(), 1.0, 0.0, 0.0); // I have this set at -45 to look down
glRotatef(-(player->cam->getYaw()), 0.0, 1.0, 0.0); // I increase this with the shift keys
glTranslatef(-(player->cam->getCamX()), 0.0, -(player->cam->getCamZ())); // translate the world

Help is greatly appreciated!

 

You need to unproject your mouse position. I can't tell you how it exactly works with OpenGL, but I can give you some DirectX-code with a little explanation, you should be able to figure out the rest yourself:

 

	//todo: access camera differently
	const Camera* pCamera = m_pGfx3D->GetCamera();

	//todo: access cursor differently
	Vector2 mousePos = Input::GetMousePos();
        //translate mouse coordinates to scene area
	mousePos.x -= m_pArea->GetX();
	mousePos.y -= m_pArea->GetY();
	D3DXVECTOR3 vMouse((float)mousePos.x, (float)mousePos.y, 0.0f);
	D3DXVECTOR3 vMouse2((float)mousePos.x, (float)mousePos.y, 1.0f);
	const D3DVIEWPORT9& ViewPort(m_pGfx3D->GetViewport());

	D3DXMATRIX mWorld;
	D3DXMatrixIdentity(&mWorld);

	D3DXVECTOR3 vP1, vP2;
	D3DXVec3Unproject(&vP1, &vMouse, &ViewPort, &pCamera->GetProjectionMatrix(), &pCamera->GetViewMatrix(), &mWorld); 

	D3DXVec3Unproject(&vP2, &vMouse2, &ViewPort, &pCamera->GetProjectionMatrix(), &pCamera->GetViewMatrix(), &mWorld); 

	D3DXVECTOR3 vDist = vP2;
	vDist -= vP1;
	D3DXVec3Normalize(&vDist, &vDist);

	const Ray mouseRay(vP1, vDist);

You basically create two points from the mouse, one on the near and one on the far clip plane. Now given the view matrix, projection matrix, viewport and (most likely identity) world matrix you can unproject these two points to their location in the world. You then construct your ray from these two points an voîla, you're done.


Edited by The King2, 03 April 2013 - 04:03 AM.


#11 Jossos   Members   -  Reputation: 207

Like
0Likes
Like

Posted 03 April 2013 - 04:31 AM

You need to unproject your mouse position. I can't tell you how it exactly works with OpenGL, but I can give you some DirectX-code with a little explanation, you should be able to figure out the rest yourself:

 

	//todo: access camera differently
	const Camera* pCamera = m_pGfx3D->GetCamera();

	//todo: access cursor differently
	Vector2 mousePos = Input::GetMousePos();
        //translate mouse coordinates to scene area
	mousePos.x -= m_pArea->GetX();
	mousePos.y -= m_pArea->GetY();
	D3DXVECTOR3 vMouse((float)mousePos.x, (float)mousePos.y, 0.0f);
	D3DXVECTOR3 vMouse2((float)mousePos.x, (float)mousePos.y, 1.0f);
	const D3DVIEWPORT9& ViewPort(m_pGfx3D->GetViewport());

	D3DXMATRIX mWorld;
	D3DXMatrixIdentity(&mWorld);

	D3DXVECTOR3 vP1, vP2;
	D3DXVec3Unproject(&vP1, &vMouse, &ViewPort, &pCamera->GetProjectionMatrix(), &pCamera->GetViewMatrix(), &mWorld); 

	D3DXVec3Unproject(&vP2, &vMouse2, &ViewPort, &pCamera->GetProjectionMatrix(), &pCamera->GetViewMatrix(), &mWorld); 

	D3DXVECTOR3 vDist = vP2;
	vDist -= vP1;
	D3DXVec3Normalize(&vDist, &vDist);

	const Ray mouseRay(vP1, vDist);

You basically create two points from the mouse, one on the near and one on the far clip plane. Now given the view matrix, projection matrix, viewport and (most likely identity) world matrix you can unproject these two points to their location in the world. You then construct your ray from these two points an voîla, you're done.

 

I used some of what you said, did a heap of research... and Now it works ^^ -  thanks - except the mouse seems to be like 8 pixels off... idk. It works for the most part, so I will probably leave it for now, and start building this program up with other features.

 

Just as a small observation, what you're calling "logic.cpp" is in fact the input portion of your program. This would run in the input function of your game loop, while logic is a separate function of the game loop that would run after the input.

 

Alright, So I'll just make a "handle_input" function in my main file then. I'm just worried that it's gonna be huge.

 

 

 

Also to the Animation stuff - seems like bones are the way to go, which means I'll just use static models to start off with lol.

 

I'm sure I'm way outta my league here - but how feasible is it to make your own modelling program? I mean, I already got the camera and mouse stuff sorted. Just need modelling tools... Animation tools... bone tools, ik tools, texturing tools. Not sure how big of a thing this would be. I'm not talking 3ds or blender, just something for models, and a bit of animation.



#12 Juliean   GDNet+   -  Reputation: 2454

Like
0Likes
Like

Posted 03 April 2013 - 04:39 AM

I used some of what you said, did a heap of research... and Now it works ^^ - thanks - except the mouse seems to be like 8 pixels off... idk. It works for the most part, so I will probably leave it for now, and start building this program up with other features.

 

Did you account for the window borders? Thats why I sub'd the m_pArea-coordinates, this is my gui element containing the scene view. Don't know if SDL converts the mouse position correctly, you might want to output the coordinates and make a screenshot to see if they are off, or if the problem is with the unprojecting.



#13 Jossos   Members   -  Reputation: 207

Like
0Likes
Like

Posted 03 April 2013 - 05:27 AM

Did you account for the window borders? Thats why I sub'd the m_pArea-coordinates, this is my gui element containing the scene view. Don't know if SDL converts the mouse position correctly, you might want to output the coordinates and make a screenshot to see if they are off, or if the problem is with the unprojecting.

 

No, the coordinates are exactly in the window. I can get to 0,0, and 799, 449 (window is 800 x 450). Very strange - Actually, it seems to be a problem in the actual 3D world. If i Rotate the camera, the offset might be to the left, but If i rotate it all the way around, it's to the right


Edited by Jossos, 03 April 2013 - 05:30 AM.


#14 Juliean   GDNet+   -  Reputation: 2454

Like
0Likes
Like

Posted 03 April 2013 - 07:26 AM

No, the coordinates are exactly in the window. I can get to 0,0, and 799, 449 (window is 800 x 450). Very strange - Actually, it seems to be a problem in the actual 3D world. If i Rotate the camera, the offset might be to the left, but If i rotate it all the way around, it's to the right

 

Can you post the code responsible for unprojecting so I might take a look at that first?



#15 Ludus   Members   -  Reputation: 970

Like
0Likes
Like

Posted 03 April 2013 - 11:13 AM

Alright, So I'll just make a "handle_input" function in my main file then. I'm just worried that it's gonna be huge.

 

It's possible to spread the function definitions of a single class over multiple source files. I recommend having a separate source file that contains only the definition of the "handle_input" function.



#16 Jossos   Members   -  Reputation: 207

Like
0Likes
Like

Posted 03 April 2013 - 10:03 PM

It's possible to spread the function definitions of a single class over multiple source files. I recommend having a separate source file that contains only the definition of the "handle_input" function.

 

How did I not know this? lol thanks a lot!

 

Can you post the code responsible for unprojecting so I might take a look at that first?

 

 

sure can:
vector3d GetOGLPos(int x, int y, float z)
{
GLint viewport[4]; // contains x, y, width and height
GLdouble modelview[16]; // modelview matrix information
GLdouble projection[16]; // projection matrix information


glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);


GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;


winX = (GLdouble)x;
winY = (GLdouble)viewport[3] - (GLdouble)y;
winZ = (GLdouble)z;


    gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);


    return vector3d(posX, posY, posZ);
}
 

 

And I use this like so:

 

// mousePosNear and mousePosFar are of type "vector3d"

mousePosNear = GetOGLPos(m_mouseX, m_mouseY, 0.0);
mousePosFar = GetOGLPos(m_mouseX, m_mouseY, 1.0);

 

And these are used in the rayplane function. Want to see that too?



#17 BeerNutts   Crossbones+   -  Reputation: 2860

Like
0Likes
Like

Posted 04 April 2013 - 08:29 AM

Question 4: Input to Logic
I'd like to have all of my logic and graphics seperate from Input. How should I do this?

 
Another solution could be to have entities or components register for certain key presses with the Input System.  In this manner, only the parts of the game that need to know about some key preses gets notified.
 
For instance, your player would need to know all movement key presses, but your weapon class may be interested in the weapon keys (fire, and alt fire for instance), while your Menu system wants Esc, and when the Menu is activated, it would then maybe tell the Input system to not send any keys to the other systems (since your "fire" key may not be the "select" key in menu mode), and register for other keys it needs (and the opposite when leaving menu).
 
Maybe something like this:
 
 
// Interface to be called for registered key presses
class IKeyPressCallback
{
  virtual ~IKeyPressCallback() {}
  virtual void OnKeyPress(TGameKey keyPressed, bool isDown) = 0;
}
 
class TWeapon : public IKeyPressCallback
{
private:
  // stuff ...
  TInputSystem& InputSystem;
public:
  TWeapon(TInputSystem& inputSystem);
 
  void OnKeyPress(TGameKey keyPressed, bool isDown);
}
 
// In TWeapons.cpp
 
TWeapon::TWeapon(TInputSystem& inputSystem) :
  InputSystem(inputSystem)
{
  InputSystem.RegisterKey(FIRE_KEY, this);
  InputSystem.RegisterKey(ALT_FIRE_KEY, this);
}
 
void TWeapon::OnKeyPressed(TGameKey keyPressed, bool isDown)
{
  if (keyPressed == FIRE_KEY) {
    // Do firing stuff
  }
}

// in TInputSystem.h
class TInputSystem
{
private:
  struct TKeyPressData
  {
    IKeyPressCallback* KeyPressCallback;
    TGameKey GameKey;
  }
  std::vector<TKeyPressData> KeyPressCallbacks;

public:
  void RegisterKey(TGameKey gameKey, IKeyPressCallback* keyPressCallback);


My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

#18 Norman Barrows   Crossbones+   -  Reputation: 2058

Like
0Likes
Like

Posted 04 April 2013 - 09:47 AM

question 5:   pick test

 

here's the ray-plane pick test i cobbled together for a real time wargame i'm working on.

 

directx, but i think you'll be able to follow it.....

 

 

 

 
 
 
D3DXVECTOR3 intersect_point;
 
 
 
 
void calc_intersection(int x,int y)
{
char s[100];
D3DXVECTOR3 v,dir,origin,
            p1,p2,     // line
            p3,p4,p5;  // plane
D3DXMATRIX m;
D3DXPLANE p;
 
v.x =   ( ( ( 2.0f * x ) / screen_width  ) - 1 ) / Zprojection_matrix._11;      
v.y = - ( ( ( 2.0f * y ) / screen_height ) - 1 ) / Zprojection_matrix._22;
v.z = 1.0f;
 
// MICROSOFT COMMENTS: 
// Get the inverse view matrix
//const D3DXMATRIX matView = *g_Camera.GetViewMatrix();    // view matrix (camera orientation & location)
//const D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix();   // world matrix (orientation & location of the mesh - not used?) 
//D3DXMATRIX mWorldView = matWorld * ZmView;
//D3DXMatrixInverse( &m, NULL, &mWorldView );
D3DXMatrixInverse(&m,NULL,&ZmView);
// MICROSOFT COMMENTS: 
// Transform the screen space pick ray into 3D space
 
// ROCKLAND COMMENTS:
// actually - object space of the mesh, not world space. the view matrix alone gets you to world space. 
// adding the world matrix gets you object space.
// object space -> (world mat) -> world space -> (view mat) -> camera space -> (proj mat) -> screen space.
// MS uses the world mat because they're picking tri's off a single mesh
dir.x = v.x * m._11 + v.y * m._21 + v.z * m._31;
dir.y = v.x * m._12 + v.y * m._22 + v.z * m._32;
dir.z = v.x * m._13 + v.y * m._23 + v.z * m._33;
origin.x = m._41;
origin.y = m._42;
origin.z = m._43;
 
Znewmenu("Pick ray results:");
f2s(origin.x,s);
Zaddmenu(s);
f2s(origin.y,s);
Zaddmenu(s);
f2s(origin.z,s);
Zaddmenu(s);
f2s(dir.x,s);
Zaddmenu(s);
f2s(dir.y,s);
Zaddmenu(s);
f2s(dir.z,s);
Zaddmenu(s);
//menu();
 
 
// need intersect of line and plane
// need to convert ray to line
p1.x=origin.x;
p1.y=origin.y;
p1.z=origin.z;
p2.x=dir.x*1000.0f+origin.x;
p2.y=dir.y*1000.0f+origin.y;
p2.z=dir.z*1000.0f+origin.z;
// now we have a nice long line from p1 (origin) to p2 (dir)
// now we need a plane...
// calc 3 points on the plane, or a point and a normal.
// use them to create a plane data structure.
p3.x=0.0f;
p3.y=0.0f;
p3.z=0.0f;
p4.x=0.0f;
p4.y=0.0f;
p4.z=1.0f;
p5.x=1.0f;
p5.y=0.0f;
p5.z=0.0f;
 
D3DXPlaneFromPoints(&p,&p3,&p4,&p5);
 
// then test ray vs plane intersection.
 
D3DXPlaneIntersectLine( &intersect_point, &p, &p1, &p2);
 
Znewmenu("plane line intersect:");
if (intersect_point == NULL)
    {
    Zaddmenu("intersect_point = NULL");
    }
else
    {
    f2s(intersect_point.x,s);
    Zaddmenu(s);
    f2s(intersect_point.y,s);
    Zaddmenu(s);
    f2s(intersect_point.z,s);
    Zaddmenu(s);
    }
//menu();
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void draw_ground()
{
int x,z;
Zdrawinfo a;
ZeroMemory(&a,sizeof(Zdrawinfo));
a.sx=10.0f;
a.sy=10.0f;
a.sz=10.0f;
for (x=0; x<200; x+=10)
    for (z=0; z<200; z+=10)
        {
        a.x=(float)x;
        a.z=(float)z;
        Zdraw(&a);
        }
}
 
 
 
 
 
 
 
 
void picktest()
{
/*
while ! quit
    clearscreen
    drawmouse
    if leftclick
        calc ray - plane intersection
        show results
    else if esc - quit
*/
int quit,x,y,b;
Zdrawinfo a;
Zsetcam(10.0f,50.0f,-10.0f,1.0f,0.0f,0.0f);
Zsetlite(0,1.0f,-1.0f,1.0f,1.0f);
Zlite(0,1);
quit=0;
ZeroMemory(&a,sizeof(Zdrawinfo));
a.sx=1.0f;
a.sy=1.0f;
a.sz=1.0f;
a.texID=2;
a.y=0.1f;
intersect_point.x=0.0f;
intersect_point.y=0.0f;
intersect_point.z=0.0f;
while (! quit)
    {
    Zclearscreen(0,0,0);
    Zclearzbuf();
    Zbeginscene();
    Zcleardrawlist();
    draw_ground();
    a.x=intersect_point.x;
    a.z=intersect_point.z;
    Zdraw(&a);
    Ztext3d(0,0,"Press ESC to quit");
    Zdrawlist();                   
    Zbeginsprite();
    drawmouse();
    Zendsprite();
    Zshowscene();
    Zdomessages();
    Zgetmouse(&x,&y,&b);
    if (b==1)
        {
        calc_intersection(x,y);
        }
    else if (Zkeypressed(VK_ESCAPE)) 
        {
        quit=1;
        }
    }
}

Norm Barrows

Rockland Software Productions

"Building PC games since 1988"

 

rocklandsoftware.net

 


#19 mippy   Members   -  Reputation: 1002

Like
0Likes
Like

Posted 04 April 2013 - 03:22 PM

I would skip the whole "design units" part and focus on gameplay. Instead of sofisticated tanks and units I would use pyramids and squares and color these in nice cool ways. This way you can pump out hundreds of randomized custom units quickly. Think minecraft but RTS ;) 



#20 Jossos   Members   -  Reputation: 207

Like
0Likes
Like

Posted 04 April 2013 - 08:13 PM

I would skip the whole "design units" part and focus on gameplay. Instead of sofisticated tanks and units I would use pyramids and squares and color these in nice cool ways. This way you can pump out hundreds of randomized custom units quickly. Think minecraft but RTS ;) 

 

I like that idea. Cubes and pyramids it is!

 

And also, the mouse offset is actually really annoying. I posted my code above if anyone could please help.

I'll add this problem to the first post: 


Edited by Jossos, 04 April 2013 - 10:21 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS