Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CTrainPlugin.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: 27628 byte(s)
[okadu] Version 2.15
橋脚・架線柱手動設置機能
車輌プラグイン以外でクランク等使用可能に
エンジン模型プラグイン追加

1 #include "stdafx.h"
2 #include "CCamera.h"
3 #include "CTrainPlugin.h"
4 #include "CTrainGroupTemplate.h"
5 #include "CTrain.h"
6 #include "CTrainEditMode.h"
7 #include "CSimulationMode.h"
8 #include "CConfigMode.h"
9 #include "CSaveFile.h"
10
11 // 外部グローバル
12 extern bool g_MoverEnabled;
13
14 // 内部グローバル
15 CTrainPlugin *g_Train = NULL; // 車輌プラグイン
16
17 /*
18 * 読込
19 */
20 char *CObjectJointZY::Read(
21 char *str, // 対象文字列
22 CModelPlugin *mpi // モデルプラグイン
23 ){
24 char *eee;
25 string obj;
26 if(!(str = BeginNamedBlock(eee = str, "JointZY", &obj))) return NULL;
27 if(!(m_Link = FindObjectHybrid(mpi, obj)))
28 throw CSynErr(eee, "%s: \"%s\"", lang(UndefinedObject), obj.c_str());
29 if(!(str = AsgnVector2D(eee = str, "AttachCoord", &m_AttachCoord))) throw CSynErr(eee);
30 if(!(str = AsgnVector2D(eee = str, "LocalCoord", &m_LocalCoord))) throw CSynErr(eee);
31 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
32 return str;
33 }
34
35 ////////////////////////////////////////////////////////////////////////////////
36 ////////////////////////////////////////////////////////////////////////////////
37
38 /*
39 * 読込
40 */
41 char *CObjectJointZYX::Read(
42 char *str, // 対象文字列
43 CModelPlugin *mpi // モデルプラグイン
44 ){
45 char *tmp, *eee;
46 string obj;
47 if(!(str = BeginNamedBlock(eee = str, "JointZYX", &obj))) return NULL;
48 if(!(m_Link = FindObjectHybrid(mpi, obj)))
49 throw CSynErr(eee, "%s: \"%s\"", lang(UndefinedObject), obj.c_str());
50 if(tmp = AsgnFloat(str, "AttachX", &m_AttachX)) str = tmp;
51 else m_AttachX = 0.0f;
52 if(!(str = AsgnVector2D(eee = str, "AttachCoord", &m_AttachCoord))) throw CSynErr(eee);
53 if(!(str = AsgnVector2D(eee = str, "LocalCoord", &m_LocalCoord))) throw CSynErr(eee);
54 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
55 return str;
56 }
57
58 ////////////////////////////////////////////////////////////////////////////////
59 ////////////////////////////////////////////////////////////////////////////////
60
61 /*
62 * 読込
63 */
64 char *CAxleObject::Read(
65 char *str, // 対象文字列
66 CModelPlugin *mpi // モデルプラグイン
67 ){
68 char *tmp, *eee;
69 if(!(str = BeginNamedBlock(eee = str, "Axle", &m_ObjectName))) return NULL;
70 CheckObjectHybrid(eee, mpi, m_ObjectName);
71 if(!(str = ReadModelInfo(eee = str, mpi))) throw CSynErr(eee);
72 if(!(str = AsgnFloat(eee = str, "Diameter", &m_Diameter))) throw CSynErr(eee);
73 if(!(str = AsgnInteger(eee = str, "Symmetric", &m_Symmetric))) throw CSynErr(eee);
74 if(m_Symmetric<1) m_Symmetric = 1;
75 m_MaxRotation = SYMMETRIC_ROTATION_MAX/m_Symmetric;
76 if(!(str = AsgnVector2D(eee = str, "Coord", &m_Coord))) throw CSynErr(eee);
77 if(tmp = AsgnYesNo(eee = str, "WheelSound", &m_WheelSound)) str = tmp;
78 else m_WheelSound = true;
79 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
80 mpi->AddPartsNum(1);
81 return str;
82 }
83
84 /*
85 * プレビュー用姿勢設定
86 */
87 float CAxleObject::CalcRotation(
88 float dist // 進行距離
89 ){
90 if(!m_Diameter) return 0.0f;
91 float tmp = m_MaxRotation*(1.0f-expf(-fabsf(dist)/(m_MaxRotation*m_Diameter*D3DX_PI)));
92 return dist<0.0f ? -tmp : tmp;
93 }
94
95 /*
96 * プレビュー用姿勢設定
97 */
98 void CAxleObject::SetPreview(
99 float offset, // オフセット
100 bool reverse // 反転
101 ){
102 SetMesh(m_LastObject = &m_PreviewObject);
103 m_PreviewObject.SetPos(VEC3(0.0f, m_Coord.y, offset+(reverse ? -m_Coord.x : m_Coord.x)));
104 m_PreviewObject.SetDir(reverse ? -V3DIR : V3DIR, m_Turn ? -V3UP : V3UP);
105 }
106
107 /*
108 * 姿勢設定
109 */
110 void CAxleObject::SetPosture(
111 VEC3 pos, // 座標
112 VEC3 dir, // dir
113 VEC3 up, // up
114 float rot // 回転量
115 ){
116 CObject *obj = GetPartsObject();
117 SetMesh(obj);
118 obj->SetPos(pos+m_Coord.y*up);
119 obj->SetDir(dir, m_Turn ? -up : up);
120 if(m_Diameter) obj->RotX(2.0f*D3DX_PI*rot);
121 }
122
123 ////////////////////////////////////////////////////////////////////////////////
124 ////////////////////////////////////////////////////////////////////////////////
125
126 // static メンバ
127 VEC3 CBodyObject::ms_TiltDir;
128
129 /*
130 * 読込
131 */
132 char *CBodyObject::Read(
133 char *str, // 対象文字列
134 CModelPlugin *mpi // モデルプラグイン
135 ){
136 char *tmp, *eee;
137 if(!(str = BeginNamedBlock(eee = str, "Body", &m_ObjectName))) return NULL;
138 CheckObjectHybrid(eee, mpi, m_ObjectName);
139 if(!(str = ReadModelInfo(eee = str, mpi))) throw CSynErr(eee);
140 if(!(str = m_Joint1.Read(eee = str, mpi))) throw CSynErr(eee);
141 if(!(str = m_Joint2.Read(eee = str, mpi))) throw CSynErr(eee);
142
143 if(tmp = BeginBlock(str, "Tilt")){
144 str = tmp;
145 if(!(str = AsgnFloat(eee = str, "TiltRatio", &m_TiltRatio))) throw CSynErr(eee);
146 if(!(str = AsgnFloat(eee = str, "MaxAngle", &m_TiltMaxAngle))) throw CSynErr(eee);
147 if(!(str = AsgnFloat(eee = str, "BaseAlt", &m_TiltBaseAlt))) throw CSynErr(eee);
148 m_TiltMaxAngle = D3DXToRadian(m_TiltMaxAngle);
149 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
150 }else{
151 m_TiltMaxAngle = 0.0f;
152 }
153
154 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
155 mpi->AddPartsNum(1);
156 return str;
157 }
158
159 /*
160 * 姿勢設定
161 */
162 void CBodyObject::SetPosture(){
163 CObject *obj = GetPartsObject();
164 SetMesh(obj);
165 VEC2 sdir = m_Joint2.m_LocalCoord-m_Joint1.m_LocalCoord;
166 VEC3 j1 = m_Joint1.GetPos(), j2 = m_Joint2.GetPos(), wdir = j2-j1;
167 VEC3 right = m_Joint1.GetRight()+m_Joint2.GetRight();
168 float slen = V2Len(&sdir), wlen = V3Len(&wdir);
169 V3Norm(&wdir, &wdir);
170 VEC3 cpos = 0.5f*(j1+j2), w90;
171 V3Norm(&w90, V3Cross(&w90, &wdir, &right));
172 VEC3 ldir = sdir.x*wdir-(m_Turn ? -sdir.y : sdir.y)*w90, lup;
173 V3Cross(&lup, &ldir, &right);
174 obj->SetDir(ldir, m_Turn ? -lup : lup);
175 VEC3 dif = 0.5f*VEC2toVEC3(m_Joint1.m_LocalCoord+m_Joint2.m_LocalCoord);
176 V3Norm(&ldir, &obj->GetDir());
177 V3Norm(&lup, &obj->GetUp());
178 VEC3 pos = cpos-dif.x*ldir-dif.y*lup;
179 if(m_TiltMaxAngle){
180 float tilt = m_TiltRatio*V3Dot(&ms_TiltDir, V3Norm(&right, &right));
181 float tmp = m_TiltMaxAngle*(1.0f-expf(-fabsf(tilt)/m_TiltMaxAngle));
182 tilt = tilt<0.0f ? -tmp : tmp;
183 pos += m_TiltBaseAlt*lup;
184 obj->RotZ(tilt);
185 V3Norm(&lup, &obj->GetUp());
186 obj->SetPos(pos-m_TiltBaseAlt*lup);
187 }else{
188 obj->SetPos(pos);
189 }
190 }
191
192 ////////////////////////////////////////////////////////////////////////////////
193 ////////////////////////////////////////////////////////////////////////////////
194
195 /*
196 * コンストラクタ
197 */
198 CFreeObjectContainer::CFreeObjectContainer(){
199 m_FreeObject = NULL;
200 }
201
202 /*
203 * コピーコンストラクタ
204 */
205 CFreeObjectContainer::CFreeObjectContainer(
206 const CFreeObjectContainer &src // コピー元
207 ){
208 m_FreeObject = src.m_FreeObject->Duplicate();
209 }
210
211 /*
212 * コピーコンストラクタ
213 */
214 CFreeObjectContainer::CFreeObjectContainer(
215 CFreeObject3D *obj3d // obj
216 ){
217 m_FreeObject = obj3d;
218 }
219
220 /*
221 * デストラクタ
222 */
223 CFreeObjectContainer::~CFreeObjectContainer(){
224 DELETE_V(m_FreeObject);
225 }
226
227 /*
228 * 読込
229 */
230 char *CFreeObjectContainer::Read(
231 char *str, // 対象文字列
232 CModelPlugin *mpi // モデルプラグイン
233 ){
234 char *tmp;
235 DELETE_V(m_FreeObject);
236 CFreeObject3D object3d;
237 CFreeObjectZY objectzy;
238 CFreeTriangleZY trianglezy;
239 CFreeCrankZY crankzy;
240 CFreePistonZY pistonzy;
241 if(tmp = object3d.Read(str, mpi)){
242 str = tmp;
243 m_FreeObject = new CFreeObject3D(object3d);
244 }else if(tmp = objectzy.Read(str, mpi)){
245 str = tmp;
246 m_FreeObject = new CFreeObjectZY(objectzy);
247 }else if(tmp = trianglezy.Read(str, mpi)){
248 str = tmp;
249 m_FreeObject = new CFreeTriangleZY(trianglezy);
250 }else if(tmp = crankzy.Read(str, mpi)){
251 str = tmp;
252 m_FreeObject = new CFreeCrankZY(crankzy);
253 }else if(tmp = pistonzy.Read(str, mpi)){
254 str = tmp;
255 m_FreeObject = new CFreePistonZY(pistonzy);
256 }else{
257 str = NULL;
258 }
259 return str;
260 }
261
262 ////////////////////////////////////////////////////////////////////////////////
263 ////////////////////////////////////////////////////////////////////////////////
264
265 /*
266 * 読込
267 */
268 char *CFreeObjectZY::Read(
269 char *str, // 対象文字列
270 CModelPlugin *mpi // モデルプラグイン
271 ){
272 char *tmp, *eee;
273 if(!(str = BeginNamedBlock(eee = str, "ObjectZY", &m_ObjectName))) return NULL;
274 CheckObjectHybrid(eee, mpi, m_ObjectName);
275 if(!(str = ReadModelInfo(eee = str, mpi))) throw CSynErr(eee);
276 if(tmp = AsgnFloat(str, "FixPosition", &m_FixPosition)) str = tmp;
277 else m_FixPosition = 0.5f;
278 if(tmp = AsgnFloat(str, "FixRight", &m_FixRight)) str = tmp;
279 else m_FixRight = m_FixPosition;
280 if(!(str = m_Joint1.Read(eee = str, mpi))) throw CSynErr(eee);
281 if(!(str = m_Joint2.Read(eee = str, mpi))) throw CSynErr(eee);
282 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
283 mpi->AddPartsNum(1);
284 return str;
285 }
286
287 /*
288 * 姿勢設定
289 */
290 void CFreeObjectZY::SetPostureFreeObject(){
291 CObject *obj = GetPartsObject();
292 SetMesh(obj);
293 VEC2 sdir = m_Joint2.m_LocalCoord-m_Joint1.m_LocalCoord;
294 VEC3 j1 = m_Joint1.GetPos(), j2 = m_Joint2.GetPos(), wdir = j2-j1;
295 VEC3 right = (1.0f-m_FixRight)*m_Joint1.GetRight()
296 +m_FixRight*m_Joint2.GetRight(), w90;
297 float slen = V2Len(&sdir), wlen = V3Len(&wdir);
298 V3Norm(&wdir, &wdir);
299 V3Norm(&right, &right);
300 VEC3 cpos = (1.0f-m_FixPosition)*j1+m_FixPosition*j2;
301 V3Norm(&w90, V3Cross(&w90, &wdir, &right));
302 VEC3 ldir = sdir.x*wdir-(m_Turn ? -sdir.y : sdir.y)*w90, lup;
303 V3Cross(&lup, &ldir, &right);
304 obj->SetDir(ldir, m_Turn ? -lup : lup);
305 VEC3 dif = VEC2toVEC3((1.0f-m_FixPosition)*m_Joint1.m_LocalCoord
306 +m_FixPosition*m_Joint2.m_LocalCoord);
307 V3Norm(&ldir, &obj->GetDir());
308 V3Norm(&lup, &obj->GetUp());
309 obj->SetPos(cpos-dif.x*ldir-dif.y*lup);
310 }
311
312 ////////////////////////////////////////////////////////////////////////////////
313 ////////////////////////////////////////////////////////////////////////////////
314
315 /*
316 * 読込
317 */
318 char *CTriangleLinkZY::Read(
319 char *str, // 対象文字列
320 CModelPlugin *mpi // モデルプラグイン
321 ){
322 char *eee;
323 if(!(str = BeginNamedBlock(eee = str, "Link", &m_ObjectName))) return NULL;
324 CheckObjectHybrid(eee, mpi, m_ObjectName);
325 if(!(str = ReadModelInfo(eee = str, mpi))) throw CSynErr(eee);
326 if(!(str = m_Joint.Read(eee = str, mpi))) throw CSynErr(eee);
327 if(!(str = AsgnVector2D(eee = str, "LinkCoord", &m_LinkCoord))) throw CSynErr(eee);
328 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
329 return str;
330 }
331
332 ////////////////////////////////////////////////////////////////////////////////
333 ////////////////////////////////////////////////////////////////////////////////
334
335 /*
336 * 読込
337 */
338 char *CFreeTriangleZY::Read(
339 char *str, // 対象文字列
340 CModelPlugin *mpi // モデルプラグイン
341 ){
342 char *eee;
343 if(!(str = BeginBlock(str, "TriangleZY"))) return NULL;
344 if(!(str = m_Link1.Read(eee = str, mpi))) throw CSynErr(eee);
345 if(!(str = m_Link2.Read(eee = str, mpi))) throw CSynErr(eee);
346 if(m_Link1.Check(m_Link2.GetName()))
347 throw CSynErr(eee, "%s: \"%s\"", lang(OverlappedObjectName), m_Link2.GetName());
348 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
349 mpi->AddPartsNum(2);
350 return str;
351 }
352
353 /*
354 * 読込
355 */
356 void CFreeTriangleZY::SetPostureFreeObject(){
357 CObject *obj1 = m_Link1.GetPartsObject();
358 CObject *obj2 = m_Link2.GetPartsObject();
359 m_Link1.SetMesh(obj1);
360 m_Link2.SetMesh(obj2);
361 VEC2 &lc1 = m_Link1.m_Joint.m_LocalCoord, sdir1 = m_Link1.m_LinkCoord-lc1;
362 VEC2 &lc2 = m_Link2.m_Joint.m_LocalCoord, sdir2 = m_Link2.m_LinkCoord-lc2;
363 VEC3 j1 = m_Link1.m_Joint.GetPos();
364 VEC3 j2 = m_Link2.m_Joint.GetPos(), wdir = j2-j1;
365 VEC3 right = m_Link1.m_Joint.GetRight()+m_Link2.m_Joint.GetRight(), w90;
366 float slen1 = V2Len(&sdir1), slen2 = V2Len(&sdir2), wlen = V3Len(&wdir);
367 V3Norm(&wdir, &wdir);
368 V3Norm(&right, &right);
369 V3Norm(&w90, V3Cross(&w90, &wdir, &right));
370 float px = (wlen*wlen+slen1*slen1-slen2*slen2)*0.5f/wlen;
371 float py2 = slen1*slen1-px*px, py = py2<0.0f ? 0.5f*wlen : -sqrtf(py2);
372 VEC3 ppos = j1+px*wdir+py*w90, w11, w12, w21, w22;
373 V3Norm(&w12, V3Cross(&w12, V3Norm(&w11, &(ppos-j1)), &right));
374 V3Norm(&w22, V3Cross(&w22, V3Norm(&w21, &(ppos-j2)), &right));
375 VEC3 ldir1 = sdir1.x*w11-(m_Link1.m_Turn ? -sdir1.y : sdir1.y)*w12, lup1;
376 VEC3 ldir2 = sdir2.x*w21-(m_Link2.m_Turn ? -sdir2.y : sdir2.y)*w22, lup2;
377 V3Cross(&lup1, &ldir1, &right);
378 V3Cross(&lup2, &ldir2, &right);
379 obj1->SetDir(ldir1, m_Link1.m_Turn ? -lup1 : lup1);
380 obj2->SetDir(ldir2, m_Link2.m_Turn ? -lup2 : lup2);
381 V3Norm(&ldir1, &obj1->GetDir());
382 V3Norm(&ldir2, &obj2->GetDir());
383 V3Norm(&lup1, &obj1->GetUp());
384 V3Norm(&lup2, &obj2->GetUp());
385 obj1->SetPos(j1-lc1.x*ldir1-lc1.y*lup1);
386 obj2->SetPos(j2-lc2.x*ldir2-lc2.y*lup2);
387 }
388
389 ////////////////////////////////////////////////////////////////////////////////
390 ////////////////////////////////////////////////////////////////////////////////
391
392 /*
393 * 読込
394 */
395 char *CCrankSlideZY::Read(
396 char *str, // 対象文字列
397 CModelPlugin *mpi // モデルプラグイン
398 ){
399 char *eee;
400 if(!(str = BeginNamedBlock(eee = str, "Slide", &m_ObjectName))) return NULL;
401 CheckObjectHybrid(eee, mpi, m_ObjectName);
402 if(!(str = ReadModelInfo(eee = str, mpi))) throw CSynErr(eee);
403 if(!(str = m_Joint.Read(eee = str, mpi))) throw CSynErr(eee);
404 if(!(str = AsgnVector2D(eee = str, "Direction", &m_Direction))) throw CSynErr(eee);
405 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
406 return str;
407 }
408
409 ////////////////////////////////////////////////////////////////////////////////
410 ////////////////////////////////////////////////////////////////////////////////
411
412 /*
413 * 読込
414 */
415 char *CFreeCrankZY::Read(
416 char *str, // 対象文字列
417 CModelPlugin *mpi // モデルプラグイン
418 ){
419 char *eee;
420 if(!(str = BeginBlock(str, "CrankZY"))) return NULL;
421 if(!(str = m_Link.Read(eee = str, mpi))) throw CSynErr(eee);
422 if(!(str = m_Slide.Read(eee = str, mpi))) throw CSynErr(eee);
423 if(m_Link.Check(m_Slide.GetName()))
424 throw CSynErr(eee, "%s: \"%s\"", lang(OverlappedObjectName), m_Slide.GetName());
425 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
426 mpi->AddPartsNum(2);
427 return str;
428 }
429
430 /*
431 * 読込
432 */
433 void CFreeCrankZY::SetPostureFreeObject(){
434 CObject *obj1 = m_Link.GetPartsObject();
435 CObject *obj2 = m_Slide.GetPartsObject();
436 m_Link.SetMesh(obj1);
437 m_Slide.SetMesh(obj2);
438 VEC3 sldir = m_Slide.m_Joint.GetDir(), slup = m_Slide.m_Joint.GetUp();
439 VEC3 direction = m_Slide.m_Direction.x*sldir+m_Slide.m_Direction.y*slup;
440 V3Norm(&direction, &direction);
441 VEC2 &lc1 = m_Link.m_Joint.m_LocalCoord, sdir1 = m_Link.m_LinkCoord-lc1;
442 VEC2 &lc2 = m_Slide.m_Joint.m_LocalCoord;
443 VEC3 j1 = m_Link.m_Joint.GetPos();
444 VEC3 j2 = m_Slide.m_Joint.GetPos(), wdir = j2-j1;
445 VEC3 right = m_Link.m_Joint.GetRight()+m_Slide.m_Joint.GetRight(), w90;
446 float lldcos = V3Dot(&wdir, &direction), lldsin = V3Len(&(wdir-lldcos*direction));
447 float slen1 = V2Len(&sdir1), llofs = slen1*slen1-lldsin*lldsin;
448 VEC3 lljpos = j2+((llofs<0.0f ? 0.0f : sqrtf(llofs))-lldcos)*direction;
449 wdir = lljpos-j1;
450 float wlen = V3Len(&wdir);
451 V3Norm(&wdir, &wdir);
452 V3Norm(&right, &right);
453 V3Norm(&w90, V3Cross(&w90, &wdir, &right));
454 VEC3 ldir1 = sdir1.x*wdir-(m_Link.m_Turn ? -sdir1.y : sdir1.y)*w90, lup1;
455 VEC3 lup2 = -m_Slide.m_Direction.y*sldir+m_Slide.m_Direction.x*slup;
456 V3Cross(&lup1, &ldir1, &right);
457 obj1->SetDir(ldir1, m_Link.m_Turn ? -lup1 : lup1);
458 obj2->SetDir(direction, m_Slide.m_Turn ? -lup2 : lup2);
459 V3Norm(&ldir1, &obj1->GetDir());
460 V3Norm(&lup1, &obj1->GetUp());
461 obj1->SetPos(j1-lc1.x*ldir1-lc1.y*lup1);
462 obj2->SetPos(lljpos);
463 }
464
465 ////////////////////////////////////////////////////////////////////////////////
466 ////////////////////////////////////////////////////////////////////////////////
467
468 /*
469 * 読込
470 */
471 char *CFreePistonZY::Read(
472 char *str, // 対象文字列
473 CModelPlugin *mpi // モデルプラグイン
474 ){
475 char *eee;
476 if(!(str = BeginBlock(str, "PistonZY"))) return NULL;
477 if(!(str = m_Link1.Read(eee = str, mpi))) throw CSynErr(eee);
478 if(!(str = m_Link2.Read(eee = str, mpi))) throw CSynErr(eee);
479 if(m_Link1.Check(m_Link2.GetName()))
480 throw CSynErr(eee, "%s: \"%s\"", lang(OverlappedObjectName), m_Link2.GetName());
481 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
482 mpi->AddPartsNum(2);
483 return str;
484 }
485
486 /*
487 * 読込
488 */
489 void CFreePistonZY::SetPostureFreeObject(){
490 CObject *obj1 = m_Link1.GetPartsObject();
491 CObject *obj2 = m_Link2.GetPartsObject();
492 m_Link1.SetMesh(obj1);
493 m_Link2.SetMesh(obj2);
494 VEC2 &lc1 = m_Link1.m_Joint.m_LocalCoord, sdir1 = m_Link1.m_LinkCoord-lc1;
495 VEC2 &lc2 = m_Link2.m_Joint.m_LocalCoord, sdir2 = m_Link2.m_LinkCoord-lc2;
496 VEC3 j1 = m_Link1.m_Joint.GetPos();
497 VEC3 j2 = m_Link2.m_Joint.GetPos(), wdir = j2-j1;
498 VEC3 right = m_Link1.m_Joint.GetRight()+m_Link2.m_Joint.GetRight(), w90;
499 float slen1 = V2Len(&sdir1), slen2 = V2Len(&sdir2), wlen = V3Len(&wdir);
500 V3Norm(&wdir, &wdir);
501 V3Norm(&right, &right);
502 V3Norm(&w90, V3Cross(&w90, &wdir, &right));
503 VEC3 ppos = 0.5f*(j1+j2), w11, w12, w21, w22;
504 V3Norm(&w12, V3Cross(&w12, V3Norm(&w11, &(ppos-j1)), &right));
505 V3Norm(&w22, V3Cross(&w22, V3Norm(&w21, &(ppos-j2)), &right));
506 VEC3 ldir1 = sdir1.x*w11-(m_Link1.m_Turn ? -sdir1.y : sdir1.y)*w12, lup1;
507 VEC3 ldir2 = sdir2.x*w21-(m_Link2.m_Turn ? -sdir2.y : sdir2.y)*w22, lup2;
508 V3Cross(&lup1, &ldir1, &right);
509 V3Cross(&lup2, &ldir2, &right);
510 obj1->SetDir(ldir1, m_Link1.m_Turn ? -lup1 : lup1);
511 obj2->SetDir(ldir2, m_Link2.m_Turn ? -lup2 : lup2);
512 V3Norm(&ldir1, &obj1->GetDir());
513 V3Norm(&ldir2, &obj2->GetDir());
514 V3Norm(&lup1, &obj1->GetUp());
515 V3Norm(&lup2, &obj2->GetUp());
516 obj1->SetPos(j1-lc1.x*ldir1-lc1.y*lup1);
517 obj2->SetPos(j2-lc2.x*ldir2-lc2.y*lup2);
518 }
519
520 ////////////////////////////////////////////////////////////////////////////////
521 ////////////////////////////////////////////////////////////////////////////////
522
523 /*
524 * [static]
525 * プレビュー
526 */
527 void CTrainPlugin::RenderPreview(){
528 CNamedObjectAfterRenderer::SetCurrentInst(NULL);
529 g_SaveFile->ResetSwitch();
530 if(ms_PreviewState && g_Train) g_Train->Preview(0.0f, false);
531 }
532
533 /*
534 * デストラクタ
535 */
536 CTrainPlugin::~CTrainPlugin(){
537 }
538
539 /*
540 * ロード
541 */
542 bool CTrainPlugin::Load(){
543 char *str = m_Script, *tmp, *eee;
544 if(!ChDir() || !m_Script) return false;
545 g_NamedObjectMipMap = g_TrainMipMap;
546 CNamedObject::SetCastShadowDefault(true);
547 try{
548 if(!(str = BeginBlock(eee = str, "TrainInfo"))) throw CSynErr(eee);
549 if(!(str = AsgnFloat(eee = str, "FrontLimit", &m_FrontLimit))) throw CSynErr(eee);
550 if(!(str = AsgnFloat(eee = str, "TailLimit", &m_TailLimit))) throw CSynErr(eee);
551 if((m_Length = m_FrontLimit-m_TailLimit)<0.0f) throw CSynErr(eee, lang(InvalidTrainLength));
552 if(!(str = AsgnFloat(eee = str, "MaxVelocity", &m_MaxVelocity))) throw CSynErr(eee);
553 if(!(str = AsgnFloat(eee = str, "MaxAcceleration", &m_MaxAcceleration))) throw CSynErr(eee);
554 if(!(str = AsgnFloat(eee = str, "MaxDeceleration", &m_MaxDeceleration))) throw CSynErr(eee);
555 if(tmp = AsgnFloat(str, "TiltSpeed", &m_TiltSpeed)) str = tmp;
556 else m_TiltSpeed = 1.0;
557 if(tmp = AsgnFloat(str, "DoorClosingTime", &m_DoorClosingTime)) str = tmp;
558 else m_DoorClosingTime = 0.0;
559 // [km/h/sec] to [km/h/frame]
560 m_MaxAcceleration /= MAXFPS;
561 m_MaxDeceleration /= MAXFPS;
562 if(m_MaxVelocity<0.0f) m_MaxVelocity = 0.0f;
563 if(m_MaxAcceleration<0.0f) m_MaxVelocity = 0.0f;
564 if(m_MaxDeceleration<0.0f) m_MaxDeceleration = 0.0f;
565 ValueArea(&m_TiltSpeed, 0.0f, 1.0f);
566 if(m_DoorClosingTime<0.0f) m_DoorClosingTime = 0.0f;
567 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
568
569 if(!(str = ReadModelSwitch(eee = str))) throw CSynErr(eee);
570
571 if(!(str = BeginBlock(eee = str, "PrimaryAssembly"))) throw CSynErr(eee);
572 CAxleObject axleobj;
573 while(tmp = axleobj.Read(str, this)){
574 str = tmp;
575 m_AxleObject.push_back(axleobj);
576 }
577 m_AxleObject.sort();
578 CBodyObject bodyobj;
579 while(tmp = bodyobj.Read(str, this)){
580 str = tmp;
581 m_BodyObject.push_back(bodyobj);
582 }
583 CFreeObjectContainer freeobj;
584 while(tmp = freeobj.Read(str, this)){
585 str = tmp;
586 m_FreeObject.push_back(freeobj);
587 }
588 if(!(str = ReadEffect(eee = str))) throw CSynErr(eee);
589 if(tmp = BeginBlock(eee = str, "FrontCabin")){
590 str = tmp;
591 if(!(str = m_FrontCabin.Read(eee = str, this))) throw CSynErr(eee);
592 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
593 }
594 if(tmp = BeginBlock(eee = str, "TailCabin")){
595 str = tmp;
596 if(!(str = m_TailCabin.Read(eee = str, this))) throw CSynErr(eee);
597 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
598 }
599 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
600
601 if(*(eee = str)) throw CSynErr(eee);
602 }
603 catch(CSynErr err){
604 HandleError(&err);
605 return false;
606 }
607 IAxleObject iao = m_AxleObject.begin();
608 for(; iao!=m_AxleObject.end(); iao++) iao->LoadModel(this);
609 IBodyObject ibo = m_BodyObject.begin();
610 for(; ibo!=m_BodyObject.end(); ibo++) ibo->LoadModel(this);
611 IFreeObjectContainer ifo = m_FreeObject.begin();
612 for(; ifo!=m_FreeObject.end(); ifo++) ifo->LoadModel(this);
613 LoadData();
614 DELETE_A(m_Buffer);
615 return true;
616 }
617
618 /*
619 * ロード
620 */
621 bool CTrainPlugin::LoadOldForm(){
622 if(!ChDir()) return false;
623 g_NamedObjectMipMap = g_StructMipMap;
624 CNamedObject::SetCastShadowDefault(true);
625 FILE *file = fopen(TextName(), "rt");
626 char *dummy = FlashOut();
627 float sc, itv, len, spd;
628 fscanf(file, "%s %s %f %f %f %f", dummy, dummy, &sc, &itv, &len, &spd);
629 fclose(file);
630 float oldscale = 2.0f/sc;
631 itv *= oldscale;
632 len *= oldscale;
633 m_FrontLimit = len*0.5f+0.3f;
634 m_TailLimit = -m_FrontLimit;
635 m_Length = m_FrontLimit-m_TailLimit;
636 m_MaxVelocity = spd*10.0f;
637 m_MaxAcceleration = 3.0f/MAXFPS;
638 m_MaxDeceleration = 4.0f/MAXFPS;
639 m_TiltSpeed = 1.0f;
640 m_DoorClosingTime = 0.0f;
641 if(m_MaxVelocity<0.0f) m_MaxVelocity = 0.0f;
642 CAxleObject axle;
643 axle.m_ObjectName = "Wheel1";
644 axle.m_ModelFileName = "";
645 axle.m_ModelScale = 1.0f;
646 axle.m_Turn = false;
647 axle.m_Diameter = 1.0f;
648 axle.m_Symmetric = 1;
649 axle.m_MaxRotation = 1.0f;
650 axle.m_Coord = VEC2(0.5f*itv, 0.0f);
651 axle.m_WheelSound = false;
652 m_AxleObject.push_back(axle);
653 axle.m_ObjectName = "Wheel2";
654 axle.m_Coord = VEC2(-0.5f*itv, 0.0f);
655 m_AxleObject.push_back(axle);
656 CBodyObject body;
657 body.m_ObjectName = "MainBody";
658 body.m_ModelFileName = "Model.x";
659 body.m_ModelScale = oldscale;
660 body.m_Turn = true;
661 body.m_TiltMaxAngle = 0.0f;
662 body.m_Joint1.m_AttachCoord = V2ZERO;
663 body.m_Joint1.m_LocalCoord = VEC2(-0.5f*itv, 0.0f);
664 body.m_Joint1.m_Link = FindObject("Wheel1");
665 body.m_Joint2.m_AttachCoord = V2ZERO;
666 body.m_Joint2.m_LocalCoord = VEC2(0.5f*itv, 0.0f);
667 body.m_Joint2.m_Link = FindObject("Wheel2");
668 m_BodyObject.push_back(body);
669 m_BodyObject.begin()->LoadModel(this);
670 m_FrontCabin.m_LocalCoord = V3ZERO;
671 m_FrontCabin.m_AttachCoord = VEC3(0.0f, 2.5f, -m_FrontLimit);
672 m_FrontCabin.m_AttachDir = -V3DIR;
673 m_FrontCabin.m_AttachUp = V3UP;
674 m_FrontCabin.m_Link = &*m_BodyObject.begin();
675 m_FrontCabin.m_DirLink = &*m_BodyObject.begin();
676 m_FrontCabin.m_UpLink = &*m_BodyObject.begin();
677 m_TailCabin.m_LocalCoord = V3ZERO;
678 m_TailCabin.m_AttachCoord = VEC3(0.0f, 2.5f, -m_TailLimit);
679 m_TailCabin.m_AttachDir = V3DIR;
680 m_TailCabin.m_AttachUp = V3UP;
681 m_TailCabin.m_Link = &*m_BodyObject.begin();
682 m_TailCabin.m_DirLink = &*m_BodyObject.begin();
683 m_TailCabin.m_UpLink = &*m_BodyObject.begin();
684 m_PartsNum = 3;
685 return true;
686 }
687
688 /*
689 * プレビュー設定
690 */
691 void CTrainPlugin::SetPreview(){
692 ms_PreviewState = true;
693 g_Train = this;
694 g_TrainGroupTemplate = NULL;
695 string desc = g_Train->GetBasicInfo();
696 desc += FlashIn("\n%s: %.3f [m]\n%s: %.1f [km/h]",
697 lang(EntireLength), m_Length, lang(MaxVelocity), m_MaxVelocity);
698 desc += "\n"+g_Train->GetDescription();
699 g_TrainEditMode->SetProperty((char *)desc.c_str());
700 }
701
702 /*
703 * プレビュー
704 */
705 void CTrainPlugin::Preview(
706 float offset, // オフセット
707 bool reverse // 反転
708 ){
709 CBodyObject::SetTiltDir(R2L(V3ZERO));
710 SetPartsInst(NULL);
711 SetMoverState(NULL);
712 IAxleObject iao = m_AxleObject.begin();
713 for(; iao!=m_AxleObject.end(); iao++) iao->SetPreview(offset, reverse);
714 SetPosture();
715 Render(NULL);
716 }
717
718 /*
719 * オブジェクト検索
720 */
721 CNamedObject *CTrainPlugin::FindObject(
722 const string &name // オブジェクト名
723 ){
724 CNamedObject *ret;
725 IAxleObject iao = m_AxleObject.begin();
726 for(; iao!=m_AxleObject.end(); iao++) if(ret = iao->Check(name)) return ret;
727 IBodyObject ibo = m_BodyObject.begin();
728 for(; ibo!=m_BodyObject.end(); ibo++) if(ret = ibo->Check(name)) return ret;
729 IFreeObjectContainer ifo = m_FreeObject.begin();
730 for(; ifo!=m_FreeObject.end(); ifo++) if(ret = ifo->Check(name)) return ret;
731 return NULL;
732 }
733
734 /*
735 * サウンド有効かどうか
736 */
737 bool CTrainPlugin::IsSoundEnabled(){
738 return !!g_ConfigMode->GetTrainSound();
739 }
740
741 /*
742 * 車軸リスト設定
743 */
744 void CTrainPlugin::SetAxleList(
745 CTrain *train // 車輌
746 ){
747 int i = 0;
748 IAxleObject ia = m_AxleObject.begin();
749 for(; ia!=m_AxleObject.end(); ia++, i++) train->PushAxle(R2L(CAxlePosture(
750 &*ia, train, (!i || i==m_AxleObject.size()-1) && m_AxleObject.size()>1)));
751 }
752
753 /*
754 * 姿勢設定
755 */
756 void CTrainPlugin::SetPosture(){
757 IBodyObject ibo = m_BodyObject.begin();
758 for(; ibo!=m_BodyObject.end(); ibo++) ibo->SetPosture();
759 IFreeObjectContainer ifo = m_FreeObject.begin();
760 for(; ifo!=m_FreeObject.end(); ifo++) ifo->SetPosture();
761 }
762
763 /*
764 * パーツインスタンスのアタッチ
765 */
766 void CTrainPlugin::AttachPartsObject(){
767 IAxleObject iao = m_AxleObject.begin();
768 for(; iao!=m_AxleObject.end(); iao++) iao->GetPartsObject();
769 IBodyObject ibo = m_BodyObject.begin();
770 for(; ibo!=m_BodyObject.end(); ibo++) ibo->GetPartsObject();
771 IFreeObjectContainer ifo = m_FreeObject.begin();
772 for(; ifo!=m_FreeObject.end(); ifo++) ifo->AttachPartsObject();
773 }
774
775 /*
776 * 入力チェック
777 */
778 void CTrainPlugin::ScanInput(
779 CTrain *train // 車輌インスタンス
780 ){
781 train->SetLocalAxis();
782 SetCamDistSwitch(train->GetPos());
783 g_PreSimulationFlag = false;
784 IAxleObject iao = m_AxleObject.begin();
785 for(; iao!=m_AxleObject.end(); iao++) iao->CheckDetect();
786 IBodyObject ibo = m_BodyObject.begin();
787 for(; ibo!=m_BodyObject.end(); ibo++) ibo->CheckDetect();
788 IFreeObjectContainer ifo = m_FreeObject.begin();
789 for(; ifo!=m_FreeObject.end(); ifo++) ifo->ScanInput();
790 }
791
792 /*
793 * レンダリング
794 */
795 void CTrainPlugin::Render(
796 CTrain *train // 車輌インスタンス
797 ){
798 SetAnimation(train);
799 if(train){
800 train->SetLocalAxis();
801 SetCamDistSwitch(train->GetPos());
802 }else{
803 VEC3 pvpos = m_AxleObject.size()
804 ? 0.5f*(m_AxleObject.begin()->GetObject()->GetPos()
805 +(--m_AxleObject.end())->GetObject()->GetPos()) : V3ZERO;
806 g_SystemObject[SYS_OBJ_LOCAL].SetPreviewPosture(pvpos, V3DIR, V3UP);
807 SetCamDistSwitch(pvpos);
808 }
809 g_PreSimulationFlag = false;
810 CNamedObject::SetSetMaterial(m_Version>=2.00f);
811 if(train && !g_SimulationMode->GetSimSpeed()){
812 g_MoverEnabled = false;
813 train->ApplyAxle(false);
814 SetMoverState(train);
815 SetPosture();
816 SetPartsInst(train);
817 g_MoverEnabled = true;
818 }
819 IAxleObject iao = m_AxleObject.begin();
820 for(; iao!=m_AxleObject.end(); iao++) iao->Render();
821 IBodyObject ibo = m_BodyObject.begin();
822 for(; ibo!=m_BodyObject.end(); ibo++) ibo->Render();
823 IFreeObjectContainer ifo = m_FreeObject.begin();
824 for(; ifo!=m_FreeObject.end(); ifo++) ifo->Render();
825 SimulateEffect(train);
826 }
827
828 /*
829 * シミュレーション進行
830 */
831 void CTrainPlugin::Simulate(
832 CTrain *train // 車輌インスタンス
833 ){
834 SetMoverState(train);
835 train->SetLocalAxis();
836 SetCamDistSwitch(train->GetPos());
837 g_PreSimulationFlag = true;
838 SetPosture();
839 SimulateEffect(train);
840 }

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