+
+
+void primray(cgm_ray *ray, int x, int y)
+{
+ float nx, ny;
+ cgm_vec3 npos, farpt;
+ float inv_pv[16];
+
+ y = win_height - y;
+ nx = (float)(x - viewport[0]) / (float)viewport[2];
+ ny = (float)(y - viewport[1]) / (float)viewport[3];
+
+ cgm_mcopy(inv_pv, proj_matrix_inv);
+ cgm_mmul(inv_pv, view_matrix_inv);
+
+ cgm_vcons(&npos, nx, ny, 0.0f);
+ cgm_unproject(&ray->origin, &npos, inv_pv);
+ npos.z = 1.0f;
+ cgm_unproject(&farpt, &npos, inv_pv);
+
+ ray->dir.x = farpt.x - ray->origin.x;
+ ray->dir.y = farpt.y - ray->origin.y;
+ ray->dir.z = farpt.z - ray->origin.z;
+}
+
+static void moveobj(struct object *obj, int px0, int py0, int px1, int py1)
+{
+ cgm_ray ray;
+ float dist;
+ cgm_vec3 p0, p1;
+
+ primray(&ray, px0, py0);
+ cgm_vnormalize(&ray.dir);
+ dist = ray_object_dist(&ray, obj);
+ cgm_raypos(&p0, &ray, dist);
+ primray(&ray, px1, py1);
+ cgm_vnormalize(&ray.dir);
+ cgm_raypos(&p1, &ray, dist);
+
+ cgm_vsub(&p1, &p0);
+ cgm_vadd(&obj->pos, &p1);
+ obj->xform_valid = 0;
+
+ inval_vport();
+}
+
+static void inval_vport(void)
+{
+ vpdirty = 1;
+ app_redisplay(0, 0, 0, 0);
+}