• R/O
  • SSH
  • HTTPS

提交

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。


Commit MetaInfo

修訂93 (tree)
時間2015-06-14 20:33:25
作者xops-mikan

Log Message

ブロックの法線ベクトル算出を変更、当たり判定に用いる関数のバグ修正

Change Summary

差異

--- trunk/soundmanager.cpp (revision 92)
+++ trunk/soundmanager.cpp (revision 93)
@@ -455,7 +455,7 @@
455455 speed = (float)sqrt(plist->move_x*plist->move_x + plist->move_y*plist->move_y + plist->move_z*plist->move_z);
456456
457457 //最短距離の座標を求める
458- min_dist = DistancePosRay(camera_x, camera_y, camera_z, plist->x, plist->y, plist->z, plist->move_x/speed, plist->move_y/speed, plist->move_z/speed, (float)speed*2);
458+ min_dist = DistancePosRay(camera_x, camera_y, camera_z, plist->x, plist->y, plist->z, plist->move_x/speed, plist->move_y/speed, plist->move_z/speed);
459459
460460 //最短距離時の座標を求める
461461 dist = (float)sqrt(dist2 - min_dist*min_dist);
--- trunk/collision.h (revision 92)
+++ trunk/collision.h (revision 93)
@@ -88,7 +88,7 @@
8888 bool CollideSphereRay(float s_x, float s_y, float s_z, float s_r, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float *Dist, float maxDist);
8989 bool CollideAABBRay(float box_min_x, float box_min_y, float box_min_z, float box_max_x, float box_max_y, float box_max_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float *Dist, float maxDist);
9090 bool CollideCylinderRay(float c_x, float c_y, float c_z, float c_r, float c_h, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float *Dist, float maxDist);
91-float DistancePosRay(float Pos_x, float Pos_y, float Pos_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float maxDist);
91+float DistancePosRay(float Pos_x, float Pos_y, float Pos_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z);
9292 bool Collide2DLine(int A1x, int A1y, int A2x, int A2y, int B1x, int B1y, int B2x, int B2y, int *out_x, int *out_y);
9393 bool Get2DLineInBox(int line_x1, int line_y1, int line_x2, int line_y2, int box_x1, int box_y1, int box_x2, int box_y2, int *out_line_x1, int *out_line_y1, int *out_line_x2, int *out_line_y2);
9494
--- trunk/datafile.cpp (revision 92)
+++ trunk/datafile.cpp (revision 93)
@@ -177,6 +177,10 @@
177177 int uvID[4];
178178 float g;
179179 float xs, ys, zs;
180+ float g1;
181+ float xs1, ys1, zs1;
182+ float g2;
183+ float xs2, ys2, zs2;
180184 float lx, ly, lz;
181185 float rx, ry, rz, a;
182186
@@ -193,18 +197,30 @@
193197 blockdataface(j, vID, uvID);
194198
195199 //面の法線(ベクトル)と、その長さを求める
196- xs = ((data[i].y[ vID[3] ] - data[i].y[ vID[2] ]) * (data[i].z[ vID[0] ] - data[i].z[ vID[2] ])) - ((data[i].y[ vID[0] ] - data[i].y[ vID[2] ]) * (data[i].z[ vID[3] ] - data[i].z[ vID[2] ]));
197- ys = ((data[i].z[ vID[3] ] - data[i].z[ vID[2] ]) * (data[i].x[ vID[0] ] - data[i].x[ vID[2] ])) - ((data[i].z[ vID[0] ] - data[i].z[ vID[2] ]) * (data[i].x[ vID[3] ] - data[i].x[ vID[2] ]));
198- zs = ((data[i].x[ vID[3] ] - data[i].x[ vID[2] ]) * (data[i].y[ vID[0] ] - data[i].y[ vID[2] ])) - ((data[i].x[ vID[0] ] - data[i].x[ vID[2] ]) * (data[i].y[ vID[3] ] - data[i].y[ vID[2] ]));
199- g = (float)sqrt(xs * xs + ys * ys + zs * zs);
200+ xs1 = ((data[i].y[ vID[3] ] - data[i].y[ vID[2] ]) * (data[i].z[ vID[0] ] - data[i].z[ vID[2] ])) - ((data[i].y[ vID[0] ] - data[i].y[ vID[2] ]) * (data[i].z[ vID[3] ] - data[i].z[ vID[2] ]));
201+ ys1 = ((data[i].z[ vID[3] ] - data[i].z[ vID[2] ]) * (data[i].x[ vID[0] ] - data[i].x[ vID[2] ])) - ((data[i].z[ vID[0] ] - data[i].z[ vID[2] ]) * (data[i].x[ vID[3] ] - data[i].x[ vID[2] ]));
202+ zs1 = ((data[i].x[ vID[3] ] - data[i].x[ vID[2] ]) * (data[i].y[ vID[0] ] - data[i].y[ vID[2] ])) - ((data[i].x[ vID[0] ] - data[i].x[ vID[2] ]) * (data[i].y[ vID[3] ] - data[i].y[ vID[2] ]));
203+ g1 = (float)sqrt(xs1 * xs1 + ys1 * ys1 + zs1 * zs1);
200204
201- //もし法線がおかしければ、もう一方の三角形で計算をやり直す
202- if( g < 0.01f ){
203- xs = ((data[i].y[ vID[1] ] - data[i].y[ vID[0] ]) * (data[i].z[ vID[2] ] - data[i].z[ vID[0] ])) - ((data[i].y[ vID[2] ] - data[i].y[ vID[0] ]) * (data[i].z[ vID[1] ] - data[i].z[ vID[0] ]));
204- ys = ((data[i].z[ vID[1] ] - data[i].z[ vID[0] ]) * (data[i].x[ vID[2] ] - data[i].x[ vID[0] ])) - ((data[i].z[ vID[2] ] - data[i].z[ vID[0] ]) * (data[i].x[ vID[1] ] - data[i].x[ vID[0] ]));
205- zs = ((data[i].x[ vID[1] ] - data[i].x[ vID[0] ]) * (data[i].y[ vID[2] ] - data[i].y[ vID[0] ])) - ((data[i].x[ vID[2] ] - data[i].x[ vID[0] ]) * (data[i].y[ vID[1] ] - data[i].y[ vID[0] ]));
206- g = (float)sqrt(xs * xs + ys * ys + zs * zs);
205+ //もう一方の三角形でも計算する
206+ xs2 = ((data[i].y[ vID[1] ] - data[i].y[ vID[0] ]) * (data[i].z[ vID[2] ] - data[i].z[ vID[0] ])) - ((data[i].y[ vID[2] ] - data[i].y[ vID[0] ]) * (data[i].z[ vID[1] ] - data[i].z[ vID[0] ]));
207+ ys2 = ((data[i].z[ vID[1] ] - data[i].z[ vID[0] ]) * (data[i].x[ vID[2] ] - data[i].x[ vID[0] ])) - ((data[i].z[ vID[2] ] - data[i].z[ vID[0] ]) * (data[i].x[ vID[1] ] - data[i].x[ vID[0] ]));
208+ zs2 = ((data[i].x[ vID[1] ] - data[i].x[ vID[0] ]) * (data[i].y[ vID[2] ] - data[i].y[ vID[0] ])) - ((data[i].x[ vID[2] ] - data[i].x[ vID[0] ]) * (data[i].y[ vID[1] ] - data[i].y[ vID[0] ]));
209+ g2 = (float)sqrt(xs2 * xs2 + ys2 * ys2 + zs2 * zs2);
210+
211+ //正しい計算結果を採用する
212+ if( g1 > g2 ){
213+ xs = xs1;
214+ ys = ys1;
215+ zs = zs1;
216+ g = g1;
207217 }
218+ else{
219+ xs = xs2;
220+ ys = ys2;
221+ zs = zs2;
222+ g = g2;
223+ }
208224
209225 //法線(ベクトル)を正規化
210226 data[i].material[j].vx = xs / g;
--- trunk/collision.cpp (revision 92)
+++ trunk/collision.cpp (revision 93)
@@ -956,7 +956,7 @@
956956 }
957957
958958 //点(球体の中心)とレイの最短距離を求める
959- MinDist = DistancePosRay(s_x, s_y, s_z, RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, maxDist);
959+ MinDist = DistancePosRay(s_x, s_y, s_z, RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z);
960960
961961 if( MinDist <= s_r ){
962962 RayDist = sqrt(d*d - MinDist*MinDist); //(レイ始点から)点に最も近づく距離
@@ -1135,7 +1135,7 @@
11351135 d = sqrt(x*x + z*z);
11361136
11371137 //点(円柱の中心)とレイの最短距離を求める
1138- cMinDist = DistancePosRay(c_x, 0.0f, c_z, RayPos_x, 0.0f, RayPos_z, RayDir_x, 0.0f, RayDir_z, maxDist);
1138+ cMinDist = DistancePosRay(c_x, 0.0f, c_z, RayPos_x, 0.0f, RayPos_z, RayDir_x, 0.0f, RayDir_z);
11391139
11401140 //最短距離が半径より離れている時点で当たらない
11411141 if( cMinDist > c_r ){
@@ -1231,28 +1231,37 @@
12311231 //! @param RayDir_x レイのベクトルを指定する X成分
12321232 //! @param RayDir_y レイのベクトルを指定する Y成分
12331233 //! @param RayDir_z レイのベクトルを指定する Z成分
1234-//! @param maxDist 判定を行う最大距離
12351234 //! @return 最短距離
12361235 //! @warning RayPos(始点)と RayDir(ベクトル)を間違えないこと。
1237-float DistancePosRay(float Pos_x, float Pos_y, float Pos_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float maxDist)
1236+//! @attention レイの方向は考慮されますが、レイの長さは考慮されません。
1237+float DistancePosRay(float Pos_x, float Pos_y, float Pos_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z)
12381238 {
12391239 float x1, y1, z1;
12401240 float x2, y2, z2;
12411241 float x3, y3, z3;
1242+ float Dot;
12421243
12431244 x1 = Pos_x - RayPos_x;
12441245 y1 = Pos_y - RayPos_y;
12451246 z1 = Pos_z - RayPos_z;
1246- x2 = RayDir_x * maxDist;
1247- y2 = RayDir_y * maxDist;
1248- z2 = RayDir_z * maxDist;
1247+ x2 = RayDir_x;
1248+ y2 = RayDir_y;
1249+ z2 = RayDir_z;
12491250
1251+ //内積
1252+ Dot = x1 * x2 + y1 * y2 + z1 * z2;
1253+
1254+ //レイのベクトルが逆方向なら
1255+ if( Dot < 0.0f ){
1256+ return sqrt(x1*x1 + y1*y1 + z1*z1);
1257+ }
1258+
12501259 //外積
12511260 x3 = y1 * z2 - z1 * y2;
12521261 y3 = z1 * x2 - x1 * z2;
12531262 z3 = x1 * y2 - y1 * x2;
12541263
1255- return sqrt(x3*x3 + y3*y3 + z3*z3) / maxDist;
1264+ return sqrt(x3*x3 + y3*y3 + z3*z3) / sqrt(RayDir_x*RayDir_x + RayDir_y*RayDir_y + RayDir_z*RayDir_z);
12561265 }
12571266
12581267 //! @brief 線分と線分の当たり判定(2D)