| 1 |
#include "stdafx.h" |
| 2 |
#include "CRailSplitCurve.h" |
| 3 |
#include "CRailDumpCurve.h" |
| 4 |
#include "CLineBuildCurve.h" |
| 5 |
#include "CRailDetectCurve.h" |
| 6 |
#include "CTrainSetCurve.h" |
| 7 |
#include "CRailConnector.h" |
| 8 |
#include "CRailWay.h" |
| 9 |
#include "CTrainGroup.h" |
| 10 |
#include "CStation.h" |
| 11 |
#include "CScene.h" |
| 12 |
#include "CRailPlugin.h" |
| 13 |
#include "CTiePlugin.h" |
| 14 |
#include "CGirderPlugin.h" |
| 15 |
#include "CPierPlugin.h" |
| 16 |
#include "CLinePlugin.h" |
| 17 |
#include "CPolePlugin.h" |
| 18 |
#include "CSkinPlugin.h" |
| 19 |
#include "CRailEditMode.h" |
| 20 |
|
| 21 |
#define EXTEND_RAIL 0 // 延長設置 |
| 22 |
|
| 23 |
// 内部定数 |
| 24 |
const float RAIL_SEG_MIN = 4.0f; // レール分割最小値 |
| 25 |
const float WARP_DRAW_LEN = 0.1f; // ワープ表示長さ |
| 26 |
const float POINT_DEC_MIN = 5.0f; // ポイント左右決定最小距離 |
| 27 |
|
| 28 |
// 外部グローバル |
| 29 |
extern bool g_ShowWarpSelect; |
| 30 |
extern D3DCOLOR g_ColorSelect[]; |
| 31 |
extern CDetectInfo g_StationPlatformParentDetectInfo; |
| 32 |
|
| 33 |
// 内部グローバル |
| 34 |
bool g_MultiTrackDummy = false; |
| 35 |
int g_DummyTrackNum; |
| 36 |
float g_DummyTrackInterval; |
| 37 |
CGroupEndLocator g_HitTrainGroup; // 衝突列車代入先 |
| 38 |
map<std::string, CTrainGroup *> g_RailBlockMap; // 閉塞情報 |
| 39 |
|
| 40 |
/* |
| 41 |
* 動くレールの親オブジェクト情報 |
| 42 |
*/ |
| 43 |
class CRailWayParentLink{ |
| 44 |
friend class CRailWay; |
| 45 |
private: |
| 46 |
CDetectInfo m_DetectInfo; // 親オブジェクト |
| 47 |
list<CRailSplitter> m_SplitList; // 分割点リスト |
| 48 |
}; |
| 49 |
|
| 50 |
// static メンバ |
| 51 |
CRailWay **CRailWay::ms_Root = NULL; |
| 52 |
float CRailWay::ms_MinDist; |
| 53 |
CRailWayLink CRailWay::ms_Detect; |
| 54 |
|
| 55 |
/* |
| 56 |
* コンストラクタ (読込用) |
| 57 |
*/ |
| 58 |
CRailWay::CRailWay(){ |
| 59 |
m_OldAdr = NULL; |
| 60 |
m_Selected = 0; |
| 61 |
m_Parent = NULL; |
| 62 |
m_Platform = NULL; |
| 63 |
m_BuildLine = true; |
| 64 |
m_MultiTrackDummy = false; |
| 65 |
m_DummyTrackNum = 0; |
| 66 |
m_DummyTrackInterval = 0.0f; |
| 67 |
m_WarpDummy = false; |
| 68 |
m_SpeedLimit = -1; |
| 69 |
m_Scene = g_Scene; |
| 70 |
m_RailPlugin = NULL; |
| 71 |
m_TiePlugin = NULL; |
| 72 |
m_GirderPlugin = NULL; |
| 73 |
m_PierPlugin = NULL; |
| 74 |
m_LinePlugin = NULL; |
| 75 |
m_PolePlugin = NULL; |
| 76 |
m_PierPos = m_PolePos = 0.0f; |
| 77 |
m_SegLen = -1.0f; |
| 78 |
m_Next = NULL; |
| 79 |
} |
| 80 |
|
| 81 |
/* |
| 82 |
* コンストラクタ |
| 83 |
*/ |
| 84 |
CRailWay::CRailWay( |
| 85 |
CRailConnectorLink &link1, // 始点 |
| 86 |
CRailConnectorLink &link2, // 終点 |
| 87 |
CRailPlugin *rpi, // レールプラグイン |
| 88 |
CTiePlugin *tpi, // 枕木プラグイン |
| 89 |
CGirderPlugin *gpi, // 橋桁プラグイン |
| 90 |
CPierPlugin *ipi, // 橋脚プラグイン |
| 91 |
CLinePlugin *lpi, // 架線プラグイン |
| 92 |
CPolePlugin *ppi, // 架線柱プラグイン |
| 93 |
list<CRailSplitter> *splist // 繋ぎ変え元リスト |
| 94 |
){ |
| 95 |
m_OldAdr = NULL; |
| 96 |
m_Selected = 0; |
| 97 |
m_Parent = NULL; |
| 98 |
m_Platform = NULL; |
| 99 |
m_BuildLine = false; |
| 100 |
if(m_MultiTrackDummy = g_MultiTrackDummy){ |
| 101 |
m_DummyTrackNum = g_DummyTrackNum; |
| 102 |
m_DummyTrackInterval = g_DummyTrackInterval; |
| 103 |
}else{ |
| 104 |
m_DummyTrackNum = 0; |
| 105 |
m_DummyTrackInterval = 0.0f; |
| 106 |
} |
| 107 |
m_WarpDummy = false; |
| 108 |
m_SpeedLimit = -1; |
| 109 |
m_Link[0] = link1; |
| 110 |
m_Link[1] = link2; |
| 111 |
m_Scene = g_Scene; |
| 112 |
m_RailPlugin = rpi; |
| 113 |
m_TiePlugin = tpi; |
| 114 |
m_GirderPlugin = gpi; |
| 115 |
m_PierPlugin = ipi; |
| 116 |
m_LinePlugin = lpi; |
| 117 |
m_PolePlugin = ppi; |
| 118 |
m_PierPos = m_PolePos = 0.0f; |
| 119 |
m_SegLen = -1.0f; |
| 120 |
if(splist){ |
| 121 |
AddSplitter(m_Link[0].GetSplitter(true)); |
| 122 |
m_SplitList.splice(m_SplitList.end(), *splist, splist->begin(), splist->end()); |
| 123 |
SetMapTemp(); |
| 124 |
} |
| 125 |
m_Next = *ms_Root; |
| 126 |
*ms_Root = this; |
| 127 |
} |
| 128 |
|
| 129 |
/* |
| 130 |
* デストラクタ |
| 131 |
*/ |
| 132 |
CRailWay::~CRailWay(){ |
| 133 |
DELETE_V(m_Parent); |
| 134 |
DELETE_V(m_Next); |
| 135 |
} |
| 136 |
|
| 137 |
/* |
| 138 |
* 親オブジェクト設定 |
| 139 |
*/ |
| 140 |
void CRailWay::SetParent(CDetectInfo *d_info){ |
| 141 |
DELETE_V(m_Parent); |
| 142 |
if(d_info){ |
| 143 |
m_Parent = new CRailWayParentLink; |
| 144 |
m_Parent->m_DetectInfo = *d_info; |
| 145 |
m_Parent->m_SplitList = m_SplitList; |
| 146 |
} |
| 147 |
} |
| 148 |
|
| 149 |
/* |
| 150 |
* ワープ設定 |
| 151 |
*/ |
| 152 |
void CRailWay::SetWarpDummy(){ |
| 153 |
m_BuildLine = true; |
| 154 |
m_WarpDummy = true; |
| 155 |
m_Scene = NULL; |
| 156 |
Stabilize(); |
| 157 |
} |
| 158 |
|
| 159 |
/* |
| 160 |
* リンク可能か調べる |
| 161 |
*/ |
| 162 |
bool CRailWay::IsLinkable( |
| 163 |
int s, // サイド |
| 164 |
VEC3 &pos // 座標 |
| 165 |
){ |
| 166 |
CRailConnectorLink& rlink = m_Link[s]; |
| 167 |
if(pos!=rlink.GetPos()) return true; |
| 168 |
CRailWayLink *link = rlink.m_Link->m_Link[!rlink.m_Side]; |
| 169 |
int i; |
| 170 |
for(i = 0; i<2; i++) if(link[i].m_Link && !link[i].m_Link->m_Scene) return false; |
| 171 |
return !link[0].m_Link || !link[1].m_Link; |
| 172 |
} |
| 173 |
|
| 174 |
/* |
| 175 |
* セグメント長取得 |
| 176 |
*/ |
| 177 |
float CRailWay::GetSegLen(){ |
| 178 |
if(m_SegLen>=0.0f) return m_SegLen; |
| 179 |
m_SegLen = 0.0f; |
| 180 |
if(m_WarpDummy) return 0.0f; |
| 181 |
IRailSplitter irs = m_SplitList.begin(); |
| 182 |
VEC3 tpos = (irs++)->m_Pos; |
| 183 |
for(; irs!=m_SplitList.end(); irs++){ |
| 184 |
VEC3 npos = irs->m_Pos; |
| 185 |
m_SegLen += V3Len(&(npos-tpos)); |
| 186 |
tpos = npos; |
| 187 |
} |
| 188 |
return m_SegLen; |
| 189 |
} |
| 190 |
|
| 191 |
/* |
| 192 |
* 確定 |
| 193 |
*/ |
| 194 |
void CRailWay::Stabilize(){ |
| 195 |
m_BuildLine = true; |
| 196 |
m_Link[0].Connect(R2L(CreateLink(0))); |
| 197 |
m_Link[1].Connect(R2L(CreateLink(1))); |
| 198 |
// コンストラクタでやってるので不要 |
| 199 |
// if(m_RailPlugin) m_RailPlugin->CopyMapTemp(&m_RailMapV); |
| 200 |
// if(m_TiePlugin) m_TiePlugin->CopyMapTemp(&m_TieMapV); |
| 201 |
// if(m_GirderPlugin) m_GirderPlugin->CopyMapTemp(&m_GirderMapV); |
| 202 |
if(m_PierPlugin) m_PierPos = m_PierPlugin->GetPierPos(); |
| 203 |
if(m_LinePlugin) m_LinePlugin->CopyMapTemp(m_LineMapV); |
| 204 |
} |
| 205 |
|
| 206 |
/* |
| 207 |
* 分割連結点取得 |
| 208 |
*/ |
| 209 |
CRailConnectorLink CRailWay::SplitLink( |
| 210 |
CRailLinkTemp *spl, // 分割点 |
| 211 |
CRailWay **wadr, // 接続レール格納先 |
| 212 |
IRailSplitter sit // splice 位置 |
| 213 |
){ |
| 214 |
int s = spl->m_Side; |
| 215 |
if(spl->m_Pos==m_Link[s].GetPos()){ |
| 216 |
int cs = m_Link[s].m_Side; |
| 217 |
CRailConnector *con = m_Link[s].m_Link; |
| 218 |
CRailWayLink *link = con->m_Link[!cs]; |
| 219 |
if(wadr) *wadr = this; |
| 220 |
return con->CreateLink(!cs, link[0].m_Link ? 1 : 0); |
| 221 |
} |
| 222 |
CRailConnector *con = new CRailConnector(spl->m_Pos, R2L(s ? spl->m_Dir : -spl->m_Dir)); |
| 223 |
con->Stabilize(spl->m_Up); |
| 224 |
CRailConnectorLink cl1 = con->CreateLink(1, 0), cl2 = m_Link[1]; |
| 225 |
m_Link[1] = con->CreateLink(0, 0); |
| 226 |
m_Link[1].Connect(R2L(CreateLink(1))); |
| 227 |
m_SegLen = -1.0f; |
| 228 |
//GetSegLen(); CopyMapTemp で求めるので不要 |
| 229 |
list<CRailSplitter> splist; |
| 230 |
IRailSplitter irs = m_SplitList.begin(); |
| 231 |
bool splfound = false; |
| 232 |
for(; irs!=m_SplitList.end(); irs++){ |
| 233 |
if(spl->m_Pos==irs->m_Pos){ |
| 234 |
splfound = true; |
| 235 |
sit = ++irs; |
| 236 |
break; |
| 237 |
} |
| 238 |
} |
| 239 |
splist.splice(splist.begin(), m_SplitList, sit, m_SplitList.end()); |
| 240 |
if(!splfound) m_SplitList.push_back(m_Link[1].GetSplitter(false)); |
| 241 |
CopyMapTemp(1); |
| 242 |
CRailWay *way = new CRailWay(cl1, cl2, m_RailPlugin, m_TiePlugin, |
| 243 |
m_GirderPlugin, m_PierPlugin, m_LinePlugin, m_PolePlugin, &splist); |
| 244 |
way->m_MultiTrackDummy = m_MultiTrackDummy; |
| 245 |
way->m_DummyTrackNum = m_DummyTrackNum; |
| 246 |
way->m_DummyTrackInterval = m_DummyTrackInterval; |
| 247 |
way->GetSegLen(); |
| 248 |
way->Stabilize(); |
| 249 |
if(way->m_Platform = m_Platform) m_Platform->AddRailWay(way); |
| 250 |
way->m_RailBlock = m_RailBlock; |
| 251 |
way->m_SpeedLimit = m_SpeedLimit; |
| 252 |
m_PoleList.sort(); |
| 253 |
IPolePos ippo = m_PoleList.begin(); |
| 254 |
for(; ippo!=m_PoleList.end(); ippo++){ |
| 255 |
if(ippo->m_Pos>=m_SegLen){ |
| 256 |
IPolePos ippo2 = ippo; |
| 257 |
for(; ippo2!=m_PoleList.end(); ippo2++) ippo2->m_Pos -= m_SegLen; |
| 258 |
way->m_PoleList.splice(way->m_PoleList.begin(), m_PoleList, ippo, m_PoleList.end()); |
| 259 |
break; |
| 260 |
} |
| 261 |
} |
| 262 |
m_PierList.sort(); |
| 263 |
IPierPos ippi = m_PierList.begin(); |
| 264 |
for(; ippi!=m_PierList.end(); ippi++){ |
| 265 |
if(ippi->m_Pos>=m_SegLen){ |
| 266 |
IPierPos ippi2 = ippi; |
| 267 |
for(; ippi2!=m_PierList.end(); ippi2++) ippi2->m_Pos -= m_SegLen; |
| 268 |
way->m_PierList.splice(way->m_PierList.begin(), m_PierList, ippi, m_PierList.end()); |
| 269 |
break; |
| 270 |
} |
| 271 |
} |
| 272 |
float len0 = GetSegLen(), len1 = way->GetSegLen(); |
| 273 |
IPGroupEndLocator ipge = m_GroupEnd.begin(); |
| 274 |
while(ipge!=m_GroupEnd.end()){ |
| 275 |
if((*ipge)->m_Side ? (*ipge)->m_Offset<len1 : (*ipge)->m_Offset>len0){ |
| 276 |
(*ipge)->m_SetRail = way; |
| 277 |
if(!(*ipge)->m_Side) (*ipge)->m_Offset -= len0; |
| 278 |
way->m_GroupEnd.push_back(*ipge); |
| 279 |
ipge = m_GroupEnd.erase(ipge); |
| 280 |
}else{ |
| 281 |
ipge++; |
| 282 |
} |
| 283 |
} |
| 284 |
if(wadr) *wadr = spl->m_Side ? this : way; |
| 285 |
return con->CreateLink(s, 1); |
| 286 |
} |
| 287 |
|
| 288 |
/* |
| 289 |
* 選択部分を分離 |
| 290 |
*/ |
| 291 |
void CRailWay::SplitSelect(){ |
| 292 |
IRailSplitter irs = ++m_SplitList.begin(), spl = irs; |
| 293 |
int sel = (irs++)->m_Selected&2; |
| 294 |
for(; irs!=m_SplitList.end(); irs++){ |
| 295 |
if(sel!=(irs->m_Selected&2)){ |
| 296 |
CRailWay *newway; |
| 297 |
SplitLink(&CRailLinkTemp(0, 0.0f, |
| 298 |
spl->m_Pos, R2L(-spl->m_Right), spl->m_Up, R2L(-spl->m_Dir), |
| 299 |
NULL, IRailSplitter()), &newway, IRailSplitter()); |
| 300 |
newway->SplitSelect(); |
| 301 |
return; |
| 302 |
} |
| 303 |
spl = irs; |
| 304 |
} |
| 305 |
} |
| 306 |
|
| 307 |
/* |
| 308 |
* 選択されていればリストから削除 |
| 309 |
*/ |
| 310 |
CRailWay *CRailWay::Delete(){ |
| 311 |
if(m_GroupEnd.size() |
| 312 |
|| m_Link[0].m_Link && m_Link[0].m_Link->m_User |
| 313 |
|| m_Link[1].m_Link && m_Link[1].m_Link->m_User) return this; |
| 314 |
if(m_WarpDummy){ |
| 315 |
if(!(m_Selected&2) && m_Link[0].GetLinkCount()>1 |
| 316 |
&& m_Link[1].GetLinkCount()>1) return this; |
| 317 |
}else{ |
| 318 |
if(!(m_SplitList.rbegin()->m_Selected&2)) return this; |
| 319 |
if(m_Platform) m_Platform->DeleteRailWay(this); |
| 320 |
while(m_PoleList.size()){ |
| 321 |
if(m_PoleList.begin()->m_Multi){ |
| 322 |
m_PoleList.pop_front(); |
| 323 |
}else{ |
| 324 |
CPole *pole = m_PoleList.begin()->m_Link; |
| 325 |
m_PoleList.pop_front(); |
| 326 |
m_Scene->DeletePole(pole); |
| 327 |
} |
| 328 |
} |
| 329 |
while(m_PierList.size()){ |
| 330 |
CPier *pier = m_PierList.begin()->m_Link; |
| 331 |
m_PierList.pop_front(); |
| 332 |
m_Scene->DeletePier(pier); |
| 333 |
} |
| 334 |
} |
| 335 |
m_Link[0].Disconnect(); |
| 336 |
m_Link[1].Disconnect(); |
| 337 |
CRailWay *next = m_Next; |
| 338 |
m_Next = NULL; |
| 339 |
delete this; |
| 340 |
return next; |
| 341 |
} |
| 342 |
|
| 343 |
/* |
| 344 |
* 別のレールを接続 |
| 345 |
*/ |
| 346 |
void CRailWay::ConnectRailWay(int my_side, CRailWay *o_rail, int o_side, CScene *scene){ |
| 347 |
CRailConnectorLink& rlink = m_Link[my_side]; |
| 348 |
CRailConnectorLink& orlink = o_rail->m_Link[o_side]; |
| 349 |
CRailWayLink *link = rlink.m_Link->m_Link[!rlink.m_Side]; |
| 350 |
if(link[0].m_Link==o_rail || link[1].m_Link==o_rail) return; |
| 351 |
if(rlink.m_Link->GetUser() || orlink.m_Link->GetUser()) return; |
| 352 |
scene->ResetRailWayRoot(); |
| 353 |
CRailSplitter spl = rlink.GetSplitter(false); |
| 354 |
CRailConnector *con = new CRailConnector(spl.m_Pos, spl.m_Dir); |
| 355 |
con->Stabilize(spl.m_Up); |
| 356 |
rlink.Disconnect(); |
| 357 |
orlink.Disconnect(); |
| 358 |
rlink = con->CreateLink(0, 0); |
| 359 |
rlink.Connect(R2L(CreateLink(my_side))); |
| 360 |
orlink = con->CreateLink(1, 0); |
| 361 |
orlink.Connect(R2L(o_rail->CreateLink(o_side))); |
| 362 |
scene->DeleteRailConnector(); |
| 363 |
g_Scene->ResetRailConnectorRoot(); |
| 364 |
// Dialog("CONNECTED!"); |
| 365 |
} |
| 366 |
|
| 367 |
/* |
| 368 |
* 別のレールに分岐 |
| 369 |
*/ |
| 370 |
void CRailWay::BranchRailWay(int my_side, CRailWay *o_rail, int o_side, CScene *scene){ |
| 371 |
CRailConnectorLink& rlink = m_Link[my_side]; |
| 372 |
CRailConnectorLink& orlink = o_rail->m_Link[o_side]; |
| 373 |
CRailWayLink *link = rlink.m_Link->m_Link[!rlink.m_Side]; |
| 374 |
if(link[0].m_Link==o_rail || link[1].m_Link==o_rail) return; |
| 375 |
if(link[0].m_Link && link[1].m_Link) return; |
| 376 |
if(rlink.m_Link->GetUser() || orlink.m_Link->GetUser()) return; |
| 377 |
scene->ResetRailWayRoot(); |
| 378 |
CRailConnector *con = rlink.m_Link; |
| 379 |
orlink.Disconnect(); |
| 380 |
orlink = con->CreateLink(!rlink.m_Side, !!link[0].m_Link); |
| 381 |
orlink.Connect(R2L(o_rail->CreateLink(o_side))); |
| 382 |
scene->DeleteRailConnector(); |
| 383 |
g_Scene->ResetRailConnectorRoot(); |
| 384 |
// Dialog("BRANCHED!"); |
| 385 |
} |
| 386 |
|
| 387 |
/* |
| 388 |
* レールの接続を解除 |
| 389 |
*/ |
| 390 |
void CRailWay::DisconnectRailWay(int my_side, CScene *scene){ |
| 391 |
CRailConnectorLink& rlink = m_Link[my_side]; |
| 392 |
CRailWayLink *link = rlink.m_Link->m_Link[!rlink.m_Side]; |
| 393 |
if(!link[0].m_Link && !link[1].m_Link) return; |
| 394 |
if(rlink.m_Link->GetUser()) return; |
| 395 |
scene->ResetRailWayRoot(); |
| 396 |
CRailSplitter spl = rlink.GetSplitter(false); |
| 397 |
CRailConnector *con = new CRailConnector(spl.m_Pos, spl.m_Dir); |
| 398 |
con->Stabilize(spl.m_Up); |
| 399 |
rlink.Disconnect(); |
| 400 |
rlink = con->CreateLink(0, 0); |
| 401 |
rlink.Connect(R2L(CreateLink(my_side))); |
| 402 |
scene->DeleteRailConnector(); |
| 403 |
g_Scene->ResetRailConnectorRoot(); |
| 404 |
// Dialog("DISCONNECTED!"); |
| 405 |
} |
| 406 |
|
| 407 |
/* |
| 408 |
* 選択されていれば閉塞区間設定 |
| 409 |
*/ |
| 410 |
bool CRailWay::SetRailBlock(char *rb){ |
| 411 |
if(m_WarpDummy || m_MultiTrackDummy) return false; |
| 412 |
if(!(m_SplitList.rbegin()->m_Selected&2)) return false; |
| 413 |
m_RailBlock = rb; |
| 414 |
return true; |
| 415 |
} |
| 416 |
|
| 417 |
/* |
| 418 |
* 進入可能性チェック |
| 419 |
*/ |
| 420 |
bool CRailWay::CheckRailBlock(CTrainGroup *group){ |
| 421 |
if(IsRailBlock()){ |
| 422 |
CTrainGroup *blockuser = GetRailBlockUser(m_RailBlock); |
| 423 |
if(blockuser && blockuser!=group) return false; |
| 424 |
} |
| 425 |
return true; |
| 426 |
} |
| 427 |
|
| 428 |
/* |
| 429 |
* 選択されていれば制限速度設定 |
| 430 |
*/ |
| 431 |
bool CRailWay::SetSpeedLimit(int sl){ |
| 432 |
if(m_WarpDummy || m_MultiTrackDummy) return false; |
| 433 |
if(!(m_SplitList.rbegin()->m_Selected&2)) return false; |
| 434 |
m_SpeedLimit = sl; |
| 435 |
return true; |
| 436 |
} |
| 437 |
|
| 438 |
/* |
| 439 |
* マッピング座標セット |
| 440 |
*/ |
| 441 |
void CRailWay::SetMapTemp(){ |
| 442 |
GetSegLen(); |
| 443 |
if(m_RailPlugin){ |
| 444 |
m_RailPlugin->CopyMapTemp(m_RailMapV); |
| 445 |
m_RailPlugin->AddMapTemp(m_SegLen); |
| 446 |
} |
| 447 |
if(m_TiePlugin){ |
| 448 |
m_TiePlugin->CopyMapTemp(m_TieMapV); |
| 449 |
m_TiePlugin->AddMapTemp(m_SegLen); |
| 450 |
} |
| 451 |
if(m_GirderPlugin){ |
| 452 |
m_GirderPlugin->CopyMapTemp(m_GirderMapV); |
| 453 |
m_GirderPlugin->AddMapTemp(m_SegLen); |
| 454 |
} |
| 455 |
if(m_LinePlugin){ |
| 456 |
m_LinePlugin->CopyMapTemp(m_LineMapV); |
| 457 |
m_LinePlugin->AddMapTemp(m_SegLen); // 本当は架線の折れ線距離を計算する必要があるが… |
| 458 |
} |
| 459 |
} |
| 460 |
|
| 461 |
/* |
| 462 |
* マッピング座標コピー |
| 463 |
*/ |
| 464 |
void CRailWay::CopyMapTemp( |
| 465 |
int side // サイド |
| 466 |
){ |
| 467 |
GetSegLen(); |
| 468 |
if(side){ |
| 469 |
if(m_RailPlugin){ |
| 470 |
m_RailPlugin->SetMapTemp(m_RailMapV); |
| 471 |
m_RailPlugin->AddMapTemp(m_SegLen); |
| 472 |
} |
| 473 |
if(m_TiePlugin){ |
| 474 |
m_TiePlugin->SetMapTemp(m_TieMapV); |
| 475 |
m_TiePlugin->AddMapTemp(m_SegLen); |
| 476 |
} |
| 477 |
if(m_GirderPlugin){ |
| 478 |
m_GirderPlugin->SetMapTemp(m_GirderMapV); |
| 479 |
m_GirderPlugin->AddMapTemp(m_SegLen); |
| 480 |
} |
| 481 |
if(m_PierPlugin){ |
| 482 |
m_PierPlugin->SetPierPos(m_PierPos); |
| 483 |
m_PierPlugin->AddPierPos(m_SegLen); |
| 484 |
} |
| 485 |
if(m_LinePlugin && m_PoleList.size()){ |
| 486 |
IPolePos ippo = --m_PoleList.end(); |
| 487 |
m_LinePlugin->SetMapTemp(m_LineMapV); |
| 488 |
m_LinePlugin->SetPolePos(ippo->m_Pos); |
| 489 |
m_LinePlugin->AddPolePos(m_SegLen); |
| 490 |
} |
| 491 |
}else{ |
| 492 |
if(m_RailPlugin) m_RailPlugin->ResetMapTemp(); |
| 493 |
if(m_TiePlugin) m_TiePlugin->ResetMapTemp(); |
| 494 |
if(m_GirderPlugin) m_GirderPlugin->ResetMapTemp(); |
| 495 |
if(m_PierPlugin){ |
| 496 |
m_PierPlugin->SetPierPos(m_SegLen-m_PierPos); |
| 497 |
m_PierPlugin->AddPierPos(m_SegLen); |
| 498 |
} |
| 499 |
if(m_LinePlugin && m_PoleList.size()){ |
| 500 |
IPolePos ippo = m_PoleList.begin(); |
| 501 |
m_LinePlugin->SetMapTemp(m_LineMapV); |
| 502 |
m_LinePlugin->SetPolePos(m_SegLen-ippo->m_Pos); |
| 503 |
m_LinePlugin->AddPolePos(m_SegLen); |
| 504 |
} |
| 505 |
} |
| 506 |
} |
| 507 |
|
| 508 |
/* |
| 509 |
* マッピング座標コピー (複線橋脚・架線柱位置) |
| 510 |
*/ |
| 511 |
void CRailWay::CopyMapTempMulti( |
| 512 |
int side, // サイド |
| 513 |
float *pipos, // 橋脚位置 |
| 514 |
float *pisum, // 累積距離 |
| 515 |
int *pinum, // 橋脚数 |
| 516 |
float *popos, // 架線柱位置 |
| 517 |
float *posum, // 累積距離 |
| 518 |
int *ponum // 架線柱数 |
| 519 |
){ |
| 520 |
GetSegLen(); |
| 521 |
if(side){ |
| 522 |
if(m_PierPlugin){ |
| 523 |
*pipos += m_PierPos; |
| 524 |
*pisum += m_SegLen; |
| 525 |
(*pinum)++; |
| 526 |
} |
| 527 |
if(m_LinePlugin && m_PoleList.size()){ |
| 528 |
IPolePos ippo = --m_PoleList.end(); |
| 529 |
*popos += ippo->m_Pos; |
| 530 |
*posum += m_SegLen; |
| 531 |
(*ponum)++; |
| 532 |
} |
| 533 |
}else{ |
| 534 |
if(m_PierPlugin){ |
| 535 |
*pipos += m_SegLen-m_PierPos; |
| 536 |
*pisum += m_SegLen; |
| 537 |
(*pinum)++; |
| 538 |
} |
| 539 |
if(m_LinePlugin && m_PoleList.size()){ |
| 540 |
IPolePos ippo = m_PoleList.begin(); |
| 541 |
*popos += m_SegLen-ippo->m_Pos; |
| 542 |
*posum += m_SegLen; |
| 543 |
(*ponum)++; |
| 544 |
} |
| 545 |
} |
| 546 |
} |
| 547 |
|
| 548 |
/* |
| 549 |
* 架線柱リンクの取得 |
| 550 |
*/ |
| 551 |
CPoleLink CRailWay::GetPoleLink( |
| 552 |
int side // サイド |
| 553 |
){ |
| 554 |
GetSegLen(); |
| 555 |
if(side){ |
| 556 |
if(m_LinePlugin && m_PoleList.size()){ |
| 557 |
IPolePos ippo = m_PoleList.end(); |
| 558 |
ippo--; |
| 559 |
return CPoleLink(ippo->m_Link->CreateLink(1, ippo->m_Track)); |
| 560 |
} |
| 561 |
}else{ |
| 562 |
if(m_LinePlugin && m_PoleList.size()){ |
| 563 |
IPolePos ippo = m_PoleList.begin(); |
| 564 |
return CPoleLink(ippo->m_Link->CreateLink(0, ippo->m_Track)); |
| 565 |
} |
| 566 |
} |
| 567 |
return CPoleLink(); |
| 568 |
} |
| 569 |
|
| 570 |
/* |
| 571 |
* 架線柱をリストに追加 |
| 572 |
*/ |
| 573 |
void CRailWay::AddPole( |
| 574 |
float ofs, // 現在位置からのオフセット |
| 575 |
CPole *pole, // 架線柱 |
| 576 |
int track, // 軌道番号 |
| 577 |
bool multi // 複線用リンク |
| 578 |
){ |
| 579 |
m_PoleList.push_back(CPolePos(m_PolePos+ofs, pole, track, multi)); |
| 580 |
} |
| 581 |
|
| 582 |
/* |
| 583 |
* 架線柱をリストに追加 |
| 584 |
*/ |
| 585 |
void CRailWay::InsertPole( |
| 586 |
float ofs, // 端からのオフセット |
| 587 |
CPole *pole, // 架線柱 |
| 588 |
int track, // 軌道番号 |
| 589 |
bool multi // 複線用リンク |
| 590 |
){ |
| 591 |
IPolePos ipo = m_PoleList.begin(); |
| 592 |
while(ipo!=m_PoleList.end() && ipo->m_Pos<ofs) ipo++; |
| 593 |
m_PoleList.insert(ipo, CPolePos(ofs, pole, track, multi)); |
| 594 |
} |
| 595 |
|
| 596 |
/* |
| 597 |
* 架線柱をリストから削除 |
| 598 |
*/ |
| 599 |
void CRailWay::DeletePole( |
| 600 |
CPole *pole // 架線柱 |
| 601 |
){ |
| 602 |
IPolePos ipo = m_PoleList.begin(); |
| 603 |
while(ipo!=m_PoleList.end()){ |
| 604 |
if(ipo->m_Link==pole) ipo = m_PoleList.erase(ipo); |
| 605 |
else ipo++; |
| 606 |
} |
| 607 |
} |
| 608 |
|
| 609 |
/* |
| 610 |
* 橋脚をリストに追加 |
| 611 |
*/ |
| 612 |
void CRailWay::AddPier( |
| 613 |
float ofs, // 現在位置からのオフセット |
| 614 |
CPier *pier // 架線柱 |
| 615 |
){ |
| 616 |
m_PierList.push_back(CPierPos(m_PierPos+ofs, pier)); |
| 617 |
} |
| 618 |
|
| 619 |
/* |
| 620 |
* 橋脚をリストに追加 |
| 621 |
*/ |
| 622 |
void CRailWay::InsertPier( |
| 623 |
float ofs, // 端からのオフセット |
| 624 |
CPier *pier // 架線柱 |
| 625 |
){ |
| 626 |
IPierPos ipi = m_PierList.begin(); |
| 627 |
while(ipi!=m_PierList.end() && ipi->m_Pos<ofs) ipi++; |
| 628 |
m_PierList.insert(ipi, CPierPos(ofs, pier)); |
| 629 |
} |
| 630 |
|
| 631 |
/* |
| 632 |
* 橋脚をリストから削除 |
| 633 |
*/ |
| 634 |
void CRailWay::DeletePier( |
| 635 |
CPier *pier // 架線柱 |
| 636 |
){ |
| 637 |
IPierPos ipi = m_PierList.begin(); |
| 638 |
while(ipi!=m_PierList.end()){ |
| 639 |
if(ipi->m_Link==pier) ipi = m_PierList.erase(ipi); |
| 640 |
else ipi++; |
| 641 |
} |
| 642 |
} |
| 643 |
|
| 644 |
/* |
| 645 |
* 橋脚・架線建設 |
| 646 |
*/ |
| 647 |
void CRailWay::BuildLine( |
| 648 |
CPierPlugin *ipi, // 橋脚プラグイン |
| 649 |
CLinePlugin *lpi, // 架線プラグイン |
| 650 |
CPolePlugin *ppi // 架線柱プラグイン |
| 651 |
){ |
| 652 |
if(m_BuildLine) return; |
| 653 |
if(m_PierPlugin = ipi) m_PierPos = m_PierPlugin->GetPierPos(); |
| 654 |
m_LinePlugin = lpi; |
| 655 |
m_PolePlugin = ppi; |
| 656 |
m_BuildLine = true; |
| 657 |
bool initialsplit = false; |
| 658 |
if(!m_SplitList.size()){ |
| 659 |
initialsplit = true; |
| 660 |
AddSplitter(m_Link[0].GetSplitter(true)); |
| 661 |
CRailSplitCurve curve(m_RailPlugin, m_TiePlugin, m_GirderPlugin, this); |
| 662 |
curve.Trace( |
| 663 |
R2L(m_Link[0].GetPos()), R2L(-m_Link[0].GetRight()), R2L(m_Link[0].GetUp()), R2L(-m_Link[0].GetDir()), |
| 664 |
R2L(m_Link[1].GetPos()), R2L(m_Link[1].GetRight()), R2L(m_Link[1].GetUp()), R2L(m_Link[1].GetDir()), |
| 665 |
R2L(m_Link[0].GetPos()), R2L(-m_Link[0].GetCant()), R2L(m_Link[1].GetPos()), R2L(m_Link[1].GetCant())); |
| 666 |
} |
| 667 |
if(m_Next) m_Next->BuildLine(m_PierPlugin, m_LinePlugin, m_PolePlugin); |
| 668 |
if(initialsplit) SetMapTemp(); |
| 669 |
if(g_MultiTrackDummy){ |
| 670 |
g_MultiTrackSegment = g_MultiTrackRailList.begin(); |
| 671 |
for(; g_MultiTrackSegment!=g_MultiTrackRailList.end(); g_MultiTrackSegment++){ |
| 672 |
ILPRailWay ilpr = --g_MultiTrackSegment->end(); |
| 673 |
IPRailWay ipr = ilpr->begin(); |
| 674 |
for(; ipr!=ilpr->end(); ipr++) if(*ipr==this) goto FOUND; |
| 675 |
} |
| 676 |
FOUND:; |
| 677 |
} |
| 678 |
TraceRail(1, &CLineBuildCurve(this, m_RailPlugin, m_TiePlugin, |
| 679 |
m_GirderPlugin, m_PierPlugin, m_LinePlugin, m_PolePlugin)); |
| 680 |
if(g_PlatformInst){ |
| 681 |
m_Platform = g_PlatformInst; |
| 682 |
g_PlatformInst->AddRailWay(this); |
| 683 |
if(g_StationPlatformParentDetectInfo.GetObject()){ |
| 684 |
m_Parent = new CRailWayParentLink; |
| 685 |
m_Parent->m_DetectInfo = g_StationPlatformParentDetectInfo; |
| 686 |
m_Parent->m_SplitList = m_SplitList; |
| 687 |
} |
| 688 |
} |
| 689 |
} |
| 690 |
|
| 691 |
/* |
| 692 |
* セグメント表示 |
| 693 |
*/ |
| 694 |
void CRailWay::ShowSegment(){ |
| 695 |
int i; |
| 696 |
for(i = 0; i<2; i++){ |
| 697 |
g_SegmentObject.SetPos(m_Link[i].GetPos()); |
| 698 |
g_SegmentObject.SetDir(-m_Link[i].GetDir(), m_Link[i].GetUp()); |
| 699 |
g_SegmentObject.Render(); |
| 700 |
} |
| 701 |
} |
| 702 |
|
| 703 |
/* |
| 704 |
* 入力チェック |
| 705 |
*/ |
| 706 |
void CRailWay::ScanInput( |
| 707 |
int mode, // モード |
| 708 |
VEC3 &rect1, // 領域始点 |
| 709 |
VEC3 &rect2 // 領域終点 |
| 710 |
){ |
| 711 |
if(m_MultiTrackDummy && !g_RailEditMode->IsModeActive()) return; |
| 712 |
switch(mode){ |
| 713 |
case 0: |
| 714 |
TraceRailSplit(1, &CRailDetectCurve3D( |
| 715 |
this, m_RailPlugin, m_TiePlugin, m_GirderPlugin, rect1)); |
| 716 |
break; |
| 717 |
case 1: |
| 718 |
TraceRailSplit(1, &CRailDetectCurve2D( |
| 719 |
this, m_RailPlugin, m_TiePlugin, m_GirderPlugin, mode, rect1, rect2)); |
| 720 |
break; |
| 721 |
case 2: |
| 722 |
case 3: |
| 723 |
case 4: |
| 724 |
TraceRail(1, &CRailDetectCurve2D( |
| 725 |
this, m_RailPlugin, m_TiePlugin, m_GirderPlugin, mode, rect1, rect2)); |
| 726 |
break; |
| 727 |
case 5: |
| 728 |
if(m_MultiTrackDummy) return; |
| 729 |
CRailDetectCurve2D(this, m_RailPlugin, m_TiePlugin, m_GirderPlugin, |
| 730 |
mode, rect1, rect2).FinishTrace( |
| 731 |
R2L(m_Link[0].GetPos()), R2L(-m_Link[0].GetRight()), R2L(m_Link[0].GetUp()), R2L(-m_Link[0].GetDir()), |
| 732 |
R2L(m_Link[1].GetPos()), R2L(m_Link[1].GetRight()), R2L(m_Link[1].GetUp()), R2L(m_Link[1].GetDir()), |
| 733 |
(m_Link[0].GetLinkCount()>1 ? 0 : 1)+(m_Link[1].GetLinkCount()>1 ? 0 : 2), |
| 734 |
0.0f, *m_SplitList.begin()); |
| 735 |
break; |
| 736 |
} |
| 737 |
} |
| 738 |
|
| 739 |
/* |
| 740 |
* 入力チェック (ワープ用) |
| 741 |
*/ |
| 742 |
void CRailWay::ScanInputWarp( |
| 743 |
int mode, // モード |
| 744 |
VEC3 &rect1, // 領域始点 |
| 745 |
VEC3 &rect2 // 領域終点 |
| 746 |
){ |
| 747 |
int i; |
| 748 |
bool flag = false; |
| 749 |
for(i = 0; i<2; i++){ |
| 750 |
if(m_Link[i].m_Link->GetScene()!=g_Scene) continue; |
| 751 |
VEC3 center = m_Link[i].GetPos(); |
| 752 |
VEC3 sc = WorldToScreen(center); |
| 753 |
if(sc.z<0.0f) continue; |
| 754 |
switch(mode){ |
| 755 |
case 2: |
| 756 |
if(rect1.x<=sc.x && sc.x<=rect2.x && rect1.y<=sc.y && sc.y<=rect2.y){ |
| 757 |
m_Selected |= 1; |
| 758 |
flag = true; |
| 759 |
} |
| 760 |
if(i && !flag) m_Selected &= 2; |
| 761 |
break; |
| 762 |
case 3: |
| 763 |
if(CheckCtrl()){ |
| 764 |
m_Selected &= ~m_Selected<<1; |
| 765 |
}else{ |
| 766 |
if(CheckShift()) m_Selected |= m_Selected<<1; |
| 767 |
else m_Selected = m_Selected<<1; |
| 768 |
} |
| 769 |
m_Selected &= 2; |
| 770 |
return; // 1 回でよい |
| 771 |
case 4: |
| 772 |
float dist = V3Len(&(rect1-sc)); |
| 773 |
if(dist<DETECT_2D_MAX && (ms_MinDist<0.0f || ms_MinDist>dist)){ |
| 774 |
ms_MinDist = dist; |
| 775 |
ms_Detect = CRailWayLink(i, this); |
| 776 |
} |
| 777 |
m_Selected &= 2; |
| 778 |
break; |
| 779 |
} |
| 780 |
} |
| 781 |
} |
| 782 |
|
| 783 |
class CRailWay_TraceRail_CTempTracer{ |
| 784 |
public: |
| 785 |
template<class _II> |
| 786 |
CRailWay_TraceRail_CTempTracer(_II from, _II to, CRailTraceCurve *curve, bool rev){ |
| 787 |
float sumlen = 0.0f; |
| 788 |
bool t1 = true; |
| 789 |
CRailSplitter tspl = (from++)->Get(rev); |
| 790 |
while(true){ |
| 791 |
CRailTraceCurve::SetSplitItr(from); |
| 792 |
CRailTraceCurve::SetTerminate(t1, from==to); |
| 793 |
CRailSplitter nspl = from->Get(rev); |
| 794 |
float seglen = nspl.CalcDist(tspl); |
| 795 |
if(!curve->Confirm(tspl.m_Pos, nspl.m_Pos)) return; |
| 796 |
curve->FinishTrace(tspl.m_Pos, tspl.m_Right, tspl.m_Up, tspl.m_Dir, |
| 797 |
nspl.m_Pos, nspl.m_Right, nspl.m_Up, nspl.m_Dir, sumlen, seglen, *from); |
| 798 |
if(from==to) return; |
| 799 |
from++; |
| 800 |
sumlen += seglen; |
| 801 |
tspl = nspl; |
| 802 |
t1 = false; |
| 803 |
} |
| 804 |
} |
| 805 |
}; |
| 806 |
|
| 807 |
/* |
| 808 |
* トレース |
| 809 |
*/ |
| 810 |
void CRailWay::TraceRail( |
| 811 |
int side, // 方向 |
| 812 |
CRailTraceCurve *curve // トレーサ |
| 813 |
){ |
| 814 |
if(side) CRailWay_TraceRail_CTempTracer(m_SplitList.begin(), --m_SplitList.end(), curve, false); |
| 815 |
else CRailWay_TraceRail_CTempTracer(m_SplitList.rbegin(), --m_SplitList.rend(), curve, true); |
| 816 |
} |
| 817 |
|
| 818 |
class CRailWay_TraceRailSplit_CTempTracerSplit{ |
| 819 |
public: |
| 820 |
template<class _II> |
| 821 |
CRailWay_TraceRailSplit_CTempTracerSplit(_II from, _II to, CRailTraceCurve *curve, bool rev){ |
| 822 |
float sumlen = 0.0f; |
| 823 |
bool t1 = true, t2; |
| 824 |
CRailSplitter tspl = (from++)->Get(rev); |
| 825 |
while(true){ |
| 826 |
CRailTraceCurve::SetTerminate(t1, t2 = from==to); |
| 827 |
CRailSplitter nspl = from->Get(rev); |
| 828 |
float seglen = nspl.CalcDist(tspl), sumnext = sumlen+seglen; |
| 829 |
int i, div = (int)(seglen/RAIL_SEG_MIN); |
| 830 |
if(div>1){ |
| 831 |
float seglen2 = seglen/div; |
| 832 |
CRailSplitter tspl2 = tspl; |
| 833 |
for(i = 1; i<=div; i++){ |
| 834 |
CRailTraceCurve::SetSplitItr(from); |
| 835 |
CRailTraceCurve::SetTerminate(t1, t2 && i==div); |
| 836 |
CRailSplitter nspl2 = nspl.CalcMid(&tspl, (float)i/div); |
| 837 |
if(!curve->Confirm(tspl2.m_Pos, nspl2.m_Pos)) return; |
| 838 |
curve->FinishTrace( |
| 839 |
tspl2.m_Pos, tspl2.m_Right, tspl2.m_Up, tspl2.m_Dir, |
| 840 |
nspl2.m_Pos, nspl2.m_Right, nspl2.m_Up, nspl2.m_Dir, |
| 841 |
sumlen, seglen2, *from); |
| 842 |
sumlen += seglen2; |
| 843 |
tspl2 = nspl2; |
| 844 |
t1 = false; |
| 845 |
} |
| 846 |
}else{ |
| 847 |
CRailTraceCurve::SetSplitItr(from); |
| 848 |
if(!curve->Confirm(tspl.m_Pos, nspl.m_Pos)) return; |
| 849 |
curve->FinishTrace(tspl.m_Pos, tspl.m_Right, tspl.m_Up, tspl.m_Dir, |
| 850 |
nspl.m_Pos, nspl.m_Right, nspl.m_Up, nspl.m_Dir, sumlen, seglen, *from); |
| 851 |
} |
| 852 |
if(from==to) return; |
| 853 |
from++; |
| 854 |
sumlen = sumnext; |
| 855 |
tspl = nspl; |
| 856 |
t1 = false; |
| 857 |
} |
| 858 |
} |
| 859 |
}; |
| 860 |
|
| 861 |
/* |
| 862 |
* 詳細トレース |
| 863 |
*/ |
| 864 |
void CRailWay::TraceRailSplit( |
| 865 |
int side, // 方向 |
| 866 |
CRailTraceCurve *curve // トレーサ |
| 867 |
){ |
| 868 |
if(side) CRailWay_TraceRailSplit_CTempTracerSplit(m_SplitList.begin(), --m_SplitList.end(), curve, false); |
| 869 |
else CRailWay_TraceRailSplit_CTempTracerSplit(m_SplitList.rbegin(), --m_SplitList.rend(), curve, true); |
| 870 |
} |
| 871 |
|
| 872 |
class CRailWay_GetFirstDir_CSolver{ |
| 873 |
public: |
| 874 |
template<class _II> |
| 875 |
VEC3 operator()(_II from, _II to){ |
| 876 |
VEC3 first = from->m_Pos, dir; |
| 877 |
_II prev = from++; |
| 878 |
float sumlen = 0.0f; |
| 879 |
while(true){ |
| 880 |
dir = from->m_Pos-first; |
| 881 |
sumlen += V3Len(&(from->m_Pos-prev->m_Pos)); |
| 882 |
if(from==to || sumlen>=POINT_DEC_MIN) break; |
| 883 |
prev = from++; |
| 884 |
} |
| 885 |
return dir; |
| 886 |
} |
| 887 |
}; |
| 888 |
|
| 889 |
/* |
| 890 |
* 最初の分割点までの dir ベクトルを求める |
| 891 |
*/ |
| 892 |
VEC3 CRailWay::GetFirstDir( |
| 893 |
int side // サイド |
| 894 |
){ |
| 895 |
return side ? CRailWay_GetFirstDir_CSolver()(m_SplitList.rbegin(), --m_SplitList.rend()) |
| 896 |
: CRailWay_GetFirstDir_CSolver()(m_SplitList.begin(), --m_SplitList.end()); |
| 897 |
} |
| 898 |
|
| 899 |
/* |
| 900 |
* 編成撤去 |
| 901 |
*/ |
| 902 |
void CRailWay::RemoveGroup(){ |
| 903 |
while(m_GroupEnd.size()) (*m_GroupEnd.begin())->m_Group->Remove(); |
| 904 |
} |
| 905 |
|
| 906 |
/* |
| 907 |
* ワープ端のシーンをチェック |
| 908 |
*/ |
| 909 |
void CRailWay::CheckWarpEndScene( |
| 910 |
CScene *scene // シーン |
| 911 |
){ |
| 912 |
int i, j; |
| 913 |
m_Selected = 0; |
| 914 |
for(i = 0; i<2; i++){ |
| 915 |
for(j = 0; j<2; j++){ |
| 916 |
CRailWay *way = m_Link[i].m_Link->m_Link[!m_Link[i].m_Side][j].m_Link; |
| 917 |
if(way && way->GetScene()==scene) m_Selected = 2; |
| 918 |
} |
| 919 |
} |
| 920 |
} |
| 921 |
|
| 922 |
/* |
| 923 |
* 編成の中か調べる |
| 924 |
*/ |
| 925 |
bool CRailWay::IsInsideGroup( |
| 926 |
int side, // 方向 |
| 927 |
float ofs // オフセット |
| 928 |
){ |
| 929 |
set<CTrainGroup *> inset, erset; |
| 930 |
CTrainGroup *conuser[2]; |
| 931 |
int i; |
| 932 |
for(i = 0; i<2; i++){ |
| 933 |
conuser[i] = m_Link[i].m_Link ? m_Link[i].m_Link->m_User : NULL; |
| 934 |
if(conuser[i]) inset.insert(conuser[i]); |
| 935 |
} |
| 936 |
IPGroupEndLocator ipge = m_GroupEnd.begin(); |
| 937 |
for(; ipge!=m_GroupEnd.end(); ipge++){ |
| 938 |
float end = (*ipge)->m_Offset; |
| 939 |
int ts = (*ipge)->m_Side; |
| 940 |
CTrainGroup *tg = (*ipge)->m_Group; |
| 941 |
if(ts==side){ |
| 942 |
end = GetSegLen()-end; |
| 943 |
if(end<=ofs) erset.insert(tg); |
| 944 |
else if(conuser[ts]==tg) return true; |
| 945 |
else inset.insert(tg); |
| 946 |
}else{ |
| 947 |
if(ofs<=end) erset.insert(tg); |
| 948 |
else if(conuser[ts]==tg) return true; |
| 949 |
else inset.insert(tg); |
| 950 |
} |
| 951 |
} |
| 952 |
set<CTrainGroup *>::iterator ersitr = erset.begin(); |
| 953 |
for(; ersitr!=erset.end(); ersitr++) inset.erase(*ersitr); |
| 954 |
if(inset.size()){ |
| 955 |
//Dialog("inside %d", inset.size()); |
| 956 |
return true; |
| 957 |
} |
| 958 |
return false; |
| 959 |
} |
| 960 |
|
| 961 |
/* |
| 962 |
* 車輌設置 |
| 963 |
*/ |
| 964 |
bool CRailWay::SetTrain( |
| 965 |
int side, // 方向 |
| 966 |
float ofs, // オフセット |
| 967 |
CGroupEndLocator *tail, // 最後尾レール格納先 |
| 968 |
bool rev, // 後退フラグ |
| 969 |
ITrainSetBuffer *icur, // 現在位置 |
| 970 |
ITrainSetBuffer *iend, // 終了位置 |
| 971 |
CTrainGroup *group, // 編成 |
| 972 |
bool extend, // 拡張トレール |
| 973 |
bool hittest // 衝突判定 |
| 974 |
){ |
| 975 |
if(!CheckRailBlock(group)) return false; |
| 976 |
CRailWay *ptr = this, *prev = NULL; |
| 977 |
float tmp; |
| 978 |
if(extend && ofs+(rev ? -(*icur)->m_SumLen : (*icur)->m_SumLen)<0.0f){ |
| 979 |
CRailConnectorLink &con = ptr->m_Link[!side]; |
| 980 |
VEC3 pos = con.GetPos(), dir = -con.GetDir(), up = con.GetUp(); |
| 981 |
while((tmp = (rev ? -(*icur)->m_SumLen : (*icur)->m_SumLen)+ofs)<0.0f){ |
| 982 |
(*icur)->SetPosture(pos+dir*tmp, rev ? dir : -dir, up, ptr); |
| 983 |
if(rev) (*icur)--; else (*icur)++; |
| 984 |
if(*icur==*iend){ |
| 985 |
tail->m_Side = !side; |
| 986 |
tail->m_Offset = tmp; |
| 987 |
tail->m_SetRail = ptr; |
| 988 |
return true; |
| 989 |
} |
| 990 |
} |
| 991 |
} |
| 992 |
while(ptr){ |
| 993 |
if(ptr->IsRailBlock()) SetRailBlockUser(ptr->GetRailBlock(), group); |
| 994 |
if(ptr->IsSpeedLimit()) group->SetSpeedLimit(ptr->GetSpeedLimit()); |
| 995 |
if(ptr->m_WarpDummy){ |
| 996 |
group->NotifyWarp(); |
| 997 |
}else{ |
| 998 |
if(hittest){ |
| 999 |
tmp = (rev ? ++ITrainSetBuffer(*iend) |
| 1000 |
: --ITrainSetBuffer(*iend))->m_SumLen+ofs; |
| 1001 |
IPGroupEndLocator ipge = ptr->m_GroupEnd.begin(); |
| 1002 |
for(; ipge!=ptr->m_GroupEnd.end(); ipge++){ |
| 1003 |
float fend = (*ipge)->m_Offset; |
| 1004 |
if((*ipge)->m_Side==side) fend = ptr->GetSegLen()-fend; |
| 1005 |
if(ofs-0.001f<=fend && fend<=tmp+0.001f){ |
| 1006 |
return false; |
| 1007 |
} |
| 1008 |
} |
| 1009 |
} |
| 1010 |
CTrainSetCurve curve(ptr->m_RailPlugin, ptr->m_TiePlugin, ptr->m_GirderPlugin, |
| 1011 |
rev, CGroupEndLocator(!side, ofs, ptr, group), tail, icur, iend); |
| 1012 |
ptr->TraceRail(side, &curve); |
| 1013 |
if(*icur==*iend) return true; |
| 1014 |
ofs -= ptr->GetSegLen(); |
| 1015 |
} |
| 1016 |
prev = ptr; |
| 1017 |
CRailConnectorLink &con = ptr->m_Link[side]; |
| 1018 |
CRailConnector *pcon = con.m_Link; |
| 1019 |
if(pcon->GetUser() || !pcon->CheckRailBlock(group)) return false; |
| 1020 |
pcon->SetUser(group); |
| 1021 |
group->AddPoint(pcon); |
| 1022 |
pcon->m_TrailPoint[con.m_Side] = con.m_Point; |
| 1023 |
pcon->m_Side = con.m_Side; |
| 1024 |
CRailWayLink &next = pcon->m_Link[!con.m_Side][pcon->m_TrailPoint[!con.m_Side]]; |
| 1025 |
if(ptr = next.m_Link) side = !next.m_Side; |
| 1026 |
} |
| 1027 |
if(extend && prev){ |
| 1028 |
CRailConnectorLink &con = prev->m_Link[side]; |
| 1029 |
VEC3 pos = con.GetPos(), dir = con.GetDir(), up = con.GetUp(); |
| 1030 |
while(*icur!=*iend){ |
| 1031 |
tmp = (rev ? -(*icur)->m_SumLen : (*icur)->m_SumLen)+ofs; |
| 1032 |
(*icur)->SetPosture(pos+dir*tmp, rev ? dir : -dir, up, prev); |
| 1033 |
if(rev) (*icur)--; else (*icur)++; |
| 1034 |
} |
| 1035 |
tail->m_Side = !side; |
| 1036 |
tail->m_Offset = prev->GetSegLen()+tmp; |
| 1037 |
tail->m_SetRail = prev; |
| 1038 |
return true; |
| 1039 |
} |
| 1040 |
return false; |
| 1041 |
} |
| 1042 |
|
| 1043 |
/* |
| 1044 |
* 車輌進行 |
| 1045 |
* |
| 1046 |
* 戻り値 (0: succeed, 1: railend, 2: hit train) |
| 1047 |
*/ |
| 1048 |
int CRailWay::MarchTrain( |
| 1049 |
float *limit, // 進行距離 |
| 1050 |
CGroupEndLocator *head, // 終端格納先 |
| 1051 |
CTrainGroup *caller, // 呼び出し元(予約時のみ) |
| 1052 |
CTrainGroup *group // 編成(閉塞チェック用) |
| 1053 |
){ |
| 1054 |
float ofs = head->m_Offset; |
| 1055 |
bool fin = false; |
| 1056 |
CRailWay *ptr = this, *prev = NULL; |
| 1057 |
head->m_SetRail = NULL; |
| 1058 |
while(ptr){ |
| 1059 |
float tmp = *limit+ofs, seg = ptr->GetSegLen(); |
| 1060 |
if(caller && ptr->IsRailBlock()) SetRailBlockUser(ptr->GetRailBlock(), caller); |
| 1061 |
if(caller && ptr->IsSpeedLimit()) caller->SetSpeedLimit(ptr->GetSpeedLimit()); |
| 1062 |
if(!ptr->m_WarpDummy){ |
| 1063 |
if(caller && ptr->m_Platform) caller->NotifyPlatform( |
| 1064 |
ptr->m_Platform, -ofs, !!head->m_Side); |
| 1065 |
IPGroupEndLocator ipge = ptr->m_GroupEnd.begin(); |
| 1066 |
for(; ipge!=ptr->m_GroupEnd.end(); ipge++){ |
| 1067 |
if(caller && caller==(*ipge)->m_Group) continue; |
| 1068 |
float end = (*ipge)->m_Offset; |
| 1069 |
if((*ipge)->m_Side==head->m_Side) end = seg-end; |
| 1070 |
if(ofs-0.001f<=end && end<=tmp+0.001f){ |
| 1071 |
g_HitTrainGroup = **ipge; |
| 1072 |
head->m_Offset = end; |
| 1073 |
head->m_SetRail = ptr; |
| 1074 |
*limit = end-ofs; |
| 1075 |
return 2; |
| 1076 |
} |
| 1077 |
} |
| 1078 |
if(tmp<=seg){ |
| 1079 |
head->m_Offset = tmp; |
| 1080 |
head->m_SetRail = ptr; |
| 1081 |
return 0; |
| 1082 |
} |
| 1083 |
} |
| 1084 |
prev = ptr; |
| 1085 |
CRailConnectorLink &con = ptr->m_Link[head->m_Side]; |
| 1086 |
CRailConnector *pcon = con.m_Link; |
| 1087 |
bool randomize = false; |
| 1088 |
if(pcon->GetUser() || !pcon->CheckRailBlock(group)){ |
| 1089 |
// if(!caller || caller!=pcon->GetUser()){ |
| 1090 |
head->m_Offset = seg; |
| 1091 |
head->m_SetRail = ptr; |
| 1092 |
*limit = seg-ofs; |
| 1093 |
return 2; |
| 1094 |
// } |
| 1095 |
}else if(g_ManualControl){ |
| 1096 |
randomize = true; |
| 1097 |
}else if(caller){ |
| 1098 |
pcon->SetUser(caller); |
| 1099 |
randomize = !caller->AddSeek(pcon); |
| 1100 |
} |
| 1101 |
ofs -= seg; |
| 1102 |
int newpoint = 0; |
| 1103 |
pcon->m_TrailPoint[con.m_Side] = con.m_Point; |
| 1104 |
CRailWayLink *next2 = pcon->m_Link[!con.m_Side]; |
| 1105 |
if(next2[0].m_Link){ |
| 1106 |
if(next2[1].m_Link){ |
| 1107 |
if(randomize){ |
| 1108 |
// Dialog("randomize\ncaller = %p", caller); |
| 1109 |
if(g_ManualControl){ |
| 1110 |
newpoint = pcon->GetNetPoint(); |
| 1111 |
}else{ |
| 1112 |
CPointElement *pe = pcon->m_PointInst.Dequeue(caller); |
| 1113 |
newpoint = pe->CalcPoint(); // 0: left, 1: right |
| 1114 |
} |
| 1115 |
VEC3 d1, d2, right = con.GetRight(); |
| 1116 |
V3Norm(&d1, &next2[0].GetFirstDir()); |
| 1117 |
V3Norm(&d2, &next2[1].GetFirstDir()); |
| 1118 |
if(V3Dot(&right, &d1)>V3Dot(&right, &d2)) newpoint = !newpoint; |
| 1119 |
}else{ |
| 1120 |
newpoint = pcon->m_TrailPoint[!con.m_Side]; |
| 1121 |
} |
| 1122 |
}else{ |
| 1123 |
newpoint = 0; |
| 1124 |
} |
| 1125 |
}else{ |
| 1126 |
if(next2[1].m_Link) newpoint = 1; |
| 1127 |
else break; |
| 1128 |
} |
| 1129 |
pcon->m_Side = !con.m_Side; |
| 1130 |
pcon->m_TrailPoint[pcon->m_Side] = newpoint; |
| 1131 |
CRailWayLink &next = next2[newpoint]; |
| 1132 |
ptr = next.m_Link; |
| 1133 |
head->m_Side = !next.m_Side; |
| 1134 |
} |
| 1135 |
#if EXTEND_RAIL |
| 1136 |
if(prev){ // 延長設置 |
| 1137 |
head->m_SetRail = prev; |
| 1138 |
head->m_Offset = ofs+prev->GetSegLen()+*limit; |
| 1139 |
return 0; |
| 1140 |
} |
| 1141 |
#endif |
| 1142 |
head->m_Offset = prev->GetSegLen(); |
| 1143 |
head->m_SetRail = prev; |
| 1144 |
*limit = -ofs; |
| 1145 |
return 1; |
| 1146 |
} |
| 1147 |
|
| 1148 |
/* |
| 1149 |
* プラットフォームが続いているかどうか調べる |
| 1150 |
*/ |
| 1151 |
bool CRailWay::CheckPlatformExtend( |
| 1152 |
int side, // 方向 |
| 1153 |
CPlatformInst *pf // プラットフォーム |
| 1154 |
){ |
| 1155 |
CRailWay *ptr = this; |
| 1156 |
while(ptr){ |
| 1157 |
if(ptr->m_Platform!=pf || ptr->m_WarpDummy) return true; |
| 1158 |
CRailConnectorLink &con = ptr->m_Link[side]; |
| 1159 |
CRailConnector *pcon = con.m_Link; |
| 1160 |
CRailWayLink *next2 = pcon->m_Link[!con.m_Side]; |
| 1161 |
int point = 0; |
| 1162 |
if(next2[0].m_Link){ |
| 1163 |
if(next2[1].m_Link) return true; |
| 1164 |
else point = 0; |
| 1165 |
}else{ |
| 1166 |
if(next2[1].m_Link) point = 1; |
| 1167 |
else return false; |
| 1168 |
} |
| 1169 |
ptr = next2[point].m_Link; |
| 1170 |
side = !next2[point].m_Side; |
| 1171 |
} |
| 1172 |
return false; |
| 1173 |
} |
| 1174 |
|
| 1175 |
/* |
| 1176 |
* 状態取得 (1, 2: approach, 4: stop) |
| 1177 |
*/ |
| 1178 |
int CRailWay::GetPlatformState(){ |
| 1179 |
int state = 0; |
| 1180 |
if(m_Link[0].m_Link && m_Link[0].m_Link->m_User |
| 1181 |
&& m_Link[1].m_Link && m_Link[1].m_Link->m_User==m_Link[0].m_Link->m_User){ |
| 1182 |
state |= m_Link[0].m_Link->m_Side==m_Link[0].m_Side ? 2 : 1; |
| 1183 |
if(m_Link[0].m_Link->m_User->GetState()==2) state |= 4; |
| 1184 |
} |
| 1185 |
IPGroupEndLocator ipge = m_GroupEnd.begin(); |
| 1186 |
for(; ipge!=m_GroupEnd.end(); ipge++){ |
| 1187 |
state |= (*ipge)->GetDirection() ? 2 : 1; |
| 1188 |
if((*ipge)->m_Group->GetState()==2) state |= 4; |
| 1189 |
} |
| 1190 |
return state; |
| 1191 |
} |
| 1192 |
|
| 1193 |
/* |
| 1194 |
* 動くレールの処理 |
| 1195 |
*/ |
| 1196 |
void CRailWay::UpdateSplitList(){ |
| 1197 |
if(!m_Parent) return; |
| 1198 |
MTX4 mtx = m_Parent->m_DetectInfo.GetPartsInst()->GetObject()->GetMatrix(); |
| 1199 |
NormalizeMatrix(&mtx); |
| 1200 |
if(m_SplitList.size()!=m_Parent->m_SplitList.size()) m_SplitList = m_Parent->m_SplitList; |
| 1201 |
list<CRailSplitter>::iterator itr1 = m_SplitList.begin(), itr2 = m_Parent->m_SplitList.begin(); |
| 1202 |
for(; itr1!=m_SplitList.end(); ++itr1, ++itr2){ |
| 1203 |
D3DXVec3TransformCoord(&itr1->m_Pos, &itr2->m_Pos, &mtx); |
| 1204 |
D3DXVec3TransformNormal(&itr1->m_Right, &itr2->m_Right, &mtx); |
| 1205 |
D3DXVec3TransformNormal(&itr1->m_Up, &itr2->m_Up, &mtx); |
| 1206 |
D3DXVec3TransformNormal(&itr1->m_Dir, &itr2->m_Dir, &mtx); |
| 1207 |
} |
| 1208 |
m_Link[0].m_Link->m_Splitter = m_SplitList.front(); |
| 1209 |
m_Link[1].m_Link->m_Splitter = m_SplitList.back(); |
| 1210 |
} |
| 1211 |
|
| 1212 |
/* |
| 1213 |
* 断面をダンプ |
| 1214 |
*/ |
| 1215 |
void CRailWay::Dump(){ |
| 1216 |
if(!m_RailPlugin && !m_TiePlugin && !m_GirderPlugin) return; |
| 1217 |
if(m_Parent) return; |
| 1218 |
if(m_RailPlugin) m_RailPlugin->SetMapTemp(m_RailMapV); |
| 1219 |
if(m_TiePlugin) m_TiePlugin->SetMapTemp(m_TieMapV); |
| 1220 |
if(m_GirderPlugin) m_GirderPlugin->SetMapTemp(m_GirderMapV); |
| 1221 |
g_MultiTrackDummy = m_MultiTrackDummy; |
| 1222 |
TraceRail(1, &CRailDumpCurve(m_RailPlugin, m_TiePlugin, m_GirderPlugin)); |
| 1223 |
} |
| 1224 |
|
| 1225 |
/* |
| 1226 |
* 等間隔オブジェクトをレンダリング |
| 1227 |
*/ |
| 1228 |
void CRailWay::Render(){ |
| 1229 |
#if 0 |
| 1230 |
devResetMatrix(); |
| 1231 |
devResetMaterial(); |
| 1232 |
devSetLighting(FALSE); |
| 1233 |
devSetState(D3DRS_ZFUNC, D3DCMP_ALWAYS); |
| 1234 |
IPGroupEndLocator ipge = m_GroupEnd.begin(); |
| 1235 |
for(; ipge!=m_GroupEnd.end(); ipge++){ |
| 1236 |
float end = (*ipge)->m_Offset; |
| 1237 |
int side = (*ipge)->m_Side; |
| 1238 |
CRailConnectorLink &con = m_Link[side]; |
| 1239 |
VEC3 tmp = con.GetPos()-con.GetDir()*end; |
| 1240 |
D3DCOLOR col = side ? 0x80ff0000 : 0x800000ff; |
| 1241 |
Draw3DLine(tmp, tmp+V3UP*10.0f, col, col); |
| 1242 |
} |
| 1243 |
devSetState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); |
| 1244 |
devSetLighting(TRUE); |
| 1245 |
#endif |
| 1246 |
// if(!g_ShadowNeeded && !g_ShowRailSelect |
| 1247 |
// && !(m_RailPlugin && m_RailPlugin->HasInterval()) |
| 1248 |
// && !(m_TiePlugin && m_TiePlugin->HasInterval()) |
| 1249 |
// && !(m_GirderPlugin && m_GirderPlugin->HasInterval())) return; |
| 1250 |
if(m_RailPlugin) m_RailPlugin->SetMapTemp(m_RailMapV); |
| 1251 |
if(m_TiePlugin) m_TiePlugin->SetMapTemp(m_TieMapV); |
| 1252 |
if(m_GirderPlugin) m_GirderPlugin->SetMapTemp(m_GirderMapV); |
| 1253 |
g_DummyTrackNum = m_DummyTrackNum; |
| 1254 |
g_DummyTrackInterval = m_DummyTrackInterval; |
| 1255 |
g_MultiTrackDummy = m_MultiTrackDummy; |
| 1256 |
TraceRail(1, &CRailRenderCurve(m_RailPlugin, m_TiePlugin, m_GirderPlugin, this)); |
| 1257 |
//extern int g_GroupEndCount; |
| 1258 |
//g_GroupEndCount += m_GroupEnd.size(); |
| 1259 |
} |
| 1260 |
|
| 1261 |
/* |
| 1262 |
* ワープの描画 |
| 1263 |
*/ |
| 1264 |
void CRailWay::RenderWarp(){ |
| 1265 |
int i; |
| 1266 |
bool draw[2]; |
| 1267 |
D3DCOLOR lc = g_ShowWarpSelect && m_Selected |
| 1268 |
? g_ColorSelect[m_Selected] : 0xff0080ff; |
| 1269 |
D3DCOLOR lca = ScaleColor(lc, g_BlinkAlpha); |
| 1270 |
for(i = 0; i<2; i++) |
| 1271 |
if(draw[i] = m_Link[i].m_Link->GetScene()==g_Scene) m_Link[i].m_Link->Render(lc, false); |
| 1272 |
if(draw[0] && draw[1]){ |
| 1273 |
Draw3DLineWithShadow(m_Link[0].GetPos(), m_Link[1].GetPos(), lca); |
| 1274 |
}else{ |
| 1275 |
for(i = 0; i<2; i++){ |
| 1276 |
float len = WARP_DRAW_LEN*V3Len(&(GetVPos()-m_Link[i].GetPos()))*g_FovRatio; |
| 1277 |
if(draw[i]) Draw3DLineWithShadow(m_Link[i].GetPos(), |
| 1278 |
m_Link[i].GetPos()-m_Link[i].GetDir()*len, lca, lca&0x00ffffff); |
| 1279 |
} |
| 1280 |
} |
| 1281 |
} |
| 1282 |
|
| 1283 |
/* |
| 1284 |
* アドレス復元 |
| 1285 |
*/ |
| 1286 |
void CRailWay::RestoreAddress(){ |
| 1287 |
m_Link[0].RestoreAddress(); |
| 1288 |
m_Link[1].RestoreAddress(); |
| 1289 |
m_Platform = (CPlatformInst *)ReplaceAdr(m_Platform); |
| 1290 |
IPierPos ipi = m_PierList.begin(); |
| 1291 |
for(; ipi!=m_PierList.end(); ipi++) ipi->RestoreAddress(); |
| 1292 |
IPolePos ipo = m_PoleList.begin(); |
| 1293 |
for(; ipo!=m_PoleList.end(); ipo++) ipo->RestoreAddress(); |
| 1294 |
IPGroupEndLocator ipge = m_GroupEnd.begin(); |
| 1295 |
for(; ipge!=m_GroupEnd.end();){ |
| 1296 |
*ipge = (CGroupEndLocator *)ReplaceAdr(*ipge); |
| 1297 |
if(*ipge){ |
| 1298 |
++ipge; |
| 1299 |
}else{ |
| 1300 |
//Dialog("GroupEnd not found!"); |
| 1301 |
ipge = m_GroupEnd.erase(ipge); |
| 1302 |
} |
| 1303 |
} |
| 1304 |
} |
| 1305 |
|
| 1306 |
/* |
| 1307 |
* 読込 |
| 1308 |
*/ |
| 1309 |
char *CRailWay::Read( |
| 1310 |
char *str // 対象文字列 |
| 1311 |
){ |
| 1312 |
char *eee, *tmp; |
| 1313 |
if(!(str = BeginBlock(str, "RailWay"))){ |
| 1314 |
delete this; |
| 1315 |
return NULL; |
| 1316 |
} |
| 1317 |
if(!(str = AsgnPointer(eee = str, "Address", &m_OldAdr))) throw CSynErr(eee); |
| 1318 |
g_AddressMap[m_OldAdr] = this; |
| 1319 |
string pid; |
| 1320 |
if(!(str = AsgnString(eee = str, "RailPlugin", &pid))) throw CSynErr(eee); |
| 1321 |
m_RailPlugin = g_RailPluginList->FindPlugin(pid.c_str(), true); |
| 1322 |
if(!(str = AsgnString(eee = str, "TiePlugin", &pid))) throw CSynErr(eee); |
| 1323 |
m_TiePlugin = g_TiePluginList->FindPlugin(pid.c_str(), true); |
| 1324 |
if(!(str = AsgnString(eee = str, "GirderPlugin", &pid))) throw CSynErr(eee); |
| 1325 |
m_GirderPlugin = g_GirderPluginList->FindPlugin(pid.c_str(), true); |
| 1326 |
if(!(str = AsgnString(eee = str, "PierPlugin", &pid))) throw CSynErr(eee); |
| 1327 |
m_PierPlugin = g_PierPluginList->FindPlugin(pid.c_str(), true); |
| 1328 |
if(!(str = AsgnString(eee = str, "LinePlugin", &pid))) throw CSynErr(eee); |
| 1329 |
m_LinePlugin = g_LinePluginList->FindPlugin(pid.c_str(), true); |
| 1330 |
if(!(str = AsgnString(eee = str, "PolePlugin", &pid))) throw CSynErr(eee); |
| 1331 |
m_PolePlugin = g_PolePluginList->FindPlugin(pid.c_str(), true); |
| 1332 |
if(!(str = ReadMapVector(eee = str, "RailMapV", m_RailMapV))) throw CSynErr(eee); |
| 1333 |
if(!(str = ReadMapVector(eee = str, "TieMapV", m_TieMapV))) throw CSynErr(eee); |
| 1334 |
if(!(str = ReadMapVector(eee = str, "GirderMapV", m_GirderMapV))) throw CSynErr(eee); |
| 1335 |
if(!(str = ReadMapVector(eee = str, "LineMapV", m_LineMapV))) throw CSynErr(eee); |
| 1336 |
|
| 1337 |
if(!(str = AsgnYesNo(eee = str, "MultiTrackDummy", &m_MultiTrackDummy))) throw CSynErr(eee); |
| 1338 |
if(m_MultiTrackDummy){ |
| 1339 |
if(!(str = AsgnInteger(eee = str, "DummyTrackNum", &m_DummyTrackNum))) throw CSynErr(eee); |
| 1340 |
if(!(str = AsgnFloat(eee = str, "DummyTrackInterval", &m_DummyTrackInterval))) throw CSynErr(eee); |
| 1341 |
} |
| 1342 |
if(!(str = m_Link[0].Read(eee = str, "Link0"))) throw CSynErr(eee); |
| 1343 |
if(!(str = m_Link[1].Read(eee = str, "Link1"))) throw CSynErr(eee); |
| 1344 |
if(!(str = AsgnPointer(eee = str, "Platform", (void **)&m_Platform))) throw CSynErr(eee); |
| 1345 |
if(tmp = AsgnString(str, "RailBlock", &m_RailBlock)){ |
| 1346 |
str = tmp; |
| 1347 |
m_RailBlock = RestoreDoubleQuote(m_RailBlock); |
| 1348 |
} |
| 1349 |
if(tmp = AsgnInteger(str, "SpeedLimit", &m_SpeedLimit)){ |
| 1350 |
str = tmp; |
| 1351 |
if(m_SpeedLimit<0) m_SpeedLimit = -1; |
| 1352 |
} |
| 1353 |
|
| 1354 |
if(!(str = BeginBlock(eee = str, "SplitList"))) throw CSynErr(eee); |
| 1355 |
CRailSplitter spl; |
| 1356 |
while(tmp = spl.Read(eee = str)){ |
| 1357 |
str = tmp; |
| 1358 |
m_SplitList.push_back(spl); |
| 1359 |
} |
| 1360 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 1361 |
|
| 1362 |
if(!(str = BeginBlock(str, "PierList"))) throw CSynErr(eee); |
| 1363 |
if(!(str = AsgnFloat(eee = str, "PierPos", &m_PierPos))) throw CSynErr(eee); |
| 1364 |
CPierPos pierpos; |
| 1365 |
while(tmp = pierpos.Read(eee = str)){ |
| 1366 |
str = tmp; |
| 1367 |
m_PierList.push_back(pierpos); |
| 1368 |
} |
| 1369 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 1370 |
|
| 1371 |
if(!(str = BeginBlock(str, "PoleList"))) throw CSynErr(eee); |
| 1372 |
if(!(str = AsgnFloat(eee = str, "PolePos", &m_PolePos))) throw CSynErr(eee); |
| 1373 |
CPolePos polepos; |
| 1374 |
while(tmp = polepos.Read(eee = str)){ |
| 1375 |
str = tmp; |
| 1376 |
m_PoleList.push_back(polepos); |
| 1377 |
} |
| 1378 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 1379 |
|
| 1380 |
if(tmp = Assignment(str, "GroupEnd")){ |
| 1381 |
str = tmp; |
| 1382 |
do{ |
| 1383 |
if(m_GroupEnd.size() && !(str = Character2(eee = str, ','))) throw CSynErr(eee); |
| 1384 |
CGroupEndLocator *end; |
| 1385 |
if(!(str = HexPointer(eee = str, (void **)&end))) throw CSynErr(eee); |
| 1386 |
m_GroupEnd.push_back(end); |
| 1387 |
} while(!(tmp = Character2(str, ';'))); |
| 1388 |
str = tmp; |
| 1389 |
} |
| 1390 |
|
| 1391 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 1392 |
*ms_Root = this; |
| 1393 |
ms_Root = &m_Next; |
| 1394 |
return str; |
| 1395 |
} |
| 1396 |
|
| 1397 |
/* |
| 1398 |
* 読込 |
| 1399 |
*/ |
| 1400 |
char *CRailWay::ReadWarp( |
| 1401 |
char *str // 対象文字列 |
| 1402 |
){ |
| 1403 |
char *eee; |
| 1404 |
if(!(str = BeginBlock(str, "Warp"))){ |
| 1405 |
delete this; |
| 1406 |
return NULL; |
| 1407 |
} |
| 1408 |
void *oldadr; |
| 1409 |
if(!(str = AsgnPointer(eee = str, "Address", &oldadr))) throw CSynErr(eee); |
| 1410 |
g_AddressMap[oldadr] = this; |
| 1411 |
if(!(str = m_Link[0].Read(eee = str, "Link0"))) throw CSynErr(eee); |
| 1412 |
if(!(str = m_Link[1].Read(eee = str, "Link1"))) throw CSynErr(eee); |
| 1413 |
if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK); |
| 1414 |
m_WarpDummy = true; |
| 1415 |
m_Scene = NULL; |
| 1416 |
*ms_Root = this; |
| 1417 |
ms_Root = &m_Next; |
| 1418 |
return str; |
| 1419 |
} |
| 1420 |
|
| 1421 |
/* |
| 1422 |
* 保存 |
| 1423 |
*/ |
| 1424 |
void CRailWay::Save( |
| 1425 |
FILE *df // ファイル |
| 1426 |
){ |
| 1427 |
fprintf(df, "\t\t\tRailWay{\n"); |
| 1428 |
fprintf(df, "\t\t\t\tAddress = %p;\n", this); |
| 1429 |
fprintf(df, "\t\t\t\tRailPlugin = \"%s\";\n", CheckPluginID(m_RailPlugin)); |
| 1430 |
fprintf(df, "\t\t\t\tTiePlugin = \"%s\";\n", CheckPluginID(m_TiePlugin)); |
| 1431 |
fprintf(df, "\t\t\t\tGirderPlugin = \"%s\";\n", CheckPluginID(m_GirderPlugin)); |
| 1432 |
fprintf(df, "\t\t\t\tPierPlugin = \"%s\";\n", CheckPluginID(m_PierPlugin)); |
| 1433 |
fprintf(df, "\t\t\t\tLinePlugin = \"%s\";\n", CheckPluginID(m_LinePlugin)); |
| 1434 |
fprintf(df, "\t\t\t\tPolePlugin = \"%s\";\n", CheckPluginID(m_PolePlugin)); |
| 1435 |
SaveMapVector(df, "\t\t\t\tRailMapV = ", m_RailMapV); |
| 1436 |
SaveMapVector(df, "\t\t\t\tTieMapV = ", m_TieMapV); |
| 1437 |
SaveMapVector(df, "\t\t\t\tGirderMapV = ", m_GirderMapV); |
| 1438 |
SaveMapVector(df, "\t\t\t\tLineMapV = ", m_LineMapV); |
| 1439 |
|
| 1440 |
fprintf(df, "\t\t\t\tMultiTrackDummy = %s;\n", YESNO[m_MultiTrackDummy]); |
| 1441 |
if(m_MultiTrackDummy){ |
| 1442 |
fprintf(df, "\t\t\t\tDummyTrackNum = %d;\n", m_DummyTrackNum); |
| 1443 |
fprintf(df, "\t\t\t\tDummyTrackInterval = %f;\n", m_DummyTrackInterval); |
| 1444 |
} |
| 1445 |
m_Link[0].Save(df, "\t\t\t\tLink0 = "); |
| 1446 |
m_Link[1].Save(df, "\t\t\t\tLink1 = "); |
| 1447 |
fprintf(df, "\t\t\t\tPlatform = %p;\n", m_Platform); |
| 1448 |
if(IsRailBlock()) fprintf(df, "\t\t\t\tRailBlock = \"%s\";\n", ExpandDoubleQuote(m_RailBlock).c_str()); |
| 1449 |
if(IsSpeedLimit()) fprintf(df, "\t\t\t\tSpeedLimit = %d;\n", m_SpeedLimit); |
| 1450 |
|
| 1451 |
fprintf(df, "\t\t\t\tSplitList{\n"); |
| 1452 |
list<CRailSplitter> *saving_split_list = m_Parent ? &m_Parent->m_SplitList : &m_SplitList; |
| 1453 |
IRailSplitter irs = saving_split_list->begin(); |
| 1454 |
for(; irs!=saving_split_list->end(); irs++) irs->Save(df, "\t\t\t\t\t"); |
| 1455 |
fprintf(df, "\t\t\t\t}\n"); |
| 1456 |
|
| 1457 |
fprintf(df, "\t\t\t\tPierList{\n"); |
| 1458 |
fprintf(df, "\t\t\t\t\tPierPos = %f;\n", m_PierPos); |
| 1459 |
IPierPos ipi = m_PierList.begin(); |
| 1460 |
for(; ipi!=m_PierList.end(); ipi++) ipi->Save(df); |
| 1461 |
fprintf(df, "\t\t\t\t}\n"); |
| 1462 |
|
| 1463 |
fprintf(df, "\t\t\t\tPoleList{\n"); |
| 1464 |
fprintf(df, "\t\t\t\t\tPolePos = %f;\n", m_PolePos); |
| 1465 |
IPolePos ipo = m_PoleList.begin(); |
| 1466 |
for(; ipo!=m_PoleList.end(); ipo++) ipo->Save(df); |
| 1467 |
fprintf(df, "\t\t\t\t}\n"); |
| 1468 |
|
| 1469 |
if(m_GroupEnd.size()){ |
| 1470 |
fprintf(df, "\t\t\t\tGroupEnd = "); |
| 1471 |
IPGroupEndLocator ipge = m_GroupEnd.begin(); |
| 1472 |
for(; ipge!=m_GroupEnd.end(); ipge++) |
| 1473 |
fprintf(df, ipge==m_GroupEnd.begin() ? "%p" : ", %p", *ipge); |
| 1474 |
fprintf(df, ";\n"); |
| 1475 |
} |
| 1476 |
|
| 1477 |
fprintf(df, "\t\t\t}\n"); |
| 1478 |
} |
| 1479 |
|
| 1480 |
/* |
| 1481 |
* 保存 (ワープ用) |
| 1482 |
*/ |
| 1483 |
void CRailWay::SaveWarp( |
| 1484 |
FILE *df // ファイル |
| 1485 |
){ |
| 1486 |
fprintf(df, "\tWarp{\n"); |
| 1487 |
fprintf(df, "\t\tAddress = %p;\n", this); |
| 1488 |
m_Link[0].Save(df, "\t\tLink0 = "); |
| 1489 |
m_Link[1].Save(df, "\t\tLink1 = "); |
| 1490 |
fprintf(df, "\t}\n"); |
| 1491 |
} |
| 1492 |
|
| 1493 |
//////////////////////////////////////////////////////////////////////////////// |
| 1494 |
//////////////////////////////////////////////////////////////////////////////// |
| 1495 |
|
| 1496 |
CTrainGroup* GetRailBlockUser(std::string& name){ |
| 1497 |
map<std::string, CTrainGroup *>::iterator itr = g_RailBlockMap.find(name); |
| 1498 |
if(itr==g_RailBlockMap.end()) return NULL; |
| 1499 |
return itr->second; |
| 1500 |
} |
| 1501 |
|
| 1502 |
void SetRailBlockUser(std::string& name, CTrainGroup *group){ |
| 1503 |
g_RailBlockMap[name] = group; |
| 1504 |
} |
| 1505 |
|
| 1506 |
void ClearRailBlockUser(CTrainGroup *group){ |
| 1507 |
if(group){ |
| 1508 |
map<std::string, CTrainGroup *>::iterator itr; |
| 1509 |
for(itr = g_RailBlockMap.begin(); itr!=g_RailBlockMap.end(); ++itr){ |
| 1510 |
if(itr->second==group) itr->second = NULL; |
| 1511 |
} |
| 1512 |
}else{ |
| 1513 |
g_RailBlockMap.clear(); |
| 1514 |
} |
| 1515 |
} |