cs_project in csqc
Moderator: InsideQC Admins
18 posts
• Page 1 of 2 • 1, 2
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.
(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.
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: Select all
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 ]
-

daemon - Posts: 63
- Joined: Wed Nov 07, 2007 11:10 pm
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.
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 ]
-

daemon - Posts: 63
- Joined: Wed Nov 07, 2007 11:10 pm
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)
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.
- Code: Select all
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 ]
-

daemon - Posts: 63
- Joined: Wed Nov 07, 2007 11:10 pm
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?
I was once a Quake modder
-

Urre - Posts: 1109
- Joined: Fri Nov 05, 2004 2:36 am
- Location: Moon
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.
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.
- Spike
- Posts: 2892
- Joined: Fri Nov 05, 2004 3:12 am
- Location: UK
So, this should do the trick?
- Code: Select all
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;
I was once a Quake modder
-

Urre - Posts: 1109
- Joined: Fri Nov 05, 2004 2:36 am
- Location: Moon
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.
- LordHavoc
- Posts: 322
- Joined: Fri Nov 05, 2004 3:12 am
- Location: western Oregon, USA
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.
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.
I was once a Quake modder
-

Urre - Posts: 1109
- Joined: Fri Nov 05, 2004 2:36 am
- Location: Moon
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?
I was once a Quake modder
-

Urre - Posts: 1109
- Joined: Fri Nov 05, 2004 2:36 am
- Location: Moon
For anyone who wants reference of code that actually works (atleast in DarkPlaces), here goes, shouldn't be hard to understand:
Note how the mouse position and the actual traceline require different setup code.
- Code: Select all
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.
I was once a Quake modder
-

Urre - Posts: 1109
- Joined: Fri Nov 05, 2004 2:36 am
- Location: Moon
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:
Enjoy!
- Code: Select all
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!
I was once a Quake modder
-

Urre - Posts: 1109
- Joined: Fri Nov 05, 2004 2:36 am
- Location: Moon
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.
if you wanted to do an unproject traceline it would look something like this:
project is fairly simple. you just give it an origin in the world, and it will give you a 2d origin on the screen.
- Code: Select all
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: Select all
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 ]
-

daemon - Posts: 63
- Joined: Wed Nov 07, 2007 11:10 pm
18 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 1 guest