aboutsummaryrefslogtreecommitdiff
path: root/src/gui/guiEditBoxWithScrollbar.cpp
blob: fb4bc2a0b2b14e9c10089c666395b2de18d67d2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// Modified by Mustapha T.
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#include "guiEditBoxWithScrollbar.h"

#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IGUIFont.h"
#include "IVideoDriver.h"
#include "rect.h"
#include "porting.h"
#include "Keycodes.h"

/*
todo:
optional scrollbars [done]
ctrl+left/right to select word
double click/ctrl click: word select + drag to select whole words, triple click to select line
optional? dragging selected text
numerical
*/

//! constructor
GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool border,
	IGUIEnvironment* environment, IGUIElement* parent, s32 id,
	const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar)
	: GUIEditBox(environment, parent, id, rectangle, border, writable),
	m_background(true), m_bg_color_used(false)
{
#ifdef _DEBUG
	setDebugName("GUIEditBoxWithScrollBar");
#endif


	Text = text;

	if (Environment)
		m_operator = Environment->getOSOperator();

	if (m_operator)
		m_operator->grab();

	// this element can be tabbed to
	setTabStop(true);
	setTabOrder(-1);

	if (has_vscrollbar) {
		createVScrollBar();
	}

	calculateFrameRect();
	breakText();

	calculateScrollPos();
	setWritable(writable);
}

//! Sets whether to draw the background
void GUIEditBoxWithScrollBar::setDrawBackground(bool draw)
{
	m_background = draw;
}


void GUIEditBoxWithScrollBar::updateAbsolutePosition()
{
	core::rect<s32> old_absolute_rect(AbsoluteRect);
	IGUIElement::updateAbsolutePosition();
	if (old_absolute_rect != AbsoluteRect) {
		calculateFrameRect();
		breakText();
		calculateScrollPos();
	}
}


//! draws the element and its children
void GUIEditBoxWithScrollBar::draw()
{
	if (!IsVisible)
		return;

	const bool focus = Environment->hasFocus(this);

	IGUISkin* skin = Environment->getSkin();
	if (!skin)
		return;

	video::SColor default_bg_color;
	video::SColor bg_color;

	default_bg_color = m_writable ? skin->getColor(EGDC_WINDOW) : video::SColor(0);
	bg_color = m_bg_color_used ? m_bg_color : default_bg_color;

	if (!m_border && m_background) {
		skin->draw2DRectangle(this, bg_color, AbsoluteRect, &AbsoluteClippingRect);
	}

	// draw the border

	if (m_border) {

		if (m_writable) {
			skin->draw3DSunkenPane(this, bg_color, false, m_background,
				AbsoluteRect, &AbsoluteClippingRect);
		}

		calculateFrameRect();
	}

	core::rect<s32> local_clip_rect = m_frame_rect;
	local_clip_rect.clipAgainst(AbsoluteClippingRect);

	// draw the text

	IGUIFont* font = getActiveFont();

	s32 cursor_line = 0;
	s32 charcursorpos = 0;

	if (font) {
		if (m_last_break_font != font) {
			breakText();
		}

		// calculate cursor pos

		core::stringw *txt_line = &Text;
		s32 start_pos = 0;

		core::stringw s, s2;

		// get mark position
		const bool ml = (!m_passwordbox && (m_word_wrap || m_multiline));
		const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
		const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
		const s32 hline_start = ml ? getLineFromPos(realmbgn) : 0;
		const s32 hline_count = ml ? getLineFromPos(realmend) - hline_start + 1 : 1;
		const s32 line_count = ml ? m_broken_text.size() : 1;

		// Save the override color information.
		// Then, alter it if the edit box is disabled.
		const bool prevOver = m_override_color_enabled;
		const video::SColor prevColor = m_override_color;

		if (Text.size()) {
			if (!isEnabled() && !m_override_color_enabled) {
				m_override_color_enabled = true;
				m_override_color = skin->getColor(EGDC_GRAY_TEXT);
			}

			for (s32 i = 0; i < line_count; ++i) {
				setTextRect(i);

				// clipping test - don't draw anything outside the visible area
				core::rect<s32> c = local_clip_rect;
				c.clipAgainst(m_current_text_rect);
				if (!c.isValid())
					continue;

				// get current line
				if (m_passwordbox) {
					if (m_broken_text.size() != 1) {
						m_broken_text.clear();
						m_broken_text.emplace_back();
					}
					if (m_broken_text[0].size() != Text.size()){
						m_broken_text[0] = Text;
						for (u32 q = 0; q < Text.size(); ++q)
						{
							m_broken_text[0][q] = m_passwordchar;
						}
					}
					txt_line = &m_broken_text[0];
					start_pos = 0;
				} else {
					txt_line = ml ? &m_broken_text[i] : &Text;
					start_pos = ml ? m_broken_text_positions[i] : 0;
				}


				// draw normal text
				font->draw(txt_line->c_str(), m_current_text_rect,
					m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT),
					false, true, &local_clip_rect);

				// draw mark and marked text
				if (focus && m_mark_begin != m_mark_end && i >= hline_start && i < hline_start + hline_count) {

					s32 mbegin = 0, mend = 0;
					s32 lineStartPos = 0, lineEndPos = txt_line->size();

					if (i == hline_start) {
						// highlight start is on this line
						s = txt_line->subString(0, realmbgn - start_pos);
						mbegin = font->getDimension(s.c_str()).Width;

						// deal with kerning
						mbegin += font->getKerningWidth(
							&((*txt_line)[realmbgn - start_pos]),
							realmbgn - start_pos > 0 ? &((*txt_line)[realmbgn - start_pos - 1]) : 0);

						lineStartPos = realmbgn - start_pos;
					}
					if (i == hline_start + hline_count - 1) {
						// highlight end is on this line
						s2 = txt_line->subString(0, realmend - start_pos);
						mend = font->getDimension(s2.c_str()).Width;
						lineEndPos = (s32)s2.size();
					} else {
						mend = font->getDimension(txt_line->c_str()).Width;
					}


					m_current_text_rect.UpperLeftCorner.X += mbegin;
					m_current_text_rect.LowerRightCorner.X = m_current_text_rect.UpperLeftCorner.X + mend - mbegin;


					// draw mark
					skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), m_current_text_rect, &local_clip_rect);

					// draw marked text
					s = txt_line->subString(lineStartPos, lineEndPos - lineStartPos);

					if (s.size())
						font->draw(s.c_str(), m_current_text_rect,
							m_override_color_enabled ? m_override_color : skin->getColor(EGDC_HIGH_LIGHT_TEXT),
							false, true, &local_clip_rect);

				}
			}

			// Return the override color information to its previous settings.
			m_override_color_enabled = prevOver;
			m_override_color = prevColor;
		}

		// draw cursor
		if (IsEnabled && m_writable) {
			if (m_word_wrap || m_multiline) {
				cursor_line = getLineFromPos(m_cursor_pos);
				txt_line = &m_broken_text[cursor_line];
				start_pos = m_broken_text_positions[cursor_line];
			}
			s = txt_line->subString(0, m_cursor_pos - start_pos);
			charcursorpos = font->getDimension(s.c_str()).Width +
				font->getKerningWidth(L"_", m_cursor_pos - start_pos > 0 ? &((*txt_line)[m_cursor_pos - start_pos - 1]) : 0);

			if (focus && (porting::getTimeMs() - m_blink_start_time) % 700 < 350) {
				setTextRect(cursor_line);
				m_current_text_rect.UpperLeftCorner.X += charcursorpos;

				font->draw(L"_", m_current_text_rect,
					m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT),
					false, true, &local_clip_rect);
			}
		}
	}

	// draw children
	IGUIElement::draw();
}


s32 GUIEditBoxWithScrollBar::getCursorPos(s32 x, s32 y)
{
	IGUIFont* font = getActiveFont();

	const u32 line_count = (m_word_wrap || m_multiline) ? m_broken_text.size() : 1;

	core::stringw *txt_line = 0;
	s32 start_pos = 0;
	x += 3;

	for (u32 i = 0; i < line_count; ++i) {
		setTextRect(i);
		if (i == 0 && y < m_current_text_rect.UpperLeftCorner.Y)
			y = m_current_text_rect.UpperLeftCorner.Y;
		if (i == line_count - 1 && y > m_current_text_rect.LowerRightCorner.Y)
			y = m_current_text_rect.LowerRightCorner.Y;

		// is it inside this region?
		if (y >= m_current_text_rect.UpperLeftCorner.Y && y <= m_current_text_rect.LowerRightCorner.Y) {
			// we've found the clicked line
			txt_line = (m_word_wrap || m_multiline) ? &m_broken_text[i] : &Text;
			start_pos = (m_word_wrap || m_multiline) ? m_broken_text_positions[i] : 0;
			break;
		}
	}

	if (x < m_current_text_rect.UpperLeftCorner.X)
		x = m_current_text_rect.UpperLeftCorner.X;

	if (!txt_line)
		return 0;

	s32 idx = font->getCharacterFromPos(txt_line->c_str(), x - m_current_text_rect.UpperLeftCorner.X);

	// click was on or left of the line
	if (idx != -1)
		return idx + start_pos;

	// click was off the right edge of the line, go to end.
	return txt_line->size() + start_pos;
}


//! Breaks the single text line.
void GUIEditBoxWithScrollBar::breakText()
{
	if ((!m_word_wrap && !m_multiline))
		return;

	m_broken_text.clear(); // need to reallocate :/
	m_broken_text_positions.clear();

	IGUIFont* font = getActiveFont();
	if (!font)
		return;

	m_last_break_font = font;

	core::stringw line;
	core::stringw word;
	core::stringw whitespace;
	s32 last_line_start = 0;
	s32 size = Text.size();
	s32 length = 0;
	s32 el_width = RelativeRect.getWidth() - m_scrollbar_width - 10;
	wchar_t c;

	for (s32 i = 0; i < size; ++i) {
		c = Text[i];
		bool line_break = false;

		if (c == L'\r') { // Mac or Windows breaks

			line_break = true;
			c = 0;
			if (Text[i + 1] == L'\n') { // Windows breaks
				// TODO: I (Michael) think that we shouldn't change the text given by the user for whatever reason.
				// Instead rework the cursor positioning to be able to handle this (but not in stable release
				// branch as users might already expect this behavior).
				Text.erase(i + 1);
				--size;
				if (m_cursor_pos > i)
					--m_cursor_pos;
			}
		} else if (c == L'\n') { // Unix breaks
			line_break = true;
			c = 0;
		}

		// don't break if we're not a multi-line edit box
		if (!m_multiline)
			line_break = false;

		if (c == L' ' || c == 0 || i == (size - 1)) {
			// here comes the next whitespace, look if
			// we can break the last word to the next line
			// We also break whitespace, otherwise cursor would vanish beside the right border.
			s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
			s32 worldlgth = font->getDimension(word.c_str()).Width;

			if (m_word_wrap && length + worldlgth + whitelgth > el_width && line.size() > 0) {
				// break to next line
				length = worldlgth;
				m_broken_text.push_back(line);
				m_broken_text_positions.push_back(last_line_start);
				last_line_start = i - (s32)word.size();
				line = word;
			} else {
				// add word to line
				line += whitespace;
				line += word;
				length += whitelgth + worldlgth;
			}

			word = L"";
			whitespace = L"";


			if (c)
				whitespace += c;

			// compute line break
			if (line_break) {
				line += whitespace;
				line += word;
				m_broken_text.push_back(line);
				m_broken_text_positions.push_back(last_line_start);
				last_line_start = i + 1;
				line = L"";
				word = L"";
				whitespace = L"";
				length = 0;
			}
		} else {
			// yippee this is a word..
			word += c;
		}
	}

	line += whitespace;
	line += word;
	m_broken_text.push_back(line);
	m_broken_text_positions.push_back(last_line_start);
}

// TODO: that function does interpret VAlign according to line-index (indexed
// line is placed on top-center-bottom) but HAlign according to line-width
// (pixels) and not by row.
// Intuitively I suppose HAlign handling is better as VScrollPos should handle
// the line-scrolling.
// But please no one change this without also rewriting (and this time
// testing!!!) autoscrolling (I noticed this when fixing the old autoscrolling).
void GUIEditBoxWithScrollBar::setTextRect(s32 line)
{
	if (line < 0)
		return;

	IGUIFont* font = getActiveFont();
	if (!font)
		return;

	core::dimension2du d;

	// get text dimension
	const u32 line_count = (m_word_wrap || m_multiline) ? m_broken_text.size() : 1;
	if (m_word_wrap || m_multiline) {
		d = font->getDimension(m_broken_text[line].c_str());
	} else {
		d = font->getDimension(Text.c_str());
		d.Height = AbsoluteRect.getHeight();
	}
	d.Height += font->getKerningHeight();

	// justification
	switch (m_halign) {
	case EGUIA_CENTER:
		// align to h centre
		m_current_text_rect.UpperLeftCorner.X = (m_frame_rect.getWidth() / 2) - (d.Width / 2);
		m_current_text_rect.LowerRightCorner.X = (m_frame_rect.getWidth() / 2) + (d.Width / 2);
		break;
	case EGUIA_LOWERRIGHT:
		// align to right edge
		m_current_text_rect.UpperLeftCorner.X = m_frame_rect.getWidth() - d.Width;
		m_current_text_rect.LowerRightCorner.X = m_frame_rect.getWidth();
		break;
	default:
		// align to left edge
		m_current_text_rect.UpperLeftCorner.X = 0;
		m_current_text_rect.LowerRightCorner.X = d.Width;

	}

	switch (m_valign) {
	case EGUIA_CENTER:
		// align to v centre
		m_current_text_rect.UpperLeftCorner.Y =
			(m_frame_rect.getHeight() / 2) - (line_count*d.Height) / 2 + d.Height*line;
		break;
	case EGUIA_LOWERRIGHT:
		// align to bottom edge
		m_current_text_rect.UpperLeftCorner.Y =
			m_frame_rect.getHeight() - line_count*d.Height + d.Height*line;
		break;
	default:
		// align to top edge
		m_current_text_rect.UpperLeftCorner.Y = d.Height*line;
		break;
	}

	m_current_text_rect.UpperLeftCorner.X -= m_hscroll_pos;
	m_current_text_rect.LowerRightCorner.X -= m_hscroll_pos;
	m_current_text_rect.UpperLeftCorner.Y -= m_vscroll_pos;
	m_current_text_rect.LowerRightCorner.Y = m_current_text_rect.UpperLeftCorner.Y + d.Height;

	m_current_text_rect += m_frame_rect.UpperLeftCorner;
}

// calculate autoscroll
void GUIEditBoxWithScrollBar::calculateScrollPos()
{
	if (!m_autoscroll)
		return;

	IGUISkin* skin = Environment->getSkin();
	if (!skin)
		return;
	IGUIFont* font = m_override_font ? m_override_font : skin->getFont();
	if (!font)
		return;

	s32 curs_line = getLineFromPos(m_cursor_pos);
	if (curs_line < 0)
		return;
	setTextRect(curs_line);
	const bool has_broken_text = m_multiline || m_word_wrap;

	// Check horizonal scrolling
	// NOTE: Calculations different to vertical scrolling because setTextRect interprets VAlign relative to line but HAlign not relative to row
	{
		// get cursor position
		IGUIFont* font = getActiveFont();
		if (!font)
			return;

		// get cursor area
		irr::u32 cursor_width = font->getDimension(L"_").Width;
		core::stringw *txt_line = has_broken_text ? &m_broken_text[curs_line] : &Text;
		s32 cpos = has_broken_text ? m_cursor_pos - m_broken_text_positions[curs_line] : m_cursor_pos;	// column
		s32 cstart = font->getDimension(txt_line->subString(0, cpos).c_str()).Width;		// pixels from text-start
		s32 cend = cstart + cursor_width;
		s32 txt_width = font->getDimension(txt_line->c_str()).Width;

		if (txt_width < m_frame_rect.getWidth()) {
			// TODO: Needs a clean left and right gap removal depending on HAlign, similar to vertical scrolling tests for top/bottom.
			// This check just fixes the case where it was most noticable (text smaller than clipping area).

			m_hscroll_pos = 0;
			setTextRect(curs_line);
		}

		if (m_current_text_rect.UpperLeftCorner.X + cstart < m_frame_rect.UpperLeftCorner.X) {
			// cursor to the left of the clipping area
			m_hscroll_pos -= m_frame_rect.UpperLeftCorner.X - (m_current_text_rect.UpperLeftCorner.X + cstart);
			setTextRect(curs_line);

			// TODO: should show more characters to the left when we're scrolling left
			//	and the cursor reaches the border.
		} else if (m_current_text_rect.UpperLeftCorner.X + cend > m_frame_rect.LowerRightCorner.X)	{
			// cursor to the right of the clipping area
			m_hscroll_pos += (m_current_text_rect.UpperLeftCorner.X + cend) - m_frame_rect.LowerRightCorner.X;
			setTextRect(curs_line);
		}
	}

	// calculate vertical scrolling
	if (has_broken_text) {
		irr::u32 line_height = font->getDimension(L"A").Height + font->getKerningHeight();
		// only up to 1 line fits?
		if (line_height >= (irr::u32)m_frame_rect.getHeight()) {
			m_vscroll_pos = 0;
			setTextRect(curs_line);
			s32 unscrolledPos = m_current_text_rect.UpperLeftCorner.Y;
			s32 pivot = m_frame_rect.UpperLeftCorner.Y;
			switch (m_valign) {
			case EGUIA_CENTER:
				pivot += m_frame_rect.getHeight() / 2;
				unscrolledPos += line_height / 2;
				break;
			case EGUIA_LOWERRIGHT:
				pivot += m_frame_rect.getHeight();
				unscrolledPos += line_height;
				break;
			default:
				break;
			}
			m_vscroll_pos = unscrolledPos - pivot;
			setTextRect(curs_line);
		} else {
			// First 2 checks are necessary when people delete lines
			setTextRect(0);
			if (m_current_text_rect.UpperLeftCorner.Y > m_frame_rect.UpperLeftCorner.Y && m_valign != EGUIA_LOWERRIGHT) {
				// first line is leaving a gap on top
				m_vscroll_pos = 0;
			} else if (m_valign != EGUIA_UPPERLEFT) {
				u32 lastLine = m_broken_text_positions.empty() ? 0 : m_broken_text_positions.size() - 1;
				setTextRect(lastLine);
				if (m_current_text_rect.LowerRightCorner.Y < m_frame_rect.LowerRightCorner.Y)
				{
					// last line is leaving a gap on bottom
					m_vscroll_pos -= m_frame_rect.LowerRightCorner.Y - m_current_text_rect.LowerRightCorner.Y;
				}
			}

			setTextRect(curs_line);
			if (m_current_text_rect.UpperLeftCorner.Y < m_frame_rect.UpperLeftCorner.Y) {
				// text above valid area
				m_vscroll_pos -= m_frame_rect.UpperLeftCorner.Y - m_current_text_rect.UpperLeftCorner.Y;
				setTextRect(curs_line);
			} else if (m_current_text_rect.LowerRightCorner.Y > m_frame_rect.LowerRightCorner.Y){
				// text below valid area
				m_vscroll_pos += m_current_text_rect.LowerRightCorner.Y - m_frame_rect.LowerRightCorner.Y;
				setTextRect(curs_line);
			}
		}
	}

	if (m_vscrollbar) {
		m_vscrollbar->setPos(m_vscroll_pos);
	}
}

void GUIEditBoxWithScrollBar::calculateFrameRect()
{
	m_frame_rect = AbsoluteRect;


	IGUISkin *skin = 0;
	if (Environment)
		skin = Environment->getSkin();
	if (m_border && skin) {
		m_frame_rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X) + 1;
		m_frame_rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y) + 1;
		m_frame_rect.LowerRightCorner.X -= skin->getSize(EGDS_TEXT_DISTANCE_X) + 1;
		m_frame_rect.LowerRightCorner.Y -= skin->getSize(EGDS_TEXT_DISTANCE_Y) + 1;
	}

	updateVScrollBar();
}

//! create a vertical scroll bar
void GUIEditBoxWithScrollBar::createVScrollBar()
{
	IGUISkin *skin = 0;
	if (Environment)
		skin = Environment->getSkin();

	s32 fontHeight = 1;

	if (m_override_font) {
		fontHeight = m_override_font->getDimension(L"Ay").Height;
	} else {
		IGUIFont *font;
		if (skin && (font = skin->getFont())) {
			fontHeight = font->getDimension(L"Ay").Height;
		}
	}

	m_scrollbar_width = skin ? skin->getSize(gui::EGDS_SCROLLBAR_SIZE) : 16;

	irr::core::rect<s32> scrollbarrect = m_frame_rect;
	scrollbarrect.UpperLeftCorner.X += m_frame_rect.getWidth() - m_scrollbar_width;
	m_vscrollbar = new GUIScrollBar(Environment, getParent(), -1,
			scrollbarrect, false, true);

	m_vscrollbar->setVisible(false);
	m_vscrollbar->setSmallStep(3 * fontHeight);
	m_vscrollbar->setLargeStep(10 * fontHeight);
}



//! Change the background color
void GUIEditBoxWithScrollBar::setBackgroundColor(const video::SColor &bg_color)
{
	m_bg_color = bg_color;
	m_bg_color_used = true;
}

//! Writes attributes of the element.
void GUIEditBoxWithScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options = 0) const
{
	out->addBool("Border", m_border);
	out->addBool("Background", m_background);
	// out->addFont("OverrideFont", OverrideFont);

	GUIEditBox::serializeAttributes(out, options);
}


//! Reads attributes of the element
void GUIEditBoxWithScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options = 0)
{
	GUIEditBox::deserializeAttributes(in, options);

	setDrawBorder(in->getAttributeAsBool("Border"));
	setDrawBackground(in->getAttributeAsBool("Background"));
}

bool GUIEditBoxWithScrollBar::isDrawBackgroundEnabled() const { return false; }
bool GUIEditBoxWithScrollBar::isDrawBorderEnabled() const { return false; }
void GUIEditBoxWithScrollBar::setCursorChar(const wchar_t cursorChar) { }
wchar_t GUIEditBoxWithScrollBar::getCursorChar() const { return '|'; }
void GUIEditBoxWithScrollBar::setCursorBlinkTime(irr::u32 timeMs) { }
irr::u32 GUIEditBoxWithScrollBar::getCursorBlinkTime() const { return 500; }
8607 vt 0.502578 0.922911 vt 0.448463 0.401390 vt 0.448463 0.297086 vt 0.502580 0.401390 vt 0.502580 0.297086 vt 0.502578 0.938557 vt 0.448461 0.922911 vt 0.448461 0.938557 vt 0.448461 0.818607 vt 0.502579 0.714303 vt 0.448462 0.714303 vt 0.502579 0.609999 vt 0.448462 0.609998 vt 0.502579 0.505694 vt 0.448462 0.505694 vt 0.432816 0.922911 vt 0.432816 0.818607 vt 0.432817 0.714303 vt 0.432817 0.609998 vt 0.432817 0.505694 vt 0.518225 0.297086 vt 0.518225 0.401390 vt 0.518224 0.505694 vt 0.518224 0.609999 vt 0.518224 0.714303 vt 0.413238 0.714303 vt 0.413238 0.609998 vt 0.413238 0.505694 vt 0.537804 0.297086 vt 0.537803 0.401390 vt 0.537803 0.505694 vt 0.537803 0.609999 vt 0.537803 0.714303 vt 0.381947 0.297086 vt 0.381947 0.401390 vt 0.381947 0.505694 vt 0.381947 0.609998 vt 0.381947 0.714303 vt 0.609725 0.922911 vt 0.609725 0.818607 vt 0.609725 0.714303 vt 0.569094 0.714303 vt 0.609725 0.609999 vt 0.569094 0.609999 vt 0.609725 0.505694 vt 0.569094 0.505694 vt 0.341316 0.297086 vt 0.341316 0.401390 vt 0.341316 0.505694 vt 0.341316 0.609998 vt 0.341316 0.714302 vt 0.518225 0.475893 vt 0.502579 0.475893 vt 0.502579 0.565297 vt 0.518224 0.565297 vt 0.518225 0.297086 vt 0.502580 0.297086 vt 0.502580 0.386490 vt 0.518225 0.386490 vt 0.502579 0.654700 vt 0.518224 0.654700 vt 0.569094 0.833508 vt 0.537803 0.833508 vt 0.537803 0.922911 vt 0.569094 0.922911 vt 0.341316 0.833507 vt 0.341316 0.922911 vt 0.381947 0.922911 vt 0.381947 0.833507 vt 0.429134 0.985493 vt 0.521905 0.985494 vt 0.483250 0.972977 vt 0.467789 0.972977 vt 0.609725 0.386490 vt 0.609725 0.297086 vt 0.569095 0.297086 vt 0.569094 0.386490 vt 0.467791 0.247020 vt 0.483253 0.247020 vt 0.521907 0.234503 vt 0.429136 0.234503 vt 0.483252 0.278311 vt 0.467790 0.278311 vt 0.413238 0.922911 vt 0.413238 0.833507 vt 0.483250 0.941686 vt 0.467789 0.941686 vt 0.518224 0.833507 vt 0.518224 0.922911 vt 0.413238 0.386490 vt 0.432817 0.386490 vt 0.432817 0.297086 vt 0.413238 0.297086 vt 0.502578 0.833507 vt 0.502578 0.922911 vt 0.448463 0.386490 vt 0.448463 0.297086 vt 0.448463 0.281440 vt 0.502580 0.281440 vt 0.502578 0.938557 vt 0.448461 0.922911 vt 0.448461 0.938557 vt 0.432817 0.565297 vt 0.448462 0.565297 vt 0.448462 0.475893 vt 0.432817 0.475893 vt 0.432816 0.744104 vt 0.448462 0.744104 vt 0.448462 0.654700 vt 0.432817 0.654700 vt 0.432816 0.922911 vt 0.448461 0.833507 vt 0.432816 0.833507 vt 0.537803 0.475893 vt 0.537803 0.565297 vt 0.381947 0.297086 vt 0.381947 0.386490 vt 0.537803 0.654700 vt 0.518224 0.744104 vt 0.537803 0.744104 vt 0.569095 0.297086 vt 0.537804 0.297086 vt 0.537803 0.922911 vt 0.569094 0.922911 vt 0.341316 0.297086 vt 0.341316 0.922911 vt 0.381947 0.922911 vt 0.381947 0.297086 vt 0.429134 0.985493 vt 0.521905 0.985494 vt 0.483250 0.972977 vt 0.467789 0.972977 vt 0.609725 0.922911 vt 0.609725 0.297086 vt 0.467791 0.247020 vt 0.483253 0.247020 vt 0.521907 0.234503 vt 0.429136 0.234503 vt 0.483252 0.278311 vt 0.467790 0.278311 vt 0.413238 0.922911 vt 0.413238 0.297086 vt 0.483250 0.941686 vt 0.467789 0.941686 vt 0.518225 0.297086 vt 0.518224 0.922911 vt 0.432816 0.922911 vt 0.432817 0.297086 vt 0.502580 0.297086 vt 0.502578 0.922911 vt 0.448461 0.922911 vt 0.448463 0.297086 vt 0.448463 0.281440 vt 0.502580 0.281440 vt 0.502578 0.938557 vt 0.448461 0.938557 vt 0.502578 0.744104 vt 0.413238 0.475893 vt 0.537804 0.297086 vt 0.537803 0.386490 vt 0.413238 0.565297 vt 0.413238 0.654700 vt 0.413238 0.744104 vt 0.569094 0.744104 vt 0.569094 0.475893 vt 0.569094 0.654700 vt 0.341316 0.744104 vt 0.381947 0.744104 vt 0.341316 0.654700 vt 0.381947 0.654700 vt 0.569094 0.565297 vt 0.609725 0.744104 vt 0.609725 0.654700 vt 0.341316 0.565297 vt 0.381947 0.565297 vt 0.341316 0.386489 vt 0.341316 0.475893 vt 0.381947 0.475893 vt 0.341316 0.297086 vt 0.609725 0.565297 vt 0.609725 0.475893 vt 0.609725 0.833508 vt 0.609725 0.922911 vt 0.467682 0.284699 vt 0.467682 0.320821 vt 0.485531 0.320821 vt 0.485531 0.284699 vt 0.530153 0.270250 vt 0.423059 0.270250 vt 0.445370 0.324434 vt 0.445370 0.342495 vt 0.507842 0.342495 vt 0.507842 0.324433 vn 0.4087 0.0071 0.9126 vn -0.1321 0.9512 -0.2789 vn -0.8949 -0.0000 0.4462 vn 0.0105 0.9519 0.3062 vn -0.4288 0.0000 -0.9034 vn 0.0673 -0.9866 0.1487 vn -0.0045 -0.9872 -0.1592 vn 0.4162 0.0000 0.9093 vn -0.0284 0.0009 -0.9996 vn -0.0001 1.0000 0.0001 vn 0.0001 1.0000 -0.0000 vn 0.0009 1.0000 -0.0004 vn 0.0007 1.0000 -0.0002 vn -0.0007 1.0000 0.0002 vn -0.0009 1.0000 0.0002 vn -0.4170 0.0012 -0.9089 vn -0.4369 0.0628 -0.8973 vn -0.4191 0.0973 -0.9027 vn -0.3908 0.0248 -0.9201 vn -0.2329 -0.0054 -0.9725 vn 0.0341 0.0015 0.9994 vn 0.2410 0.0047 0.9705 vn 0.3914 0.0031 0.9202 vn 0.4236 0.0000 0.9058 vn 0.4377 0.0000 0.8991 vn -0.0705 -0.9860 -0.1508 vn -0.0773 -0.9850 -0.1543 vn -0.0711 -0.9857 -0.1529 vn -0.0630 -0.9863 -0.1522 vn -0.0367 -0.9871 -0.1561 vn 0.0054 -0.9873 0.1589 vn 0.0393 -0.9871 0.1549 vn 0.0652 -0.9863 0.1513 vn 0.0706 -0.9858 0.1523 vn 0.0724 -0.9858 0.1514 vn -0.0294 0.0006 -0.9996 vn -0.2344 0.0020 -0.9721 vn -0.3861 0.0013 -0.9225 vn -0.4167 0.0000 -0.9091 vn -0.4419 0.0000 -0.8971 vn 0.1262 0.9510 0.2821 vn 0.1364 0.9497 0.2819 vn 0.1359 0.9487 0.2855 vn 0.1232 0.9499 0.2871 vn 0.0734 0.9518 0.2978 vn -0.0086 0.9518 -0.3065 vn -0.0719 0.9518 -0.2982 vn -0.1215 0.9501 -0.2872 vn -0.1306 0.9491 -0.2865 vn -0.1363 0.9500 -0.2811 vn 0.0327 0.0001 0.9995 vn 0.2396 0.0006 0.9709 vn 0.3952 0.0113 0.9185 vn 0.4262 0.0351 0.9040 vn 0.4328 0.0301 0.9010 vn -0.4938 -0.0097 -0.8695 vn -0.4879 -0.0001 -0.8729 vn -0.6078 -0.0215 -0.7938 vn -0.4809 -0.0018 -0.8768 vn -0.7047 -0.0001 -0.7095 vn 0.2171 0.9514 0.2185 vn 0.7071 -0.0000 -0.7071 vn -0.1499 0.9513 -0.2695 vn -0.8879 -0.0717 0.4545 vn -0.8863 -0.0003 0.4631 vn 0.7060 -0.0059 0.7082 vn -0.1139 -0.9869 -0.1143 vn 0.0770 -0.9872 0.1395 vn -0.7061 -0.0078 -0.7081 vn 0.4839 -0.0125 0.8750 vn 0.0000 1.0000 0.0000 vn -0.8929 0.0400 0.4484 vn 0.4980 0.0000 0.8672 vn 0.6543 -0.0027 0.7562 vn 0.4837 -0.0014 0.8752 vn 0.6057 -0.0001 0.7957 vn 0.7049 -0.0003 0.7093 vn 0.7075 -0.0029 0.7067 vn -0.0796 -0.9870 -0.1399 vn 0.4832 0.0000 0.8755 vn -0.1069 -0.9866 -0.1229 vn -0.0986 -0.9867 -0.1289 vn -0.1152 -0.9866 -0.1155 vn -0.4462 0.0000 -0.8949 vn 0.1380 0.9511 0.2765 vn 0.8890 -0.0722 -0.4521 vn -0.1369 0.9518 -0.2743 vn 0.4462 0.0000 0.8949 vn 0.8949 0.0000 -0.4462 vn -0.0707 -0.9874 -0.1416 vn 0.0713 -0.9871 0.1430 vn -0.4471 -0.0000 -0.8945 vn 0.4465 0.0092 0.8947 vn 0.8873 0.0394 -0.4596 vn 0.0770 -0.9872 0.1397 vn -0.0783 -0.9869 -0.1408 vn 0.0799 -0.9870 0.1397 vn 0.0982 -0.9867 0.1291 vn -0.0768 -0.9872 -0.1399 vn 0.1139 -0.9869 0.1143 vn 0.1154 -0.9866 0.1153 vn -0.7060 -0.0190 -0.7080 vn -0.6558 -0.0248 -0.7545 vn 0.1066 -0.9866 0.1232 vn -0.7063 -0.0015 -0.7079 vn -0.4820 -0.0007 -0.8762 vn -0.6560 -0.0014 -0.7547 vn -0.4837 -0.0012 -0.8753 vn 0.2174 0.9517 0.2170 vn 0.2004 0.9519 0.2318 vn -0.6077 -0.0000 -0.7942 vn -0.4961 0.0000 -0.8683 vn -0.2012 0.9519 -0.2310 vn 0.1863 0.9515 0.2447 vn 0.1485 0.9518 0.2685 vn 0.1479 0.9521 0.2676 vn 0.1533 0.9514 0.2670 vn -0.1524 0.9514 -0.2676 vn -0.1476 0.9518 -0.2690 vn -0.1873 0.9515 -0.2440 vn 0.6547 -0.0144 0.7558 vn -0.2166 0.9517 -0.2174 vn 0.6059 -0.0107 0.7955 vn 0.4957 -0.0048 0.8685 vn 0.4827 -0.0009 0.8758 vn -0.2169 0.9514 -0.2185 vn 0.7073 -0.0134 0.7068 vn 1.0000 0.0000 -0.0077 usemtl Rails s off f 274/406/156 284/407/156 249/408/156 245/409/156 f 263/410/157 240/411/157 244/412/157 273/413/157 f 240/414/158 241/415/158 245/416/158 244/417/158 f 268/418/159 242/419/159 246/420/159 278/421/159 f 273/413/160 244/412/160 248/422/160 283/423/160 f 245/416/158 249/424/158 248/425/158 244/417/158 f 284/407/161 289/426/161 251/427/161 249/408/161 f 279/428/162 294/429/162 253/430/162 247/431/162 f 289/426/163 299/432/163 255/433/163 251/427/163 f 294/429/164 304/434/164 257/435/164 253/430/164 f 303/436/165 256/437/165 257/435/165 304/434/165 f 248/425/158 249/424/158 251/438/158 255/433/158 258/439/158 254/440/158 f 255/433/166 299/432/166 308/441/166 258/439/166 f 299/432/167 300/442/167 307/443/167 308/441/167 f 300/442/168 301/444/168 306/445/168 307/443/168 f 301/444/169 302/446/169 305/447/169 306/445/169 f 302/446/170 303/436/170 304/434/170 305/447/170 f 254/448/171 258/439/171 308/441/171 298/449/171 f 298/449/172 308/441/172 307/443/172 297/450/172 f 297/450/173 307/443/173 306/445/173 296/451/173 f 296/451/174 306/445/174 305/447/174 295/452/174 f 295/452/175 305/447/175 304/434/175 294/429/175 f 252/453/176 256/437/176 303/436/176 293/454/176 f 293/454/177 303/436/177 302/446/177 292/455/177 f 292/455/178 302/446/178 301/444/178 291/456/178 f 291/456/179 301/444/179 300/442/179 290/457/179 f 290/457/180 300/442/180 299/432/180 289/426/180 f 248/422/181 254/448/181 298/449/181 283/423/181 f 283/423/182 298/449/182 297/450/182 282/458/182 f 282/458/183 297/450/183 296/451/183 281/459/183 f 281/459/184 296/451/184 295/452/184 280/460/184 f 280/460/185 295/452/185 294/429/185 279/428/185 f 250/461/186 252/453/186 293/454/186 288/462/186 f 288/462/187 293/454/187 292/455/187 287/463/187 f 287/463/188 292/455/188 291/456/188 286/464/188 f 286/464/189 291/456/189 290/457/189 285/465/189 f 285/465/190 290/457/190 289/426/190 284/407/190 f 243/466/191 269/467/191 279/428/191 247/431/191 f 269/467/192 270/468/192 280/460/192 279/428/192 f 270/468/193 271/469/193 281/459/193 280/460/193 f 271/469/194 272/470/194 282/458/194 281/459/194 f 272/470/195 273/413/195 283/423/195 282/458/195 f 241/471/196 264/472/196 274/406/196 245/409/196 f 264/472/197 265/473/197 275/474/197 274/406/197 f 265/473/198 266/475/198 276/476/198 275/474/198 f 266/475/199 267/477/199 277/478/199 276/476/199 f 267/477/200 268/418/200 278/421/200 277/478/200 f 239/479/201 259/480/201 269/467/201 243/466/201 f 259/480/202 260/481/202 270/468/202 269/467/202 f 260/481/203 261/482/203 271/469/203 270/468/203 f 261/482/204 262/483/204 272/470/204 271/469/204 f 262/483/205 263/410/205 273/413/205 272/470/205 f 246/420/206 250/461/206 288/462/206 278/421/206 f 278/421/207 288/462/207 287/463/207 277/478/207 f 277/478/208 287/463/208 286/464/208 276/476/208 f 276/476/209 286/464/209 285/465/209 275/474/209 f 275/474/210 285/465/210 284/407/210 274/406/210 f 392/484/211 357/485/211 358/486/211 393/487/211 f 330/488/212 334/489/212 356/490/212 391/491/212 f 393/487/213 358/486/213 359/492/213 394/493/213 f 391/491/214 356/490/214 357/485/214 392/484/214 f 343/494/215 310/495/215 327/496/215 323/497/215 f 379/498/216 318/499/216 322/500/216 344/501/216 f 318/502/217 319/503/217 323/504/217 322/505/217 f 350/506/218 320/507/218 324/508/218 338/509/218 f 321/510/219 324/511/219 320/512/219 317/513/219 f 328/514/220 324/511/220 321/510/220 325/515/220 f 344/501/221 322/500/221 326/516/221 311/517/221 f 323/504/217 327/518/217 326/519/217 322/505/217 f 310/495/222 396/520/222 329/521/222 327/496/222 f 316/522/223 390/523/223 331/524/223 325/525/223 f 396/520/224 361/526/224 333/527/224 329/521/224 f 390/523/225 355/528/225 335/529/225 331/524/225 f 356/490/226 334/489/226 335/529/226 355/528/226 f 325/515/227 331/530/227 335/529/227 334/489/227 330/531/227 328/514/227 f 326/519/217 327/518/217 329/532/217 333/527/217 336/533/217 332/534/217 f 388/535/228 404/536/228 354/537/228 389/538/228 f 386/539/229 402/540/229 403/541/229 387/542/229 f 389/538/230 354/537/230 355/528/230 390/523/230 f 387/542/231 403/541/231 404/536/231 388/535/231 f 332/543/232 336/533/232 401/544/232 385/545/232 f 358/486/226 357/485/226 354/537/226 404/536/226 f 385/545/233 401/544/233 402/540/233 386/539/233 f 357/485/226 356/490/226 355/528/226 354/537/226 f 398/546/234 392/484/234 393/487/234 399/547/234 f 321/548/235 349/549/235 316/522/235 325/525/235 f 400/550/236 394/493/236 395/551/236 309/552/236 f 399/547/237 393/487/237 394/493/237 400/550/237 f 309/552/238 395/551/238 396/520/238 310/495/238 f 367/553/239 371/554/239 370/555/239 366/556/239 f 362/557/240 317/558/240 365/559/240 364/560/240 f 317/561/241 320/562/241 366/563/241 365/564/241 f 320/565/242 363/566/242 367/553/242 366/556/242 f 364/567/158 367/568/158 363/569/158 362/570/158 f 371/571/158 367/568/158 364/567/158 368/572/158 f 364/560/243 365/559/243 369/573/243 368/574/243 f 366/563/244 370/575/244 369/576/244 365/564/244 f 371/554/245 372/577/245 330/578/245 370/555/245 f 369/573/246 374/579/246 373/580/246 368/574/246 f 372/577/247 375/581/247 334/582/247 330/578/247 f 374/579/248 335/583/248 376/584/248 373/580/248 f 334/582/226 375/581/226 376/584/226 335/583/226 f 368/572/158 373/585/158 376/584/158 375/581/158 372/586/158 371/571/158 f 369/576/249 370/575/249 330/587/249 334/582/249 335/583/249 374/588/249 f 360/589/226 359/492/226 403/541/226 402/540/226 f 333/527/226 361/526/226 401/544/226 336/533/226 f 359/492/226 358/486/226 404/536/226 403/541/226 f 361/526/226 360/589/226 402/540/226 401/544/226 f 315/590/250 389/538/250 390/523/250 316/522/250 f 328/591/251 330/488/251 391/491/251 397/592/251 f 314/593/252 388/535/252 389/538/252 315/590/252 f 313/594/253 387/542/253 388/535/253 314/593/253 f 397/592/254 391/491/254 392/484/254 398/546/254 f 326/516/255 332/543/255 385/545/255 311/517/255 f 311/517/256 385/545/256 386/539/256 312/595/256 f 395/551/257 360/589/257 361/526/257 396/520/257 f 394/493/258 359/492/258 360/589/258 395/551/258 f 312/595/259 386/539/259 387/542/259 313/594/259 f 342/596/260 309/552/260 310/495/260 343/494/260 f 338/509/261 397/592/261 398/546/261 339/597/261 f 341/598/262 400/550/262 309/552/262 342/596/262 f 324/508/263 328/591/263 397/592/263 338/509/263 f 380/599/264 379/498/264 344/501/264 345/600/264 f 381/601/265 380/599/265 345/600/265 346/602/265 f 340/603/266 399/547/266 400/550/266 341/598/266 f 339/597/267 398/546/267 399/547/267 340/603/267 f 377/604/268 353/605/268 341/598/268 342/596/268 f 382/606/269 381/601/269 346/602/269 347/607/269 f 384/608/270 383/609/270 348/610/270 349/549/270 f 317/611/271 384/608/271 349/549/271 321/548/271 f 383/609/272 382/606/272 347/607/272 348/610/272 f 352/612/273 351/613/273 339/597/273 340/603/273 f 351/613/274 350/506/274 338/509/274 339/597/274 f 353/605/275 352/612/275 340/603/275 341/598/275 f 346/602/276 345/600/276 312/595/276 313/594/276 f 378/614/277 377/604/277 342/596/277 343/494/277 f 347/607/278 346/602/278 313/594/278 314/593/278 f 348/610/279 347/607/279 314/593/279 315/590/279 f 349/549/280 348/610/280 315/590/280 316/522/280 f 319/615/281 378/614/281 343/494/281 323/497/281 f 345/600/282 344/501/282 311/517/282 312/595/282 f 243/616/283 247/617/283 250/618/283 246/619/283 f 246/619/283 242/620/283 239/621/283 243/616/283 f 247/617/283 253/622/283 257/623/283 256/624/283 252/625/283 250/618/283 o dtrack_s3_30.sleepers.001_Cube.009 v -1.256096 -0.510000 -0.201944 v -0.594658 -0.510000 1.124696 v -0.487266 -0.510000 1.071152 v -1.148704 -0.510000 -0.255488 v -1.256096 -0.460000 -0.201944 v -0.594657 -0.460000 1.124696 v -0.487266 -0.460000 1.071152 v -1.148703 -0.460000 -0.255488 v -1.016096 -0.510000 -0.321944 v -0.354658 -0.510000 1.004696 v -0.247266 -0.510000 0.951152 v -0.908704 -0.510000 -0.375488 v -1.016096 -0.460000 -0.321944 v -0.354657 -0.460000 1.004696 v -0.247266 -0.460000 0.951152 v -0.908703 -0.460000 -0.375488 v -0.776096 -0.510000 -0.441944 v -0.114658 -0.510000 0.884696 v -0.007266 -0.510000 0.831152 v -0.668704 -0.510000 -0.495488 v -0.776096 -0.460000 -0.441944 v -0.114657 -0.460000 0.884696 v -0.007266 -0.460000 0.831152 v -0.668703 -0.460000 -0.495488 v -0.536096 -0.510000 -0.561944 v 0.125342 -0.510000 0.764696 v 0.232734 -0.510000 0.711152 v -0.428704 -0.510000 -0.615488 v -0.536096 -0.460000 -0.561944 v 0.125343 -0.460000 0.764696 v 0.232734 -0.460000 0.711152 v -0.428703 -0.460000 -0.615488 v -0.412306 -0.512551 -0.637587 v 0.429612 -0.506060 0.582496 v 0.528378 -0.505618 0.514341 v -0.313540 -0.512109 -0.705743 v -0.412582 -0.462552 -0.637663 v 0.429337 -0.456061 0.582421 v 0.528102 -0.455619 0.514266 v -0.313816 -0.462110 -0.705818 v 0.818151 -0.510000 0.230055 v -0.230055 -0.510000 -0.818151 v -0.314908 -0.510000 -0.733298 v 0.733299 -0.510000 0.314908 v 0.818151 -0.460000 0.230055 v -0.230055 -0.460000 -0.818151 v -0.314908 -0.460000 -0.733298 v 0.733298 -0.460000 0.314908 v 0.978798 -0.510000 0.069408 v -0.069408 -0.510000 -0.978798 v -0.154261 -0.510000 -0.893945 v 0.893945 -0.510000 0.154261 v 0.978798 -0.460000 0.069408 v -0.069409 -0.460000 -0.978798 v -0.154261 -0.460000 -0.893945 v 0.893945 -0.460000 0.154261 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vt 0.958794 0.962518 vt 0.958793 0.034812 vt 0.883694 0.034812 vt 0.883696 0.962519 vt 0.990085 0.962519 vt 0.990085 0.034812 vt 0.958793 0.003520 vt 0.883694 0.003521 vt 0.852403 0.034812 vt 0.852404 0.962519 vt 0.883696 0.993810 vt 0.958794 0.993809 vn 0.0000 1.0000 0.0000 vn -0.8949 0.0000 0.4462 vn 0.4462 -0.0000 0.8949 vn 0.8949 0.0000 -0.4462 vn -0.4462 0.0000 -0.8949 vn -0.0055 1.0000 -0.0015 vn -0.8230 -0.0037 0.5680 vn 0.5679 0.0044 0.8231 vn 0.8230 0.0037 -0.5680 vn -0.5679 -0.0044 -0.8231 vn 0.7071 -0.0000 -0.7071 vn -0.7071 -0.0000 -0.7071 vn -0.7071 -0.0000 0.7071 vn 0.7071 0.0000 0.7071 usemtl Sleepers s off f 409/626/284 410/627/284 411/628/284 412/629/284 f 405/630/285 406/631/285 410/627/285 409/626/285 f 406/632/286 407/633/286 411/628/286 410/627/286 f 407/634/287 408/635/287 412/629/287 411/628/287 f 409/626/288 412/629/288 408/636/288 405/637/288 f 417/638/284 418/639/284 419/640/284 420/641/284 f 413/642/285 414/643/285 418/639/285 417/638/285 f 414/644/286 415/645/286 419/640/286 418/639/286 f 415/646/287 416/647/287 420/641/287 419/640/287 f 417/638/288 420/641/288 416/648/288 413/649/288 f 425/650/284 426/651/284 427/652/284 428/653/284 f 421/654/285 422/655/285 426/651/285 425/650/285 f 422/656/286 423/657/286 427/652/286 426/651/286 f 423/658/287 424/659/287 428/653/287 427/652/287 f 425/650/288 428/653/288 424/660/288 421/661/288 f 433/662/284 434/663/284 435/664/284 436/665/284 f 429/666/285 430/667/285 434/663/285 433/662/285 f 430/668/286 431/669/286 435/664/286 434/663/286 f 431/670/287 432/671/287 436/665/287 435/664/287 f 433/662/288 436/665/288 432/672/288 429/673/288 f 441/674/289 442/675/289 443/676/289 444/677/289 f 437/678/290 438/679/290 442/675/290 441/674/290 f 438/680/291 439/681/291 443/676/291 442/675/291 f 439/682/292 440/683/292 444/677/292 443/676/292 f 441/674/293 444/677/293 440/684/293 437/685/293 f 449/686/284 450/687/284 451/688/284 452/689/284 f 445/690/294 446/691/294 450/687/294 449/686/294 f 446/692/295 447/693/295 451/688/295 450/687/295 f 447/694/296 448/695/296 452/689/296 451/688/296 f 449/686/297 452/689/297 448/696/297 445/697/297 f 457/698/284 458/699/284 459/700/284 460/701/284 f 453/702/294 454/703/294 458/699/294 457/698/294 f 454/704/295 455/705/295 459/700/295 458/699/295 f 455/706/296 456/707/296 460/701/296 459/700/296 f 457/698/297 460/701/297 456/708/297 453/709/297