| 1 |
#include "stdafx.h" |
| 2 |
#include "CRailWay.h" |
| 3 |
#include "CTrain.h" |
| 4 |
#include "CTrainGroup.h" |
| 5 |
#include "CTrainSetCurve.h" |
| 6 |
#include "CRailPlugin.h" |
| 7 |
#include "CTrainPlugin.h" |
| 8 |
|
| 9 |
// 関数宣言 |
| 10 |
void *ReplaceAdr(void *); |
| 11 |
|
| 12 |
// 外部グローバル |
| 13 |
extern CScene *g_Scene; |
| 14 |
extern map<void *, void *> g_AddressMap; |
| 15 |
|
| 16 |
/* |
| 17 |
* コンストラクタ |
| 18 |
*/ |
| 19 |
CAxlePosture::CAxlePosture( |
| 20 |
CAxleObject *axle, // 車軸 |
| 21 |
CTrain *train, // 車輌 |
| 22 |
bool term // 端フラグ |
| 23 |
){ |
| 24 |
m_Axle = axle; |
| 25 |
m_Train = train; |
| 26 |
m_Rotation = m_Distance = 0.0f; |
| 27 |
m_Terminate = term; |
| 28 |
m_Rail = NULL; |
| 29 |
} |
| 30 |
|
| 31 |
/* |
| 32 |
* 姿勢設定 |
| 33 |
*/ |
| 34 |
void CAxlePosture::SetPosture( |
| 35 |
VEC3 pos, // 座標 |
| 36 |
VEC3 dir, // dir |
| 37 |
VEC3 up, // up |
| 38 |
CRailWay *way // レール |
| 39 |
){ |
| 40 |
m_Pos = pos; |
| 41 |
m_Dir = dir; |
| 42 |
m_Up = up; |
| 43 |
V3NormAxis(&m_Right, &m_Up, &m_Dir); |
| 44 |
m_Rail = way; |
| 45 |
if(m_Terminate) m_Train->ToggleSetting(); |
| 46 |
} |
| 47 |
|
| 48 |
/* |
| 49 |
* 前後位置取得 |
| 50 |
*/ |
| 51 |
float CAxlePosture::GetZPos(){ |
| 52 |
return m_Axle->m_Coord.x; |
| 53 |
} |
| 54 |
|
| 55 |
/* |
| 56 |
* 姿勢適用 |
| 57 |
*/ |
| 58 |
void CAxlePosture::Apply(){ |
| 59 |
m_Axle->SetPosture(m_Pos, m_Dir, m_Up, m_Rotation); |
| 60 |
} |
| 61 |
|
| 62 |
/* |
| 63 |
* 車軸回転 |
| 64 |
*/ |
| 65 |
void CAxlePosture::Rotate( |
| 66 |
float dist, // 回転数 |
| 67 |
bool rev // 逆転フラグ |
| 68 |
){ |
| 69 |
m_Rotation += m_Axle->CalcRotation(rev ? -dist : dist); |
| 70 |
m_Rotation -= floor(m_Rotation); |
| 71 |
float tmp = m_Distance; |
| 72 |
m_Distance += dist; |
| 73 |
if(m_Axle && m_Axle->m_WheelSound && m_Rail->GetScene()==g_Scene){ |
| 74 |
CRailPlugin *rpi = m_Rail->GetRailPlugin(); |
| 75 |
if(rpi) rpi->PlayWheelSound(tmp, m_Distance, m_Pos); |
| 76 |
} |
| 77 |
} |
| 78 |
|
| 79 |
//////////////////////////////////////////////////////////////////////////////// |
| 80 |
//////////////////////////////////////////////////////////////////////////////// |
| 81 |
|
| 82 |
/* |
| 83 |
* コンストラクタ |
| 84 |
*/ |
| 85 |
CTrainSetBuffer::CTrainSetBuffer( |
| 86 |
float sumlen, // 積算距離 |
| 87 |
bool rev, // 反転フラグ |
| 88 |
CAxlePosture *ap // 姿勢バッファ |
| 89 |
){ |
| 90 |
m_SumLen = sumlen; |
| 91 |
m_Reverse = rev; |
| 92 |
m_Posture = ap; |
| 93 |
} |
| 94 |
|
| 95 |
//////////////////////////////////////////////////////////////////////////////// |
| 96 |
//////////////////////////////////////////////////////////////////////////////// |
| 97 |
|
| 98 |
/* |
| 99 |
* コンストラクタ |
| 100 |
*/ |
| 101 |
CGroupEndLocator::CGroupEndLocator(){ |
| 102 |
m_Side = 0; |
| 103 |
m_Type = 0; |
| 104 |
m_Offset = 0.0f; |
| 105 |
m_SetRail = NULL; |
| 106 |
m_Group = NULL; |
| 107 |
} |
| 108 |
|
| 109 |
/* |
| 110 |
* コンストラクタ |
| 111 |
*/ |
| 112 |
CGroupEndLocator::CGroupEndLocator( |
| 113 |
int side, // サイド |
| 114 |
float ofs, // オフセット |
| 115 |
CRailWay *way, // 設置レール |
| 116 |
CTrainGroup *group // 編成 |
| 117 |
){ |
| 118 |
m_Side = side; |
| 119 |
m_Type = 0; |
| 120 |
m_Offset = ofs; |
| 121 |
m_SetRail = way; |
| 122 |
m_Group = group; |
| 123 |
} |
| 124 |
|
| 125 |
/* |
| 126 |
* レールにセット |
| 127 |
*/ |
| 128 |
void CGroupEndLocator::Attach( |
| 129 |
int type // 探索子フラグ |
| 130 |
){ |
| 131 |
m_Type = type; |
| 132 |
if(m_SetRail) m_SetRail->m_GroupEnd.push_back(this); |
| 133 |
// else Dialog("ERROR@CGroupEndLocator::Attach"); |
| 134 |
} |
| 135 |
|
| 136 |
/* |
| 137 |
* レールから解除 |
| 138 |
*/ |
| 139 |
void CGroupEndLocator::Detach(){ |
| 140 |
if(m_SetRail){ |
| 141 |
int before = m_SetRail->m_GroupEnd.size(); |
| 142 |
m_SetRail->m_GroupEnd.remove(this); |
| 143 |
int after = m_SetRail->m_GroupEnd.size(); |
| 144 |
// if(before==after) Dialog("ERROR@CGroupEndLocator::Detach"); |
| 145 |
} |
| 146 |
} |
| 147 |
|
| 148 |
/* |
| 149 |
* 進行方向取得 (m_Side || !m_Side) |
| 150 |
*/ |
| 151 |
int CGroupEndLocator::GetDirection(){ |
| 152 |
switch(m_Type){ |
| 153 |
case 0: return m_Group->IsReverse() ? !m_Side : m_Side; |
| 154 |
case 1: return m_Group->IsReverse() ? m_Side : !m_Side; |
| 155 |
case 2: return m_Side; |
| 156 |
} |
| 157 |
return 0; |
| 158 |
} |
| 159 |
|
| 160 |
/* |
| 161 |
* アドレス復元 |
| 162 |
*/ |
| 163 |
void CGroupEndLocator::RestoreAddress(){ |
| 164 |
m_SetRail = (CRailWay *)ReplaceAdr(m_SetRail); |
| 165 |
} |
| 166 |
|
| 167 |
/* |
| 168 |
* 読込 |
| 169 |
*/ |
| 170 |
char *CGroupEndLocator::Read( |
| 171 |
char *str, // 対象文字列 |
| 172 |
char *pref // プレフィックス |
| 173 |
){ |
| 174 |
char *eee; |
| 175 |
if(!(str = BeginBlock(str, pref))) return NULL; |
| 176 |
void *oldadr; |
| 177 |
if(!(str = AsgnPointer(eee = str, "Address", &oldadr))) throw CSynErr(eee); |
| 178 |
g_AddressMap[oldadr] = this; |
| 179 |
if(!(str = Assignment(eee = str, "Location"))) throw CSynErr(eee); |
| 180 |
if(!(str = ConstInteger(eee = str, &m_Side))) throw CSynErr(eee); |
| 181 |
if(!(str = Character2(eee = str, ','))) throw CSynErr(eee); |
| 182 |
if(!(str = ConstFloat(eee = str, &m_Offset))) throw CSynErr(eee); |
| 183 |
if(!(str = Character2(eee = str, ','))) throw CSynErr(eee); |
| 184 |
if(!(str = HexPointer(eee = str, (void **)&m_SetRail))) throw CSynErr(eee); |
| 185 |
if(!(str = Character2(eee = str, ';'))) throw CSynErr(eee); |
| 186 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 187 |
return str; |
| 188 |
} |
| 189 |
|
| 190 |
/* |
| 191 |
* 保存 |
| 192 |
*/ |
| 193 |
void CGroupEndLocator::Save( |
| 194 |
FILE *df, // ファイル |
| 195 |
char *ind, // インデント |
| 196 |
char *pref // プレフィックス |
| 197 |
){ |
| 198 |
fprintf(df, "%s%s{\n", ind, pref); |
| 199 |
fprintf(df, "%s\tAddress = %p;\n", ind, this); |
| 200 |
fprintf(df, "%s\tLocation = %d, %f, %p;\n", ind, m_Side, m_Offset, m_SetRail); |
| 201 |
fprintf(df, "%s}\n", ind); |
| 202 |
} |
| 203 |
|
| 204 |
//////////////////////////////////////////////////////////////////////////////// |
| 205 |
//////////////////////////////////////////////////////////////////////////////// |
| 206 |
|
| 207 |
/* |
| 208 |
* コンストラクタ |
| 209 |
*/ |
| 210 |
CTrainSetCurve::CTrainSetCurve( |
| 211 |
CRailPlugin *rpi, // レールプラグイン |
| 212 |
CTiePlugin *tpi, // 枕木プラグイン |
| 213 |
CGirderPlugin *gpi, // 橋桁プラグイン |
| 214 |
bool rev, // 逆方向フラグ |
| 215 |
CGroupEndLocator loc, // 設置位置 |
| 216 |
CGroupEndLocator *tail, // 終端格納先 |
| 217 |
ITrainSetBuffer *icur, // 現在位置 |
| 218 |
ITrainSetBuffer *iend // 終了位置 |
| 219 |
): |
| 220 |
CRailTraceCurve(rpi, tpi, gpi, NULL) // 基本クラス |
| 221 |
{ |
| 222 |
m_Reverse = rev; |
| 223 |
m_Location = loc; |
| 224 |
m_Tail = tail; |
| 225 |
m_Current = icur; |
| 226 |
m_End = iend; |
| 227 |
} |
| 228 |
|
| 229 |
/* |
| 230 |
* トレース完了 |
| 231 |
*/ |
| 232 |
void CTrainSetCurve::FinishTrace( |
| 233 |
VEC3 &pos1, VEC3 &right1, VEC3 &up1, VEC3 &dir1, // 始点 |
| 234 |
VEC3 &pos2, VEC3 &right2, VEC3 &up2, VEC3 &dir2, // 終点 |
| 235 |
float sumlen, float seglen, // 積算距離・セグメント距離 |
| 236 |
CRailSplitter &splitter // 分割子 |
| 237 |
){ |
| 238 |
ITrainSetBuffer &cur = *m_Current; |
| 239 |
if(cur==*m_End) return; |
| 240 |
while(true){ |
| 241 |
float tmp = (m_Reverse ? -cur->m_SumLen : cur->m_SumLen)+m_Location.m_Offset; |
| 242 |
float tmp2 = tmp-sumlen; |
| 243 |
if(seglen<tmp2) return; |
| 244 |
// if(tmp2<0.0f) Dialog("Calculation Error"); |
| 245 |
float q2 = tmp2/seglen, q1 = 1.0f-q2; |
| 246 |
VEC3 td = q1*dir1+q2*dir2; |
| 247 |
cur->SetPosture(q1*pos1+q2*pos2+0.5f*seglen*q1*q2*(dir1-dir2), |
| 248 |
m_Reverse ? td : -td, q1*up1+q2*up2, m_Location.m_SetRail); |
| 249 |
if(m_Reverse) cur--; else cur++; |
| 250 |
if(cur==*m_End){ |
| 251 |
m_Tail->m_Side = m_Location.m_Side; |
| 252 |
m_Tail->m_Offset = tmp; |
| 253 |
m_Tail->m_SetRail = m_Location.m_SetRail; |
| 254 |
return; |
| 255 |
} |
| 256 |
} |
| 257 |
} |