1219b2ee8SDavid du Colombier /*
2219b2ee8SDavid du Colombier * The following routines transform points and planes from one space
3219b2ee8SDavid du Colombier * to another. Points and planes are represented by their
4219b2ee8SDavid du Colombier * homogeneous coordinates, stored in variables of type Point3.
5219b2ee8SDavid du Colombier */
6219b2ee8SDavid du Colombier #include <u.h>
7219b2ee8SDavid du Colombier #include <libc.h>
8*7dd7cddfSDavid du Colombier #include <draw.h>
9219b2ee8SDavid du Colombier #include <geometry.h>
10219b2ee8SDavid du Colombier /*
11219b2ee8SDavid du Colombier * Transform point p.
12219b2ee8SDavid du Colombier */
xformpoint(Point3 p,Space * to,Space * from)13219b2ee8SDavid du Colombier Point3 xformpoint(Point3 p, Space *to, Space *from){
14219b2ee8SDavid du Colombier Point3 q, r;
15219b2ee8SDavid du Colombier register double *m;
16219b2ee8SDavid du Colombier if(from){
17219b2ee8SDavid du Colombier m=&from->t[0][0];
18219b2ee8SDavid du Colombier q.x=*m++*p.x; q.x+=*m++*p.y; q.x+=*m++*p.z; q.x+=*m++*p.w;
19219b2ee8SDavid du Colombier q.y=*m++*p.x; q.y+=*m++*p.y; q.y+=*m++*p.z; q.y+=*m++*p.w;
20219b2ee8SDavid du Colombier q.z=*m++*p.x; q.z+=*m++*p.y; q.z+=*m++*p.z; q.z+=*m++*p.w;
21219b2ee8SDavid du Colombier q.w=*m++*p.x; q.w+=*m++*p.y; q.w+=*m++*p.z; q.w+=*m *p.w;
22219b2ee8SDavid du Colombier }
23219b2ee8SDavid du Colombier else
24219b2ee8SDavid du Colombier q=p;
25219b2ee8SDavid du Colombier if(to){
26219b2ee8SDavid du Colombier m=&to->tinv[0][0];
27219b2ee8SDavid du Colombier r.x=*m++*q.x; r.x+=*m++*q.y; r.x+=*m++*q.z; r.x+=*m++*q.w;
28219b2ee8SDavid du Colombier r.y=*m++*q.x; r.y+=*m++*q.y; r.y+=*m++*q.z; r.y+=*m++*q.w;
29219b2ee8SDavid du Colombier r.z=*m++*q.x; r.z+=*m++*q.y; r.z+=*m++*q.z; r.z+=*m++*q.w;
30219b2ee8SDavid du Colombier r.w=*m++*q.x; r.w+=*m++*q.y; r.w+=*m++*q.z; r.w+=*m *q.w;
31219b2ee8SDavid du Colombier }
32219b2ee8SDavid du Colombier else
33219b2ee8SDavid du Colombier r=q;
34219b2ee8SDavid du Colombier return r;
35219b2ee8SDavid du Colombier }
36219b2ee8SDavid du Colombier /*
37219b2ee8SDavid du Colombier * Transform point p with perspective division.
38219b2ee8SDavid du Colombier */
xformpointd(Point3 p,Space * to,Space * from)39219b2ee8SDavid du Colombier Point3 xformpointd(Point3 p, Space *to, Space *from){
40219b2ee8SDavid du Colombier p=xformpoint(p, to, from);
41219b2ee8SDavid du Colombier if(p.w!=0){
42219b2ee8SDavid du Colombier p.x/=p.w;
43219b2ee8SDavid du Colombier p.y/=p.w;
44219b2ee8SDavid du Colombier p.z/=p.w;
45219b2ee8SDavid du Colombier p.w=1;
46219b2ee8SDavid du Colombier }
47219b2ee8SDavid du Colombier return p;
48219b2ee8SDavid du Colombier }
49219b2ee8SDavid du Colombier /*
50219b2ee8SDavid du Colombier * Transform plane p -- same as xformpoint, except multiply on the
51219b2ee8SDavid du Colombier * other side by the inverse matrix.
52219b2ee8SDavid du Colombier */
xformplane(Point3 p,Space * to,Space * from)53219b2ee8SDavid du Colombier Point3 xformplane(Point3 p, Space *to, Space *from){
54219b2ee8SDavid du Colombier Point3 q, r;
55219b2ee8SDavid du Colombier register double *m;
56219b2ee8SDavid du Colombier if(from){
57219b2ee8SDavid du Colombier m=&from->tinv[0][0];
58219b2ee8SDavid du Colombier q.x =*m++*p.x; q.y =*m++*p.x; q.z =*m++*p.x; q.w =*m++*p.x;
59219b2ee8SDavid du Colombier q.x+=*m++*p.y; q.y+=*m++*p.y; q.z+=*m++*p.y; q.w+=*m++*p.y;
60219b2ee8SDavid du Colombier q.x+=*m++*p.z; q.y+=*m++*p.z; q.z+=*m++*p.z; q.w+=*m++*p.z;
61219b2ee8SDavid du Colombier q.x+=*m++*p.w; q.y+=*m++*p.w; q.z+=*m++*p.w; q.w+=*m *p.w;
62219b2ee8SDavid du Colombier }
63219b2ee8SDavid du Colombier else
64219b2ee8SDavid du Colombier q=p;
65219b2ee8SDavid du Colombier if(to){
66219b2ee8SDavid du Colombier m=&to->t[0][0];
67219b2ee8SDavid du Colombier r.x =*m++*q.x; r.y =*m++*q.x; r.z =*m++*q.x; r.w =*m++*q.x;
68219b2ee8SDavid du Colombier r.x+=*m++*q.y; r.y+=*m++*q.y; r.z+=*m++*q.y; r.w+=*m++*q.y;
69219b2ee8SDavid du Colombier r.x+=*m++*q.z; r.y+=*m++*q.z; r.z+=*m++*q.z; r.w+=*m++*q.z;
70219b2ee8SDavid du Colombier r.x+=*m++*q.w; r.y+=*m++*q.w; r.z+=*m++*q.w; r.w+=*m *q.w;
71219b2ee8SDavid du Colombier }
72219b2ee8SDavid du Colombier else
73219b2ee8SDavid du Colombier r=q;
74219b2ee8SDavid du Colombier return r;
75219b2ee8SDavid du Colombier }
76