Mercurial > hg > old > magoroku_racing
comparison col.c @ 0:0fae5658fb0b
Initial revision
author | gongo |
---|---|
date | Thu, 02 Nov 2006 08:55:19 +0000 |
parents | |
children | b1ba4dad7f6e |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0fae5658fb0b |
---|---|
1 /* | |
2 * $Id$ | |
3 */ | |
4 #include <stdio.h> | |
5 #include"libps2.h" | |
6 #include"ps2util.h" | |
7 #include"col.h" | |
8 #include"mytype.h" | |
9 | |
10 /* | |
11 * v0, v1が描く三角形と点pの内外判定(approx detection) | |
12 * 点pはv0, v1が描く面のどこかに位置している。 | |
13 * pが面の三角形の外側にあるときTRUEを戻し、 | |
14 * そうでなければFALSEを戻す。境界は含む。 | |
15 */ | |
16 static Bool | |
17 col_detect_approx(FVECTOR p, FVECTOR v0, FVECTOR v1) | |
18 { | |
19 float v_r1, v_r2, r1_r2, r1_r1, r2_r2; | |
20 float a, b, r; | |
21 | |
22 v_r1 = ps2_vu0_inner_product( p, v0 ); | |
23 v_r2 = ps2_vu0_inner_product( p, v1 ); | |
24 r1_r2 = ps2_vu0_inner_product( v0, v1 ); | |
25 r1_r1 = ps2_vu0_inner_product( v0, v0 ); | |
26 r2_r2 = ps2_vu0_inner_product( v1, v1 ); | |
27 | |
28 a = (v_r1 * r2_r2 - v_r2 * r1_r2); | |
29 b = (v_r2 * r1_r1 - v_r1 * r1_r2); | |
30 r = (r1_r1 * r2_r2 - r1_r2 * r1_r2); | |
31 | |
32 return (a>=0 && b>=0 && a+b-r<=0) ? TRUE : FALSE; | |
33 } | |
34 | |
35 /** | |
36 * 垂心oの算出. 点pからv0, v1が描く面へ垂線を引いたときの交点oを | |
37 * 垂心(orthocenter)と呼ぶ。 | |
38 */ | |
39 static void | |
40 col_orthocenter(FVECTOR o, FVECTOR p, FVECTOR p0, FVECTOR normal) | |
41 { | |
42 FVECTOR o0, d; | |
43 | |
44 ps2_vu0_sub_vector(o0, p, p0); | |
45 o0[W_AXIS] = 0; | |
46 ps2_vu0_scale_vector( | |
47 d, normal, ps2_vu0_inner_product(o0, normal)); | |
48 | |
49 o[X_AXIS] = p[X_AXIS] - d[X_AXIS]; | |
50 o[Y_AXIS] = p[Y_AXIS] - d[Y_AXIS]; | |
51 o[Z_AXIS] = p[Z_AXIS] - d[Z_AXIS]; | |
52 o[W_AXIS] = 1; | |
53 } | |
54 | |
55 /** | |
56 * 点pと面との衝突(点pとdetection face面との垂心oがdetection face領域の | |
57 * 中にあるかを)判定衝突時(oがdetection face領域の外)はFALSEを戻し、そう | |
58 * でなければTRUE、 垂心(orthocenter)、垂心のある面の法線(normal | |
59 * vector)を戻す. | |
60 */ | |
61 Bool | |
62 col_detect(ColFaceHd* hd, FVECTOR pose, FVECTOR p) | |
63 { | |
64 FVECTOR o, o0; | |
65 int i; | |
66 ColFacePtr col_face=hd->colface; | |
67 for (i=0; i<hd->facenum; i++) { | |
68 /* | |
69 * 垂心oを求める | |
70 */ | |
71 col_orthocenter(o, p, col_face[i].p0, col_face[i].normal); | |
72 /* | |
73 * detection face上のある点p0から垂心oへのベクトルo0を求める | |
74 */ | |
75 ps2_vu0_sub_vector(o0, o, col_face[i].p0); | |
76 /* | |
77 * ベクトルv0, v1の描く三角形とo0とで内外判定(range approx detection)を行う | |
78 */ | |
79 if (col_detect_approx(o0, col_face[i].v0, col_face[i].v1)==TRUE) { | |
80 goto NOCOLLISION; | |
81 } | |
82 } | |
83 return FALSE; | |
84 NOCOLLISION: | |
85 ps2_vu0_copy_vector(p, o); | |
86 ps2_vu0_copy_vector(pose, col_face[i].normal); | |
87 return TRUE; | |
88 } | |
89 | |
90 /* | |
91 * detection face作成 | |
92 */ | |
93 void | |
94 col_init(ColFaceHd* hd, PolygonInfo* face) | |
95 { | |
96 int i; | |
97 FVECTOR p1, p2; | |
98 ColFacePtr colface; | |
99 | |
100 malloc_align16(&hd->free_addr, &colface, sizeof(ColFace)*face->siz/3); | |
101 | |
102 hd->facenum = face->siz/3; | |
103 | |
104 for (i=0; i<hd->facenum; i++) { | |
105 memcpy(colface[i].p0, ((FVECTOR*)face->pnts)[i*3], sizeof(FVECTOR)); | |
106 memcpy(p1, ((FVECTOR*)face->pnts)[i*3+2], sizeof(FVECTOR)); | |
107 memcpy(p2, ((FVECTOR*)face->pnts)[i*3+1], sizeof(FVECTOR)); | |
108 | |
109 ps2_vu0_sub_vector(colface[i].v0, p1, colface[i].p0); | |
110 ps2_vu0_sub_vector(colface[i].v1, p2, colface[i].p0); | |
111 | |
112 ps2_vu0_outer_product(colface[i].normal, colface[i].v0, colface[i].v1); | |
113 ps2_vu0_normalize(colface[i].normal, colface[i].normal); | |
114 | |
115 if (colface[i].normal[1] > 0) { | |
116 colface[i].normal[0] = -colface[i].normal[0]; | |
117 colface[i].normal[1] = -colface[i].normal[1]; | |
118 colface[i].normal[2] = -colface[i].normal[2]; | |
119 } | |
120 } | |
121 | |
122 hd->colface = colface; | |
123 } |