Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CRailWay.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations) (download) (as text)
Sat Oct 26 14:53:53 2013 UTC (10 years, 6 months ago) by okadu
File MIME type: text/x-c++src
File size: 44287 byte(s)
[okadu] Version 2.15
橋脚・架線柱手動設置機能
車輌プラグイン以外でクランク等使用可能に
エンジン模型プラグイン追加

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 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26