A great game hit a bottomless pit

I like the idea of projecting bounding boxes into screen space.

Kilam’s suggestion sounds good.

  • Click the mouse

  • Use gluUnProject to project all the bounding boxes for objects in the frustrum into 2d space

  • Compare values.

Quick and easy!

. . No I don’t really totally understand that.

Here’s my interpretation and its problem:

I got my 2d points onscreen to compare to mouse pointer. Nice.
Problem is how big are the bounding boxes(fields that the ships occupy on 2d screen) so say I can tell if user’s clicking on fighter close or very very far away?

I need the Z coordinates-distance from viewer to these ships . . .

heh just solved my own problem, never mind me
use distance formulae to find distance between user and ship, also using ship
size value(say 1 for fighter, 10 for capital ship) to affect the size of bounding box . .

also remember I AM using gluUnProject and NeRomancer is going to help me with this

http://members.xoom.com/myBollux world builder press p then press h and drag the mouse over the screen is this what u want?. i just use the selection buffer

If the z value matters them I think that the best way to do this is with glRenderMode(GL_SELECT). In MSDN is explained pretty well all this. Next week I’ll try to find a solution and as soon as I’ll solve the problem I’ll post the code…
HAve a nice week-end because I have a friend that has just became a slave (he got married - and I have to go to his wedding).

NewROmancer

Originally posted by Schlogenburg:

I need the Z coordinates-distance from viewer to these ships . . .

Yeah, thats the first possibility I posted. You use gluUnProject on the x and y screencoordinates and the z-buffer value on this screen position (use glReadPixels). Then you get the x-y-z coordinates in your coordinate space.

Kilam.

As far as I understand, the selection buffer can solve some problems that might occur when using manual bouding box selection.

Imagine a scene, where you have a flying torus (doughnut) infront of you. Behind that torus, there is another object that you want to select. This object is visible through the hole of the torus. Now, if you are using bouding boxes, won’t you select the torus when clicking on the other object? If using selection buffer, this problem is solved, because you are clicking ON the other object, not WITHIN the bouding box of the torus.

Schlogenburg asked for the code, so here it is. Sorry guys, its DirectX (I know you all hate DirecX ), but I haven’t ported my modeler to OpenGL yet because I am also stuck on the selection problem.

THE CODE

type
TfrmMain = class(TForm)
protected
DraggingSelection: Boolean; // True if user is using mouse to drag or rotate selected object
DragCount: DWORD; // Number of times mouse has moved since drag started
LastMouseX, LastMouseY: Integer;

     procedure DragModelStart;
     procedure DragModelEnd;

end;

// D3DVALUE is a single-precision floating point
// D3DVECTOR is a record/structure of 3 D3DVALUES, one for each x, y, and z

procedure TfrmMain.DragModelStart;
begin
DraggingSelection := True;
DragCount := 0;
end;

procedure TfrmMain.DragModelEnd;
begin
DraggingSelection := False;
end;

// MouseDown code picks/selects model and if a model was picked it calls DragModelStart()

procedure TfrmMain.adxctlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
// For drag
DeltaX, DeltaY, DeltaR: Double;
Denom: Double;

  Rotation: D3DVECTOR;
  RotationTheta: D3DVALUE;

begin
if Dragging then begin
Inc(DragCount);

  DeltaX := x - LastMouseX;
  DeltaY := y - LastMouseY;
  LastMouseX := x;
  LastMouseY := y;

  DeltaR := Sqrt(DeltaX * DeltaX + DeltaY * DeltaY);
  Denom := Sqrt(Radius * Radius + DeltaR * DeltaR);

  if (DeltaR = 0) or (Denom = 0) then Exit;

  Rotation.x := -DeltaY / DeltaR;  // Notice the reverse of x and y - this is intentional
  Rotation.y := -DeltaX / DeltaR;
  Rotation.z := 0;
  RotationTheta := DeltaR / Denom;

  if DragCount < 2 then begin
     // First couple of drag movements cause wierd model rotation
     RotationTheta := 0;
  end;

  ADXHRESULT(Model.Frame.AddRotation(D3DRMCOMBINE_AFTER, Rotation.x, Rotation.y, Rotation.z, RotationTheta));

  RenderUpdate;

end;
end;

// MouseUp event calls DragModelEnd

// RenderUpdate re-renders entire scene

NOTE: The Model.Frame variable is an IDirect3DRMFrame3, which is a child frame of the scene frame, so its position is in world coordinates. Likewise with the camera frame (but the camera position should not affect the above code).

I imagine that the call to AddRotation() would be replaced by a call to glRotate(), or maybe you would postmultiply a new rotation matrix onto a position/orientation matrix associated with your model?

Do you have a beta version of your game somewhere on the net?

Thanks for posting all that. It’ll take a while to digest, and no I don’t hate DirectX. It is another tool that may come in handy if GL fails me.

First I’ll try this though, if it doesn’t work I’ll take a close look at the DX code:

-Use angles from the viewers position to the ships, first of all to find which ships are within viewing window(a 45 degree window), getting the angles RELATIVE to the viewer and relating that to the angle of the mouse position, converted. Say mouse position is at far right, y-axis would be 45 degrees. In the middle it would be zero, but always additioning the actual angle of the viewer.

ps. about the demo, it’s not very playable as you cannot select ships to give them orders. However the camera system works very well, as does many other aspects of the engine eg. Moving ships around realistically.

I’ll definetly let people know when the early 0.01 beta is available. Screenshots will be posted soon also, as of course I can at least get those.

I looked at the code of skippyj777 and I don’t get where is the selection code. You see you have to make the connection between the objects from the scene with the objects into the memory (in other words if I detect that at one position from the screen is an object i must know what object from my object list it is…). And that code I don’t see in the program. And if you don’t use the lists from Ogl or you don’t code the position of the ship in your object you have to make some pattern recognition and then…
The solution is to attach to each object in the world a propriety named coordinates
(an array of 3 floats or doubles) and keep them in the memory all the time. This problem is that the function of transformations from the objects into the memory to screen isn’t bijective.
If you want to use the tools OpenGl has you have to create all the objects from lists and them you can select with the gl PopName().

NewROmancer

This code does not select a model because there is only one model. The selection code the program does have (which I removed from the sample) selects a face on the model.

Since you are making a space based 3dRTS, I suggest you look at Homeworld and how they handled this problem. I thought it worked quite well and I was never frustrated with it:

  1. A single click is a selection on the firstmost object in your view with coords(x,y, z) where you raytrace z into infinity (or the boundries of your view) until it hits an object

  2. A click and drag selects all objects within that 2d plane, traced back into infinity (or the boundries of your view). If there are two objects on top of each other, they are still both selected.

That way, the user then must control the camera properly to get the ships he wants selected, and you don’t have to worry about exactly what he needs. This has the added benefit of being a similar thought process to how most other RTS games work. I’ve seen enough suggestions here to help you implement this in code.

It seems like you guys are going through a lot of trouble to find out what you are trying to select. I think that the redbook idea is probably the most simple, though it does have problems if one object totally occludes another object. Even there, though, I think that it would be rather unlikely in a space RTS that one object would totally occlude another during selection. Generally, people want to pick what they can see.

I haven’t checked, but is GLReadPixels that slow? Even for a large number of pixels I can’t imagine it being that bad. Even if it is slow I doubt that it is as bad as doing all sorts of sorting, projection, and intersection testing.

You can’t drag using any of those methods. Is draggin REALLY needed in an RTS game I ask you? It’s tons of work to implement it.

the methods you suggest are much simpler

Well I’ve been experimenting and cleaning up my camera system so that it’s bug free and all I have to do is implement my angular selection.
This may seem like a simple question, it is a simple question, it’s finding the angle between two points in 2d space. If I can do that it’s easy to do in 3d space.
Easy to do on paper and calculator, but doing it in a decent way in the C++ language is different, could somebody post a snippet of code to do this?

what I need to do is pass it two points, the cameras location in 2d x and z and another location in 2d and find the angle from the camera to the location like so:

float FindAngle(float x1 z1 x2 z2)
{
find angle from point 1 to point 2
return angle(float)
}

Humm, I don’t really understand where is the problem exactly, if you want to know the angle between 2 vectors:

From Inet (I’m very lazy) :

theta=acos((v1 DOT v2)/(|v1|*|v2|))

v1,v2: vector
DOT : dot product
|v1| : length of v1

If you preblem is to determine which model your mouse is on…

You need to make a bounding square (implicitly) for each model, you scale it by the distance, and then you go through all your visible object and determine in x and y if you mouse pointer is in one of those square. If there is more then one, choose the nearest.

To move you model in 3d, I propose you have a look at homeworld, it is quite user friendly.

If I do not answer your question, or if you need more detail explanation, feel free to ask.

Good luck!

See the source to the smooth.c demo in the GLUT distribution for an example of doing this using gluProject and gluUnproject (in the mouse and move methods).

And where can I find that GLUT source?
Also my angular selection system seems to be working in my experiments so far, if it turns out that it works, and it is pretty accurate, I will post the code for everybody to see what is probably the easiest way to do it.

The viewer is supposed to rotate around the ship with the camera pointing at the ship
to get any angle they want. The new feature is that they can change their angle, so it’s
not fixed to stare at the ship all the time. The camera will stay, the fixed angle to look
at the camera will still exist, but the viewer will look freely.

I’ve had nothing but problems with the coding of this. It always rotates or translates the
wrong way and I can’t quite seem to figure out the order of operations and coding it
in my head. The logic evades me.

Here’s what needs to be done, the orders of operation but not in the right order
and probably missing an order or two.

-Move the world so that the ship of our attention is at origin, 0,0,0
-Zoom out, this is our zoom distance from the ship
-Rotate, this is the angle that we’re looking at the ship if we’re under the ship, in front
etc.
-THEN rotate other than the fixed angle towards the ship. User presses observer button
to look. This is the confusing part(coding that is). The camera stays in the
same place but it’s looking angle changes.

Now I hope this makes sense, I’ve explained it as clearly as I could. I hope you know
my problem and what I hope to accomplish.

I’m pretty sure this is an easy concept too.

NOTE: please post pseudo code and document it as you see fit.