View previous topic :: View next topic |
Author |
Message |
daemon

Joined: 07 Nov 2007 Posts: 62
|
Posted: Sun Dec 30, 2007 2:54 am Post subject: cs_project in csqc |
|
|
can someone explain the ins and outs of cs_project to me? I finally got cs_unproject to do what I want, though I don't fully understand it yet. It's been explained to me a couple different ways, and I'm sure I'm not using it totally correct. One odd thing about it is that the results end up as though I'm facing 90 degrees in the wrong direction, so I ended up swapping the x and y coordinates of the final product after the trace. I also had to multiply my trace distance by 9, which I thought was odd...
this doesn't work too well in a map with any kind of walls, because the trace seems to be happening 90 degrees in the wrong direction, but since I'm not using any walls, it works for now.
Code: | local vector org, vec, vec2;
vec = getmousepos();
vec_x = vec_x*vid_realwidth/vid_width;
vec_y = vec_y*vid_realheight/vid_height;
vec_z = 1;
org = cs_unproject(vec);
vec_z = 0;
vec2 = cs_unproject(vec);
traceline(vec2, normalize(org)*(cl_org_y-editinglayer)*9, TRUE, world);
vec = trace_endpos;
org_x = cl_org_x + vec_y;
org_z = cl_org_z + vec_z;
org_y = 0; |
(cl_org is the client's org, y being the distance away from the plane to be drawn on)
anyway, now I need to use cs_project because I'm trying to draw some things on the screen, snapped to a grid on that plane, but I have no idea how to use it. _________________ -daemon [ daemonforge.org ] |
|
Back to top |
|
 |
daemon

Joined: 07 Nov 2007 Posts: 62
|
Posted: Mon Dec 31, 2007 2:29 am Post subject: |
|
|
Ok, I THINK the 90 degrees off thing is because I had this:
R_SetView(VF_ANGLES, '0 0 0');
before the previous code... but changing it to '0 -90 0' seems to mess things up even after getting rid of the x and y swap... guess I'll have to mess around with this more. _________________ -daemon [ daemonforge.org ] |
|
Back to top |
|
 |
daemon

Joined: 07 Nov 2007 Posts: 62
|
Posted: Mon Dec 31, 2007 3:12 am Post subject: |
|
|
YAY! I finally got it to work. It was as simple as I thought it was supposed to be. This code works a LOT better (the first two lines are just there because a lot of the HUD stuff messes with the origin and angle settings, so I needed to make them match the camera)
Code: | R_SetView(VF_ANGLES, '0 -90 0');
R_SetView(VF_ORIGIN, cl_org);
local vector org;
org = getmousepos();
org_x = org_x*vid_realwidth/vid_width;
org_y = org_y*vid_realheight/vid_height;
org_z = cl_org_y;
org = cs_unproject(org); |
Also note that org_z does not have to be between 0 and 1 as everyone told me it did... No traceline is necessary unless you're trying to hit a surface, but since the plane I'm drawing on is parallel to the camera, and the camera doesn't turn, and I know how far away I am from that plane, then I don't need to bother with any traces. _________________ -daemon [ daemonforge.org ] |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Mon Mar 10, 2008 2:51 pm Post subject: |
|
|
In your last post, what does the line org = cs_unproject(org); result in? As I understand it, it's a spot in the world. Am I supposed to project from the camera position to the result from cs_unproject or what (if I want to traceline)? Or is it possibly even simpler, a direction it returns? _________________ Look out for Twigboy |
|
Back to top |
|
 |
Spike
Joined: 05 Nov 2004 Posts: 944 Location: UK
|
Posted: Mon Mar 10, 2008 4:21 pm Post subject: |
|
|
unproject takes a 2d coordinate with depth (3d...) and converts it into a 3d coordinate.
if you unproject the same point twice with depth of 0 and 1, you'll get the view position (a point on the near clip plane) and a point gl_maxdist away. You can then traceline between the two to see what you hit.
Note that the unproject function uses the view properties state to generate matricies as required, so you will need to clear the scene and set up some stuff before use. At least if you're inside an update event. _________________ What's a signature? |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Mon Mar 10, 2008 7:39 pm Post subject: |
|
|
Neat, will test soon _________________ Look out for Twigboy |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Tue Mar 25, 2008 1:26 am Post subject: |
|
|
So, this should do the trick?
Code: | mouse_pos_x = vid_conwidth;
mouse_pos_y = vid_conheight;
mouse_pos = mouse_pos*0.5 + getmousepos();
cam = mouse_pos;
cam_z = 0;
cam = cs_unproject(cam);
proj = mouse_pos;
proj_z = 1;
proj = cs_unproject(proj);
traceline(cam, proj, FALSE, world);
mouse_trace_ent = trace_ent;
mouse_trace_endpos = trace_endpos; |
_________________ Look out for Twigboy |
|
Back to top |
|
 |
Spike
Joined: 05 Nov 2004 Posts: 944 Location: UK
|
Posted: Wed Mar 26, 2008 8:42 am Post subject: |
|
|
Your asking makes me think it does not. _________________ What's a signature? |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Sat Mar 29, 2008 10:54 am Post subject: |
|
|
Nope. It traces very close to '0 0 0', but not exactly, max 2 quake units away. _________________ Look out for Twigboy |
|
Back to top |
|
 |
LordHavoc
Joined: 05 Nov 2004 Posts: 243 Location: western Oregon, USA
|
Posted: Sat Mar 29, 2008 11:49 am Post subject: |
|
|
Urre wrote: | Nope. It traces very close to '0 0 0', but not exactly, max 2 quake units away. |
From examining the code I would guess that all results are twice as
'wide' as they're supposed to be (meaning you could get correct results by using _x * 0.5 and _y * 0.5), if you could confirm that this 'fixes' it, I'll fix the code to not do the unnecessary *2's. |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Sat Mar 29, 2008 6:27 pm Post subject: |
|
|
It resulted in half the result, as I expected. What I wanted, was to trace into the world with my mouse cursor, to select my units and whatnot...
Don't confuse my "2 units off" with '0 0 0' being the correct result. What I meant by that is that it traces towards the world centre, no matter what. _________________ Look out for Twigboy |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Mon Mar 31, 2008 2:04 pm Post subject: |
|
|
After some IRC chat with LH and frank, we came to various conclusions. One conclusion of franks perception which made it somewhat work, was that depth needed to be as far as I wanted it to trace, not between 0-1. I used 10000 on the second unproject for giggles, and that atleast trace into the world. What was still wrong however was that it didn't properly match the mousepointer. It seemed off-scale, or offset strangely. I did lots of tweaking, but to no good result. LH later informed me that I need to set up a view for it to properly work, which basicly means running the code after my R_SetView(VF_ORIGIN, blah); and R_SetView(VF_ANGLES, blah); but that didn't change anything at all... Any thoughts? Anything I've missed? _________________ Look out for Twigboy |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Wed Apr 02, 2008 4:14 pm Post subject: |
|
|
For anyone who wants reference of code that actually works (atleast in DarkPlaces), here goes, shouldn't be hard to understand:
Code: | getmouse = getmousepos();
mouse_pos_x = vid_conwidth;
mouse_pos_y = vid_conheight;
mouse_pos = mouse_pos*0.5 + getmouse;
proj = getmouse;
proj_x = proj_x*vid_width/vid_conwidth;
proj_y = proj_y*vid_height/vid_conheight;
start = cs_unproject(proj);
end = cs_unproject(proj + '0 0 10000');
traceline(start, end, FALSE, world);
mouse_trace_ent = trace_ent;
mouse_trace_endpos = trace_endpos; |
Note how the mouse position and the actual traceline require different setup code. _________________ Look out for Twigboy |
|
Back to top |
|
 |
Urre

Joined: 05 Nov 2004 Posts: 1073 Location: Sweden
|
Posted: Wed Jul 23, 2008 8:03 pm Post subject: |
|
|
There was a bug in the way DarkPlaces handled mouse reading which was fixed, so the above code is no longer valid. And therefore, I figured I should update it! Here goes:
Code: | mouse_pos = getmousepos();
proj = mouse_pos;
proj_x = (proj_x*vid_width/vid_conwidth)-vid_width*0.5;
proj_y = (proj_y*vid_height/vid_conheight)-vid_height*0.5;
start = cs_unproject(proj);
end = cs_unproject(proj + '0 0 10000');
traceline(start, end, FALSE, world);
mouse_trace_ent = trace_ent;
mouse_trace_endpos = trace_endpos; |
Enjoy! _________________ Look out for Twigboy |
|
Back to top |
|
 |
daemon

Joined: 07 Nov 2007 Posts: 62
|
Posted: Tue Jul 29, 2008 8:22 pm Post subject: |
|
|
as requested by Urre, here are a couple functions that make using project and unproject easier. They are fairly similar to what he just posted.
Code: |
vector unproject(vector vec) =
{
vec_x = (vec_x-vid_size_x*0.5)*vid_res_x/vid_size_x;
vec_y = (vec_y-vid_size_y*0.5)*vid_res_y/vid_size_y;
vec = cs_unproject(vec);
return vec;
}
vector project(vector vec) =
{
vec = cs_project(vec);
vec_x = vec_x*vid_size_x/vid_res_x;
vec_y = vec_y*vid_size_y/vid_res_y;
vec = vid_size*0.5 + vec;
vec_z = 0;
return vec;
} |
if you wanted to do an unproject traceline it would look something like this:
Code: |
start = unproject(org);
end = unproject(org + '0 0 1000');
traceline(start, end, IGNOREFLAG, ent); |
project is fairly simple. you just give it an origin in the world, and it will give you a 2d origin on the screen. _________________ -daemon [ daemonforge.org ] |
|
Back to top |
|
 |
|