Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CRailBuilder.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Sun Aug 15 01:53:13 2010 UTC (13 years, 9 months ago) by okadu
File MIME type: text/x-c++src
File size: 11912 byte(s)


1 #include "stdafx.h"
2 #include "RailMap.h"
3 #include "CInterface.h"
4 #include "CScene.h"
5 #include "CSurfacePlugin.h"
6 #include "CRailPlanCurve.h"
7 #include "CRailBuilder.h"
8 #include "CRailWay.h"
9 #include "CStation.h"
10 #include "CRailPlugin.h"
11 #include "CTiePlugin.h"
12 #include "CGirderPlugin.h"
13 #include "CSkinPlugin.h"
14
15 // 内部定数
16 extern const float CORNER_MIN_DIST = 4.5f; // 制御点間最小距離
17
18 // 内部グローバル
19 CPlatformInst *g_PlatformInst = NULL; // カレントプラットフォーム
20 list<list<list<CRailWay *> > > g_MultiTrackRailList; // 複線レールリスト
21 ILLPRailWay g_MultiTrackSegment; // カレント複線セグメント
22 ILPRailWay g_SingleTrackSegment; // カレント単線セグメント
23
24 // static メンバ
25 int CRailBuilder::ms_CurrentTrack;
26 int CRailBuilder::ms_TrackNum;
27 float CRailBuilder::ms_TrackInterval;
28 float CRailBuilder::ms_TrackShift;
29 bool CRailBuilder::ms_LiftRailSurface;
30 VEC3 CRailBuilder::ms_BeginPosSum;
31 VEC3 CRailBuilder::ms_BeginDirSum;
32 VEC3 CRailBuilder::ms_EndPosSum;
33 VEC3 CRailBuilder::ms_EndDirSum;
34
35 /*
36 * [static]
37 * ベクトル総和リセット
38 */
39 void CRailBuilder::ResetDirSum(){
40 ms_BeginPosSum = ms_EndPosSum = V3ZERO;
41 ms_BeginDirSum = ms_EndDirSum = V3ZERO;
42 g_MultiTrackRailList.clear();
43 }
44
45 /*
46 * [static]
47 * トラック情報設定
48 */
49 void CRailBuilder::SetTrack(
50 int cur, // 現在のトラック
51 int tnum, // 線数
52 float tint, // 線間隔
53 bool lift // レール持ち上げ
54 ){
55 ms_CurrentTrack = cur;
56 ms_TrackNum = tnum;
57 ms_TrackInterval = tint;
58 ms_LiftRailSurface = lift;
59 float p = ms_TrackNum==ms_CurrentTrack ? 0.0f : 0.5f*(ms_TrackNum-1)-ms_CurrentTrack;
60 CRailPlanCurve::SetRadiusDrawPos(p);
61 ms_TrackShift = ms_TrackInterval*p;
62 g_MultiTrackSegment = g_MultiTrackRailList.begin();
63 }
64
65 /*
66 * コンストラクタ
67 */
68 CRailBuilder::CRailBuilder(
69 VEC3 pos, // 座標
70 CRailBuilder *prev // 前
71 ){
72 m_Pos = pos;
73 m_HitFlag = false;
74 if(m_Prev = prev) m_Prev->m_Next = this;
75 m_Next = NULL;
76 }
77
78 /*
79 * デストラクタ
80 */
81 CRailBuilder::~CRailBuilder(){
82 DELETE_V(m_Next);
83 }
84
85 /*
86 * 制御点削除
87 */
88 CRailBuilder *CRailBuilder::Pop(){
89 if(!IsLinkEmpty()){
90 if(m_Link.rbegin()->m_Link){
91 m_Link.pop_back();
92 if(m_Link.size()) m_Link.pop_back();
93 else goto POP;
94 }else{
95 m_Link.pop_back();
96 }
97 return this;
98 }
99 POP:
100 CRailBuilder *prev = m_Prev;
101 if(prev){
102 prev->m_Pos = m_Pos;
103 prev->m_Next = NULL;
104 }
105 delete this;
106 return prev;
107 }
108
109 /*
110 * 座標設定
111 */
112 VEC3 CRailBuilder::SetPos(
113 VEC3 p, // 座標
114 int clip // クリップモード (1: 地下, 2: 高架)
115 ){
116 m_Pos = p;
117 m_HitFlag = g_Scene->ClipAlt(&m_Pos, &m_HitPos, &m_HitNorm, clip);
118 return m_Pos;
119 }
120
121 /*
122 * リンク設定
123 */
124 bool CRailBuilder::SetLink(
125 CRailLinkTemp &link // リンク
126 ){
127 if(m_Link.size()) m_Link.rbegin()->m_Link = NULL;
128 else PushLink();
129 if(link.m_Link && m_Prev){
130 if(m_Prev->IsLast()) return false;
131 if(m_Prev->CheckLink()){
132 VEC3 tdir;
133 V3Norm(&tdir, &(link.m_Pos-m_Prev->GetLink().m_Pos));
134 float dpdot = V3Dot(&tdir, &m_Prev->GetLink().m_Dir);
135 float dddot = -V3Dot(&link.m_Dir, &m_Prev->GetLink().m_Dir);
136 if(dddot<-0.999f && fabsf(dpdot)>0.999f
137 || dddot>0.999f && dpdot<0.0f) return false;
138 }
139 }
140 if(link.m_Link){
141 *m_Link.rbegin() = link;
142 VEC3 tpos = V3ZERO;
143 int i, n = 0;
144 for(i = 0; i<m_Link.size(); i++){
145 if(m_Link[i].m_Link){
146 tpos += m_Link[i].m_Pos;
147 n++;
148 }
149 }
150 SetPos(tpos/n, 0);
151 }
152 return true;
153 }
154
155 /*
156 * 最終点か調べる
157 */
158 bool CRailBuilder::IsLast(){
159 return !m_Next || m_Prev && m_Link.size()==ms_TrackNum && m_Link[ms_TrackNum-1].m_Link
160 || V3Len(&(m_Next->m_Pos-m_Pos))<CORNER_MIN_DIST;
161 }
162
163 /*
164 * right ベクトル計算
165 */
166 void CRailBuilder::CalcRight(
167 VEC3 *r1, VEC3 *d1, // 点 1
168 VEC3 *r2, VEC3 *d2 // 点 2
169 ){
170 V3Norm(r1, &VEC3(-d1->z, 0.0f, d1->x));
171 V3Norm(r2, &VEC3(-d2->z, 0.0f, d2->x));
172 }
173
174 /*
175 * 分割座標計算
176 */
177 VEC3 CRailBuilder::CalcSplitPos(){
178 if(m_Next){
179 if(m_Prev && m_Next->m_Next){
180 float len0 = V3Len(&(m_Next->m_Pos-m_Pos));
181 float len1 = V3Len(&(m_Pos-m_Prev->m_Pos));
182 float len2 = V3Len(&(m_Next->m_Next->m_Pos-m_Next->m_Pos));
183 if(!m_Prev->m_Prev) len1 *= 2.0f;
184 if(m_Next->m_Next->IsLast()) len2 *= 2.0f;
185 if(len0<len1) len1 = len0;
186 if(len0<len2) len2 = len0;
187 return (len2*m_Pos+len1*m_Next->m_Pos)/(len1+len2);
188 }else{
189 return 0.5f*(m_Pos+m_Next->m_Pos);
190 }
191 }else{
192 return m_Pos;
193 }
194 }
195
196 /*
197 * トラック座標計算
198 */
199 VEC3 CRailBuilder::CalcTrackPos(
200 VEC3 *right // 右ベクトル
201 ){
202 return *right*ms_TrackShift;
203 }
204
205 /*
206 * 曲線計算
207 */
208 bool CRailBuilder::Curve(
209 CRailCurve *curve, // 曲線オブジェクト
210 CRailPlugin *rpi, // レールプラグイン
211 CTiePlugin *tpi, // 枕木プラグイン
212 CGirderPlugin *gpi // 橋桁プラグイン
213 ){
214 VEC3 hfix = V3ZERO;
215 if(ms_LiftRailSurface) hfix.y = rpi ? rpi->m_SurfaceAlt :
216 (tpi ? tpi->m_Height : 0.0f)+(gpi ? gpi->m_Height : 0.0f);
217 VEC3 pos1, right1, dir1, pos2, right2, dir2;
218 bool comp = false, linked1 = false, linked2 = false;
219 bool last0 = IsLast();
220 bool last1 = last0 || !m_Next || m_Next->IsLast();
221 bool last2 = last1 || !m_Next->m_Next || m_Next->m_Next->IsLast();
222 if(m_Prev){
223 if(!last0 && !last1){
224 pos1 = CalcSplitPos()+hfix;
225 dir1 = m_Next->m_Pos-m_Pos;
226 V3Norm(&dir1, &dir1);
227 if(m_Next->m_Next->CheckLink()){
228 linked2 = true;
229 pos2 = m_Next->m_Next->GetLink().m_Pos;
230 dir2 = -m_Next->m_Next->GetLink().m_Dir;
231 }else{
232 pos2 = hfix+((comp = !last2)
233 ? m_Next->CalcSplitPos() : m_Next->m_Next->m_Pos);
234 dir2 = m_Next->m_Next->m_Pos-m_Next->m_Pos;
235 }
236 V3Norm(&dir2, &dir2);
237 if(ms_CurrentTrack==ms_TrackNum){
238 if(last2){
239 pos2 = ms_EndPosSum/ms_TrackNum;
240 V3Norm(&dir2, &ms_EndDirSum);
241 }
242 }else{
243 if(last2){
244 ms_EndPosSum += pos2;
245 ms_EndDirSum += dir2;
246 }
247 }
248 CalcRight(&right1, &dir1, &right2, &dir2);
249 if(linked2) right2 = V3ZERO;
250 curve->Curve(R2L(pos1+CalcTrackPos(&right1)), dir1,
251 R2L(pos2+CalcTrackPos(&right2)), dir2, comp, true);
252 return true;
253 }
254 }else{
255 if(!last0){
256 if(CheckLink()){
257 linked1 = true;
258 pos1 = GetLink().m_Pos;
259 dir1 = GetLink().m_Dir;
260 }else{
261 pos1 = m_Pos+hfix;
262 dir1 = m_Next->m_Pos-m_Pos;
263 }
264 V3Norm(&dir1, &dir1);
265 if(last1){
266 if(m_Next->CheckLink()){
267 linked2 = true;
268 pos2 = m_Next->GetLink().m_Pos;
269 dir2 = -m_Next->GetLink().m_Dir;
270 if(!CheckLink()){
271 VEC3 r = pos2-pos1;
272 V3Norm(&r, &r);
273 dir1 = -dir2+2.0f*V3Dot(&r, &dir2)*r;
274 }
275 }else{
276 pos2 = m_Next->m_Pos+hfix;
277 if(CheckLink()){
278 VEC3 r = pos2-pos1;
279 V3Norm(&r, &r);
280 dir2 = -dir1+2.0f*V3Dot(&r, &dir1)*r;
281 }else{
282 dir2 = dir1;
283 }
284 }
285 }else{
286 if(m_Next->m_Next->CheckLink()){
287 linked2 = true;
288 pos2 = m_Next->m_Next->GetLink().m_Pos;
289 dir2 = -m_Next->m_Next->GetLink().m_Dir;
290 }else{
291 pos2 = hfix+((comp = !last2)
292 ? m_Next->CalcSplitPos() : m_Next->m_Next->m_Pos);
293 dir2 = m_Next->m_Next->m_Pos-m_Next->m_Pos;
294 }
295 }
296 V3Norm(&dir2, &dir2);
297 if(ms_CurrentTrack==ms_TrackNum){
298 pos1 = ms_BeginPosSum/ms_TrackNum;
299 V3Norm(&dir1, &ms_BeginDirSum);
300 if(last1 || last2){
301 pos2 = ms_EndPosSum/ms_TrackNum;
302 V3Norm(&dir2, &ms_EndDirSum);
303 }
304 }else{
305 ms_BeginPosSum += pos1;
306 ms_BeginDirSum += dir1;
307 if(last1 || last2){
308 ms_EndPosSum += pos2;
309 ms_EndDirSum += dir2;
310 }
311 }
312 CalcRight(&right1, &dir1, &right2, &dir2);
313 if(linked1) right1 = V3ZERO;
314 if(linked2) right2 = V3ZERO;
315 curve->Curve(R2L(pos1+CalcTrackPos(&right1)), dir1,
316 R2L(pos2+CalcTrackPos(&right2)), dir2, comp, true);
317 return true;
318 }
319 }
320 return false;
321 }
322
323 /*
324 * レンダリング
325 */
326 void CRailBuilder::Render(
327 CLineDumpL *dump, // ダンパ
328 CRailPlugin *rpi, // レールプラグイン
329 CTiePlugin *tpi, // 枕木プラグイン
330 CGirderPlugin *gpi, // 枕木プラグイン
331 bool draw // 描画フラグ
332 ){
333 VEC3 hfix = V3ZERO;
334 if(ms_LiftRailSurface) hfix.y = rpi ? rpi->m_SurfaceAlt :
335 (tpi ? tpi->m_Height : 0.0f)+(gpi ? gpi->m_Height : 0.0f);
336 if(draw){
337 bool renderlink = !IsLinkEmpty();
338 int i, lnum = 0;
339 if(renderlink){
340 devSetZRead(TRUE);
341 devSetZWrite(TRUE);
342 devSetLighting(TRUE);
343 for(i = 0; i<m_Link.size() && i<ms_TrackNum; i++){
344 if(!m_Link[i].m_Link) continue;
345 lnum++;
346 g_LinkObject.SetPos(m_Link[i].m_Pos);
347 g_LinkObject.SetDir(m_Link[i].m_Dir, m_Link[i].m_Up);
348 g_LinkObject.Render();
349 }
350 }
351 if(!m_Prev || renderlink){
352 devSetZRead(FALSE);
353 devSetZWrite(FALSE);
354 devSetLighting(FALSE);
355 devResetMaterial();
356 devResetMatrix();
357 if(renderlink){
358 if(m_Prev) g_StrTex->RenderLeft(
359 TILE_QUAD, TILE_UNIT*4+TILE_QUAD, 0xffffffff, 0xff000000,
360 FlashIn("%s: %d/%d", lang(JointDest), lnum, ms_TrackNum));
361 else g_StrTex->RenderLeft(
362 TILE_QUAD, TILE_UNIT*3+TILE_QUAD, 0xffffffff, 0xff000000,
363 FlashIn("%s: %d/%d", lang(JointSrc), lnum, ms_TrackNum));
364 }
365 }
366 }
367 devResetMatrix();
368 CRailPlanCurve curve(dump);
369 Curve(&curve, rpi, tpi, gpi);
370 if(m_HitFlag){
371 DrawTangent(m_HitPos, m_HitNorm, 0xffff0000, dump);
372 dump->Add(m_HitPos, 0xffff0000, m_Pos, 0x80ff0000);
373 //RailMapLine(m_HitPos, 0xffff0000, m_Pos, 0x80ff0000, false);
374 }
375 if(IsLast()){
376 if(m_Next){
377 if(m_Next->m_HitFlag){
378 DrawTangent(m_Next->m_HitPos, m_Next->m_HitNorm, 0xff0000ff, dump);
379 dump->Add(m_Next->m_HitPos, 0xff0000ff, m_Next->m_Pos, 0x800000ff);
380 //RailMapLine(m_Next->m_HitPos, 0xff0000ff, m_Next->m_Pos, 0x800000ff, false);
381 }
382 VEC3 pp1 = m_Pos+(CheckLink() ? -hfix : V3ZERO);
383 VEC3 pp2 = m_Next->m_Pos+(m_Next->CheckLink() ? -hfix : V3ZERO);
384 dump->Add(pp1, 0xc0ff0000, pp2, 0xc0ff0000);
385 RailMapLine(pp1, 0xc0ff0000, pp2, 0xc0ff0000, false);
386 }
387 if(draw){
388 dump->Render(true);
389 devSetZRead(TRUE);
390 devSetZWrite(TRUE);
391 devSetLighting(TRUE);
392 g_ArrowObject.SetPos(m_Next ? m_Next->m_Pos : m_Pos);
393 g_ArrowObject.RotY(2.0f*D3DX_PI/MAXFPS);
394 g_ArrowObject.Render();
395 }
396 }else{
397 VEC3 pp1 = m_Pos+(CheckLink() ? -hfix : V3ZERO);
398 VEC3 pp2 = m_Next->m_Pos+(m_Next->CheckLink() ? -hfix : V3ZERO);
399 dump->Add(pp1, 0xc0ff0000, pp2, 0xc0ff0000);
400 RailMapLine(pp1, 0xc0ff0000, pp2, 0xc0ff0000, false);
401 m_Next->Render(dump, rpi, tpi, gpi, draw);
402 }
403 }
404
405 /*
406 * 建設
407 */
408 void CRailBuilder::BuildRail(
409 CRailConnectorLink &begin, // 開始リンク
410 CRailConnectorLink &end, // 終了リンク
411 CRailPlugin *rpi, // レールプラグイン
412 CTiePlugin *tpi, // 枕木プラグイン
413 CGirderPlugin *gpi // 枕木プラグイン
414 ){
415 if(!ms_CurrentTrack){
416 g_MultiTrackRailList.push_back(list<list<CRailWay *> >());
417 g_MultiTrackSegment = --g_MultiTrackRailList.end();
418 }
419 g_MultiTrackSegment->push_back(list<CRailWay *>());
420 g_SingleTrackSegment = --g_MultiTrackSegment->end();
421 if(m_Next->IsLast() || m_Next->m_Next && m_Next->m_Next->IsLast()){
422 CRailBuildCurve curve(begin, end, rpi, tpi, gpi);
423 Curve(&curve, rpi, tpi, gpi);
424 }else{
425 CRailBuildCurve curve(begin, R2L(CRailConnectorLink()), rpi, tpi, gpi);
426 Curve(&curve, rpi, tpi, gpi);
427 g_MultiTrackSegment++;
428 m_Next->BuildRail(curve.GetNext(), end, rpi, tpi, gpi);
429 }
430 }
431
432 ////////////////////////////////////////////////////////////////////////////////
433 ////////////////////////////////////////////////////////////////////////////////
434
435 /*
436 * コンストラクタ
437 */
438 CRailLinkTemp::CRailLinkTemp(
439 int side, // サイド
440 float sumlen, // 積算距離
441 VEC3 &pos, // 座標
442 VEC3 &right, // right
443 VEC3 &up, // up
444 VEC3 &dir, // dir
445 CRailWay *link, // 接続レール
446 IRailSplitter sit // splice 位置
447 ){
448 m_Side = side;
449 m_SumLen = sumlen;
450 m_SpliceItr = sit;
451 m_Pos = pos;
452 m_Right = right;
453 m_Up = up;
454 m_Dir = dir;
455 m_Link = link;
456 }

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