~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/CPLYMeshFileLoader.cpp

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2009-2011 Gaz Davidson
 
2
// This file is part of the "Irrlicht Engine".
 
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
 
4
 
 
5
#include "IrrCompileConfig.h"
 
6
#ifdef _IRR_COMPILE_WITH_PLY_LOADER_
 
7
 
 
8
#include "CPLYMeshFileLoader.h"
 
9
#include "IMeshManipulator.h"
 
10
#include "SMesh.h"
 
11
#include "CDynamicMeshBuffer.h"
 
12
#include "SAnimatedMesh.h"
 
13
#include "IReadFile.h"
 
14
#include "fast_atof.h"
 
15
#include "os.h"
 
16
 
 
17
namespace irr
 
18
{
 
19
namespace scene
 
20
{
 
21
 
 
22
// input buffer must be at least twice as long as the longest line in the file
 
23
#define PLY_INPUT_BUFFER_SIZE 51200 // file is loaded in 50k chunks
 
24
 
 
25
// constructor
 
26
CPLYMeshFileLoader::CPLYMeshFileLoader()
 
27
: File(0), Buffer(0)
 
28
{
 
29
}
 
30
 
 
31
CPLYMeshFileLoader::~CPLYMeshFileLoader()
 
32
{
 
33
        // delete the buffer in case we didn't earlier
 
34
        // (we do, but this could be disabled to increase the speed of loading hundreds of meshes)
 
35
        if (Buffer)
 
36
        {
 
37
                delete [] Buffer;
 
38
                Buffer = 0;
 
39
        }
 
40
 
 
41
        // Destroy the element list if it exists
 
42
        for (u32 i=0; i<ElementList.size(); ++i)
 
43
                delete ElementList[i];
 
44
        ElementList.clear();
 
45
}
 
46
 
 
47
//! returns true if the file maybe is able to be loaded by this class
 
48
bool CPLYMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
 
49
{
 
50
        return core::hasFileExtension(filename, "ply");
 
51
}
 
52
 
 
53
 
 
54
//! creates/loads an animated mesh from the file.
 
55
IAnimatedMesh* CPLYMeshFileLoader::createMesh(io::IReadFile* file)
 
56
{
 
57
        if (!file)
 
58
                return 0;
 
59
 
 
60
        File = file;
 
61
        File->grab();
 
62
 
 
63
        // attempt to allocate the buffer and fill with data
 
64
        if (!allocateBuffer())
 
65
        {
 
66
                File->drop();
 
67
                File = 0;
 
68
                return 0;
 
69
        }
 
70
 
 
71
        // start with empty mesh
 
72
        SAnimatedMesh* animMesh = 0;
 
73
        u32 vertCount=0;
 
74
 
 
75
        // Currently only supports ASCII meshes
 
76
        if (strcmp(getNextLine(), "ply"))
 
77
        {
 
78
                os::Printer::log("Not a valid PLY file", file->getFileName().c_str(), ELL_ERROR);
 
79
        }
 
80
        else
 
81
        {
 
82
                // cut the next line out
 
83
                c8 *line = getNextLine();
 
84
                // grab the word from this line
 
85
                c8 *word = getNextWord();
 
86
 
 
87
                // ignore comments
 
88
                while (strcmp(word, "comment") == 0)
 
89
                {
 
90
                        line = getNextLine();
 
91
                        word = getNextWord();
 
92
                }
 
93
 
 
94
                bool readingHeader   = true;
 
95
                bool continueReading = true;
 
96
                IsBinaryFile = false;
 
97
                IsWrongEndian= false;
 
98
 
 
99
                do
 
100
                {
 
101
                        if (strcmp(word, "format") == 0)
 
102
                        {
 
103
                                word = getNextWord();
 
104
 
 
105
                                if      (strcmp(word, "binary_little_endian") == 0)
 
106
                                {
 
107
                                        IsBinaryFile = true;
 
108
#ifdef __BIG_ENDIAN__
 
109
                                        IsWrongEndian = true;
 
110
#endif
 
111
 
 
112
                                }
 
113
                                else if (strcmp(word, "binary_big_endian") == 0)
 
114
                                {
 
115
                                        IsBinaryFile = true;
 
116
#ifndef __BIG_ENDIAN__
 
117
                                        IsWrongEndian = true;
 
118
#endif
 
119
                                }
 
120
                                else if (strcmp(word, "ascii"))
 
121
                                {
 
122
                                        // abort if this isn't an ascii or a binary mesh
 
123
                                        os::Printer::log("Unsupported PLY mesh format", word, ELL_ERROR);
 
124
                                        continueReading = false;
 
125
                                }
 
126
 
 
127
                                if (continueReading)
 
128
                                {
 
129
                                        word = getNextWord();
 
130
                                        if (strcmp(word, "1.0"))
 
131
                                        {
 
132
                                                os::Printer::log("Unsupported PLY mesh version", word, ELL_WARNING);
 
133
                                        }
 
134
                                }
 
135
                        }
 
136
                        else if (strcmp(word, "property") == 0)
 
137
                        {
 
138
                                word = getNextWord();
 
139
 
 
140
                                if (!ElementList.size())
 
141
                                {
 
142
                                        os::Printer::log("PLY property found before element", word, ELL_WARNING);
 
143
                                }
 
144
                                else
 
145
                                {
 
146
                                        // get element
 
147
                                        SPLYElement* el = ElementList[ElementList.size()-1];
 
148
 
 
149
                                        // fill property struct
 
150
                                        SPLYProperty prop;
 
151
                                        prop.Type = getPropertyType(word);
 
152
                                        el->KnownSize += prop.size();
 
153
 
 
154
                                        if (prop.Type == EPLYPT_LIST)
 
155
                                        {
 
156
                                                el->IsFixedWidth = false;
 
157
 
 
158
                                                word = getNextWord();
 
159
 
 
160
                                                prop.Data.List.CountType = getPropertyType(word);
 
161
                                                if (IsBinaryFile && prop.Data.List.CountType == EPLYPT_UNKNOWN)
 
162
                                                {
 
163
                                                        os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR);
 
164
                                                        continueReading = false;
 
165
                                                }
 
166
                                                else
 
167
                                                {
 
168
                                                        word = getNextWord();
 
169
                                                        prop.Data.List.ItemType = getPropertyType(word);
 
170
                                                        if (IsBinaryFile && prop.Data.List.ItemType == EPLYPT_UNKNOWN)
 
171
                                                        {
 
172
                                                                os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR);
 
173
                                                                continueReading = false;
 
174
                                                        }
 
175
                                                }
 
176
                                        }
 
177
                                        else if (IsBinaryFile && prop.Type == EPLYPT_UNKNOWN)
 
178
                                        {
 
179
                                                os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR);
 
180
                                                continueReading = false;
 
181
                                        }
 
182
 
 
183
                                        prop.Name = getNextWord();
 
184
 
 
185
                                        // add property to element
 
186
                                        el->Properties.push_back(prop);
 
187
                                }
 
188
                        }
 
189
                        else if (strcmp(word, "element")    == 0)
 
190
                        {
 
191
                                SPLYElement* el = new SPLYElement;
 
192
                                el->Name  = getNextWord();
 
193
                                el->Count = atoi(getNextWord());
 
194
                                el->IsFixedWidth = true;
 
195
                                el->KnownSize = 0;
 
196
                                ElementList.push_back(el);
 
197
 
 
198
                                if (el->Name == "vertex")
 
199
                                        vertCount = el->Count;
 
200
 
 
201
                        }
 
202
                        else if (strcmp(word, "end_header") == 0)
 
203
                        {
 
204
                                readingHeader = false;
 
205
                                if (IsBinaryFile)
 
206
                                {
 
207
                                        StartPointer = LineEndPointer + 1;
 
208
                                }
 
209
                        }
 
210
                        else if (strcmp(word, "comment") == 0)
 
211
                        {
 
212
                                // ignore line
 
213
                        }
 
214
                        else
 
215
                        {
 
216
                                os::Printer::log("Unknown item in PLY file", word, ELL_WARNING);
 
217
                        }
 
218
 
 
219
                        if (readingHeader && continueReading)
 
220
                        {
 
221
                                line = getNextLine();
 
222
                                word = getNextWord();
 
223
                        }
 
224
                }
 
225
                while (readingHeader && continueReading);
 
226
 
 
227
                // now to read the actual data from the file
 
228
                if (continueReading)
 
229
                {
 
230
                        // create a mesh buffer
 
231
                        CDynamicMeshBuffer *mb = new CDynamicMeshBuffer(video::EVT_STANDARD, vertCount > 65565 ? video::EIT_32BIT : video::EIT_16BIT);
 
232
                        mb->getVertexBuffer().reallocate(vertCount);
 
233
                        mb->getIndexBuffer().reallocate(vertCount);
 
234
                        mb->setHardwareMappingHint(EHM_STATIC);
 
235
 
 
236
                        // loop through each of the elements
 
237
                        for (u32 i=0; i<ElementList.size(); ++i)
 
238
                        {
 
239
                                // do we want this element type?
 
240
                                if (ElementList[i]->Name == "vertex")
 
241
                                {
 
242
                                        // loop through vertex properties
 
243
                                        for (u32 j=0; j < ElementList[i]->Count; ++j)
 
244
                                                readVertex(*ElementList[i], mb);
 
245
                                }
 
246
                                else if (ElementList[i]->Name == "face")
 
247
                                {
 
248
                                        // read faces
 
249
                                        for (u32 j=0; j < ElementList[i]->Count; ++j)
 
250
                                                readFace(*ElementList[i], mb);
 
251
                                }
 
252
                                else
 
253
                                {
 
254
                                        // skip these elements
 
255
                                        for (u32 j=0; j < ElementList[i]->Count; ++j)
 
256
                                                skipElement(*ElementList[i]);
 
257
                                }
 
258
                        }
 
259
                        mb->recalculateBoundingBox();
 
260
                        SMesh* m = new SMesh();
 
261
                        m->addMeshBuffer(mb);
 
262
                        m->recalculateBoundingBox();
 
263
                        mb->drop();
 
264
                        animMesh = new SAnimatedMesh();
 
265
                        animMesh->addMesh(m);
 
266
                        animMesh->recalculateBoundingBox();
 
267
                        m->drop();
 
268
                }
 
269
        }
 
270
 
 
271
 
 
272
        // free the buffer
 
273
        delete [] Buffer;
 
274
        Buffer = 0;
 
275
        File->drop();
 
276
        File = 0;
 
277
 
 
278
        // if we managed to create a mesh, return it
 
279
        return animMesh;
 
280
}
 
281
 
 
282
bool CPLYMeshFileLoader::readVertex(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb)
 
283
{
 
284
        if (!IsBinaryFile)
 
285
                getNextLine();
 
286
 
 
287
        video::S3DVertex vert;
 
288
        vert.Color.set(255,255,255,255);
 
289
        vert.TCoords.X = 0.0f;
 
290
        vert.TCoords.Y = 0.0f;
 
291
        vert.Normal.X = 0.0f;
 
292
        vert.Normal.Y = 1.0f;
 
293
        vert.Normal.Z = 0.0f;
 
294
 
 
295
        for (u32 i=0; i < Element.Properties.size(); ++i)
 
296
        {
 
297
                E_PLY_PROPERTY_TYPE t = Element.Properties[i].Type;
 
298
 
 
299
                if      (Element.Properties[i].Name == "x")
 
300
                        vert.Pos.X = getFloat(t);
 
301
                else if (Element.Properties[i].Name == "y")
 
302
                        vert.Pos.Z = getFloat(t);
 
303
                else if (Element.Properties[i].Name == "z")
 
304
                        vert.Pos.Y = getFloat(t);
 
305
                else if (Element.Properties[i].Name == "nx")
 
306
                        vert.Normal.X = getFloat(t);
 
307
                else if (Element.Properties[i].Name == "ny")
 
308
                        vert.Normal.Z = getFloat(t);
 
309
                else if (Element.Properties[i].Name == "nz")
 
310
                        vert.Normal.Y = getFloat(t);
 
311
                else if (Element.Properties[i].Name == "u")
 
312
                        vert.TCoords.X = getFloat(t);
 
313
                else if (Element.Properties[i].Name == "v")
 
314
                        vert.TCoords.Y = getFloat(t);
 
315
                else if (Element.Properties[i].Name == "red")
 
316
                {
 
317
                        u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
 
318
                        vert.Color.setRed(value);
 
319
                }
 
320
                else if (Element.Properties[i].Name == "green")
 
321
                {
 
322
                        u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
 
323
                        vert.Color.setGreen(value);
 
324
                }
 
325
                else if (Element.Properties[i].Name == "blue")
 
326
                {
 
327
                        u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
 
328
                        vert.Color.setBlue(value);
 
329
                }
 
330
                else if (Element.Properties[i].Name == "alpha")
 
331
                {
 
332
                        u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
 
333
                        vert.Color.setAlpha(value);
 
334
                }
 
335
                else
 
336
                        skipProperty(Element.Properties[i]);
 
337
        }
 
338
 
 
339
        mb->getVertexBuffer().push_back(vert);
 
340
 
 
341
        return true;
 
342
}
 
343
 
 
344
bool CPLYMeshFileLoader::readFace(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb)
 
345
{
 
346
        if (!IsBinaryFile)
 
347
                getNextLine();
 
348
 
 
349
        for (u32 i=0; i < Element.Properties.size(); ++i)
 
350
        {
 
351
                if ( (Element.Properties[i].Name == "vertex_indices" ||
 
352
                          Element.Properties[i].Name == "vertex_index") && Element.Properties[i].Type == EPLYPT_LIST)
 
353
                {
 
354
                        // get count
 
355
                        s32 count = getInt(Element.Properties[i].Data.List.CountType);
 
356
                        u32 a = getInt(Element.Properties[i].Data.List.ItemType),
 
357
                                b = getInt(Element.Properties[i].Data.List.ItemType),
 
358
                                c = getInt(Element.Properties[i].Data.List.ItemType);
 
359
                        s32 j = 3;
 
360
 
 
361
                        mb->getIndexBuffer().push_back(a);
 
362
                        mb->getIndexBuffer().push_back(c);
 
363
                        mb->getIndexBuffer().push_back(b);
 
364
 
 
365
                        for (; j < count; ++j)
 
366
                        {
 
367
                                b = c;
 
368
                                c = getInt(Element.Properties[i].Data.List.ItemType);
 
369
                                mb->getIndexBuffer().push_back(a);
 
370
                                mb->getIndexBuffer().push_back(c);
 
371
                                mb->getIndexBuffer().push_back(b);
 
372
                        }
 
373
                }
 
374
                else if (Element.Properties[i].Name == "intensity")
 
375
                {
 
376
                        // todo: face intensity
 
377
                        skipProperty(Element.Properties[i]);
 
378
                }
 
379
                else
 
380
                        skipProperty(Element.Properties[i]);
 
381
        }
 
382
        return true;
 
383
}
 
384
 
 
385
// skips an element and all properties. return false on EOF
 
386
void CPLYMeshFileLoader::skipElement(const SPLYElement &Element)
 
387
{
 
388
        if (IsBinaryFile)
 
389
                if (Element.IsFixedWidth)
 
390
                        moveForward(Element.KnownSize);
 
391
                else
 
392
                        for (u32 i=0; i < Element.Properties.size(); ++i)
 
393
                                skipProperty(Element.Properties[i]);
 
394
        else
 
395
                getNextLine();
 
396
}
 
397
 
 
398
void CPLYMeshFileLoader::skipProperty(const SPLYProperty &Property)
 
399
{
 
400
        if (Property.Type == EPLYPT_LIST)
 
401
        {
 
402
                s32 count = getInt(Property.Data.List.CountType);
 
403
 
 
404
                for (s32 i=0; i < count; ++i)
 
405
                        getInt(Property.Data.List.CountType);
 
406
        }
 
407
        else
 
408
        {
 
409
                if (IsBinaryFile)
 
410
                        moveForward(Property.size());
 
411
                else
 
412
                        getNextWord();
 
413
        }
 
414
}
 
415
 
 
416
 
 
417
bool CPLYMeshFileLoader::allocateBuffer()
 
418
{
 
419
        // Destroy the element list if it exists
 
420
        for (u32 i=0; i<ElementList.size(); ++i)
 
421
                delete ElementList[i];
 
422
        ElementList.clear();
 
423
 
 
424
        if (!Buffer)
 
425
                Buffer = new c8[PLY_INPUT_BUFFER_SIZE];
 
426
 
 
427
        // not enough memory?
 
428
        if (!Buffer)
 
429
                return false;
 
430
 
 
431
        // blank memory
 
432
        memset(Buffer, 0, PLY_INPUT_BUFFER_SIZE);
 
433
 
 
434
        StartPointer   = Buffer;
 
435
        EndPointer     = Buffer;
 
436
        LineEndPointer = Buffer-1;
 
437
        WordLength     = -1;
 
438
        EndOfFile      = false;
 
439
 
 
440
        // get data from the file
 
441
        fillBuffer();
 
442
 
 
443
        return true;
 
444
}
 
445
 
 
446
// gets more data from the file. returns false on EOF
 
447
void CPLYMeshFileLoader::fillBuffer()
 
448
{
 
449
        if (EndOfFile)
 
450
                return;
 
451
 
 
452
        u32 length = EndPointer - StartPointer;
 
453
        if (length && StartPointer != Buffer)
 
454
        {
 
455
                // copy the remaining data to the start of the buffer
 
456
                memcpy(Buffer, StartPointer, length);
 
457
        }
 
458
        // reset start position
 
459
        StartPointer = Buffer;
 
460
        EndPointer   = StartPointer + length;
 
461
 
 
462
        if (File->getPos() == File->getSize())
 
463
        {
 
464
                EndOfFile = true;
 
465
        }
 
466
        else
 
467
        {
 
468
                // read data from the file
 
469
                u32 count = File->read(EndPointer, PLY_INPUT_BUFFER_SIZE - length);
 
470
 
 
471
                // increment the end pointer by the number of bytes read
 
472
                EndPointer = EndPointer + count;
 
473
 
 
474
                // if we didn't completely fill the buffer
 
475
                if (count != PLY_INPUT_BUFFER_SIZE - length)
 
476
                {
 
477
                        // blank the rest of the memory
 
478
                        memset(EndPointer, 0, Buffer + PLY_INPUT_BUFFER_SIZE - EndPointer);
 
479
 
 
480
                        // end of file
 
481
                        EndOfFile = true;
 
482
                }
 
483
        }
 
484
}
 
485
 
 
486
// skips x bytes in the file, getting more data if required
 
487
void CPLYMeshFileLoader::moveForward(u32 bytes)
 
488
{
 
489
        if (StartPointer + bytes >= EndPointer)
 
490
                fillBuffer();
 
491
        if (StartPointer + bytes < EndPointer)
 
492
                StartPointer += bytes;
 
493
        else
 
494
                StartPointer = EndPointer;
 
495
}
 
496
 
 
497
E_PLY_PROPERTY_TYPE CPLYMeshFileLoader::getPropertyType(const c8* typeString) const
 
498
{
 
499
        if      (strcmp(typeString, "char")   == 0 ||
 
500
                 strcmp(typeString, "uchar")  == 0 ||
 
501
                 strcmp(typeString, "int8")   == 0 ||
 
502
                 strcmp(typeString, "uint8")  == 0)
 
503
        {
 
504
                return EPLYPT_INT8;
 
505
        }
 
506
        else if (strcmp(typeString, "uint")   == 0 ||
 
507
                 strcmp(typeString, "int16")  == 0 ||
 
508
                 strcmp(typeString, "uint16") == 0 ||
 
509
                 strcmp(typeString, "short")  == 0 ||
 
510
                 strcmp(typeString, "ushort") == 0)
 
511
        {
 
512
                return EPLYPT_INT16;
 
513
        }
 
514
        else if (strcmp(typeString, "int")    == 0 ||
 
515
                 strcmp(typeString, "long")   == 0 ||
 
516
                 strcmp(typeString, "ulong")  == 0 ||
 
517
                 strcmp(typeString, "int32")  == 0 ||
 
518
                 strcmp(typeString, "uint32") == 0)
 
519
        {
 
520
                return EPLYPT_INT32;
 
521
        }
 
522
        else if (strcmp(typeString, "float")   == 0 ||
 
523
                 strcmp(typeString, "float32") == 0)
 
524
        {
 
525
                return EPLYPT_FLOAT32;
 
526
        }
 
527
        else if (strcmp(typeString, "float64") == 0 ||
 
528
                 strcmp(typeString, "double")  == 0)
 
529
        {
 
530
                return EPLYPT_FLOAT64;
 
531
        }
 
532
        else if ( strcmp(typeString, "list") == 0 )
 
533
        {
 
534
                return EPLYPT_LIST;
 
535
        }
 
536
        else
 
537
        {
 
538
                // unsupported type.
 
539
                // cannot be loaded in binary mode
 
540
                return EPLYPT_UNKNOWN;
 
541
        }
 
542
}
 
543
 
 
544
 
 
545
// Split the string data into a line in place by terminating it instead of copying.
 
546
c8* CPLYMeshFileLoader::getNextLine()
 
547
{
 
548
        // move the start pointer along
 
549
        StartPointer = LineEndPointer + 1;
 
550
 
 
551
        // crlf split across buffer move
 
552
        if (*StartPointer == '\n')
 
553
        {
 
554
                *StartPointer = '\0';
 
555
                ++StartPointer;
 
556
        }
 
557
 
 
558
        // begin at the start of the next line
 
559
        c8* pos = StartPointer;
 
560
        while (pos < EndPointer && *pos && *pos != '\r' && *pos != '\n')
 
561
                ++pos;
 
562
 
 
563
        if ( pos < EndPointer && ( *(pos+1) == '\r' || *(pos+1) == '\n') )
 
564
        {
 
565
                *pos = '\0';
 
566
                ++pos;
 
567
        }
 
568
 
 
569
        // we have reached the end of the buffer
 
570
        if (pos >= EndPointer)
 
571
        {
 
572
                // get data from the file
 
573
                if (!EndOfFile)
 
574
                {
 
575
                        fillBuffer();
 
576
                        // reset line end pointer
 
577
                        LineEndPointer = StartPointer - 1;
 
578
 
 
579
                        if (StartPointer != EndPointer)
 
580
                                return getNextLine();
 
581
                        else
 
582
                                return Buffer;
 
583
                }
 
584
                else
 
585
                {
 
586
                        // EOF
 
587
                        StartPointer = EndPointer-1;
 
588
                        *StartPointer = '\0';
 
589
                        return StartPointer;
 
590
                }
 
591
        }
 
592
        else
 
593
        {
 
594
                // null terminate the string in place
 
595
                *pos = '\0';
 
596
                LineEndPointer = pos;
 
597
                WordLength = -1;
 
598
                // return pointer to the start of the line
 
599
                return StartPointer;
 
600
        }
 
601
}
 
602
// null terminate the next word on the previous line and move the next word pointer along
 
603
// since we already have a full line in the buffer, we never need to retrieve more data
 
604
c8* CPLYMeshFileLoader::getNextWord()
 
605
{
 
606
        // move the start pointer along
 
607
        StartPointer += WordLength + 1;
 
608
 
 
609
        if (StartPointer == LineEndPointer)
 
610
        {
 
611
                WordLength = -1; //
 
612
                return LineEndPointer;
 
613
        }
 
614
        // begin at the start of the next word
 
615
        c8* pos = StartPointer;
 
616
        while (*pos && pos < LineEndPointer && pos < EndPointer && *pos != ' ' && *pos != '\t')
 
617
                ++pos;
 
618
 
 
619
        while(*pos && pos < LineEndPointer && pos < EndPointer && (*pos == ' ' || *pos == '\t') )
 
620
        {
 
621
                // null terminate the string in place
 
622
                *pos = '\0';
 
623
                ++pos;
 
624
        }
 
625
        --pos;
 
626
        WordLength = pos-StartPointer;
 
627
        // return pointer to the start of the word
 
628
        return StartPointer;
 
629
}
 
630
// read the next float from the file and move the start pointer along
 
631
f32 CPLYMeshFileLoader::getFloat(E_PLY_PROPERTY_TYPE t)
 
632
{
 
633
        f32 retVal = 0.0f;
 
634
 
 
635
        if (IsBinaryFile)
 
636
        {
 
637
                if (EndPointer - StartPointer < 8)
 
638
                        fillBuffer();
 
639
 
 
640
                if (EndPointer - StartPointer > 0)
 
641
                {
 
642
                        switch (t)
 
643
                        {
 
644
                        case EPLYPT_INT8:
 
645
                                retVal = *StartPointer;
 
646
                                StartPointer++;
 
647
                                break;
 
648
                        case EPLYPT_INT16:
 
649
                                if (IsWrongEndian)
 
650
                                        retVal = os::Byteswap::byteswap(*(reinterpret_cast<s16*>(StartPointer)));
 
651
                                else
 
652
                                        retVal = *(reinterpret_cast<s16*>(StartPointer));
 
653
                                StartPointer += 2;
 
654
                                break;
 
655
                        case EPLYPT_INT32:
 
656
                                if (IsWrongEndian)
 
657
                                        retVal = f32(os::Byteswap::byteswap(*(reinterpret_cast<s32*>(StartPointer))));
 
658
                                else
 
659
                                        retVal = f32(*(reinterpret_cast<s32*>(StartPointer)));
 
660
                                StartPointer += 4;
 
661
                                break;
 
662
                        case EPLYPT_FLOAT32:
 
663
                                if (IsWrongEndian)
 
664
                                        retVal = os::Byteswap::byteswap(*(reinterpret_cast<f32*>(StartPointer)));
 
665
                                else
 
666
                                        retVal = *(reinterpret_cast<f32*>(StartPointer));
 
667
                                StartPointer += 4;
 
668
                                break;
 
669
                        case EPLYPT_FLOAT64:
 
670
                                // todo: byteswap 64-bit
 
671
                                retVal = f32(*(reinterpret_cast<f64*>(StartPointer)));
 
672
                                StartPointer += 8;
 
673
                                break;
 
674
                        case EPLYPT_LIST:
 
675
                        case EPLYPT_UNKNOWN:
 
676
                        default:
 
677
                                retVal = 0.0f;
 
678
                                StartPointer++; // ouch!
 
679
                        }
 
680
                }
 
681
                else
 
682
                        retVal = 0.0f;
 
683
        }
 
684
        else
 
685
        {
 
686
                c8* word = getNextWord();
 
687
                switch (t)
 
688
                {
 
689
                case EPLYPT_INT8:
 
690
                case EPLYPT_INT16:
 
691
                case EPLYPT_INT32:
 
692
                        retVal = f32(atoi(word));
 
693
                        break;
 
694
                case EPLYPT_FLOAT32:
 
695
                case EPLYPT_FLOAT64:
 
696
                        retVal = f32(atof(word));
 
697
                        break;
 
698
                case EPLYPT_LIST:
 
699
                case EPLYPT_UNKNOWN:
 
700
                default:
 
701
                        retVal = 0.0f;
 
702
                }
 
703
        }
 
704
        return retVal;
 
705
}
 
706
// read the next int from the file and move the start pointer along
 
707
u32 CPLYMeshFileLoader::getInt(E_PLY_PROPERTY_TYPE t)
 
708
{
 
709
        u32 retVal = 0;
 
710
 
 
711
        if (IsBinaryFile)
 
712
        {
 
713
                if (!EndOfFile && EndPointer - StartPointer < 8)
 
714
                        fillBuffer();
 
715
 
 
716
                if (EndPointer - StartPointer)
 
717
                {
 
718
                        switch (t)
 
719
                        {
 
720
                        case EPLYPT_INT8:
 
721
                                retVal = *StartPointer;
 
722
                                StartPointer++;
 
723
                                break;
 
724
                        case EPLYPT_INT16:
 
725
                                if (IsWrongEndian)
 
726
                                        retVal = os::Byteswap::byteswap(*(reinterpret_cast<u16*>(StartPointer)));
 
727
                                else
 
728
                                        retVal = *(reinterpret_cast<u16*>(StartPointer));
 
729
                                StartPointer += 2;
 
730
                                break;
 
731
                        case EPLYPT_INT32:
 
732
                                if (IsWrongEndian)
 
733
                                        retVal = os::Byteswap::byteswap(*(reinterpret_cast<s32*>(StartPointer)));
 
734
                                else
 
735
                                        retVal = *(reinterpret_cast<s32*>(StartPointer));
 
736
                                StartPointer += 4;
 
737
                                break;
 
738
                        case EPLYPT_FLOAT32:
 
739
                                if (IsWrongEndian)
 
740
                                        retVal = (u32)os::Byteswap::byteswap(*(reinterpret_cast<f32*>(StartPointer)));
 
741
                                else
 
742
                                        retVal = (u32)(*(reinterpret_cast<f32*>(StartPointer)));
 
743
                                StartPointer += 4;
 
744
                                break;
 
745
                        case EPLYPT_FLOAT64:
 
746
                                // todo: byteswap 64-bit
 
747
                                retVal = (u32)(*(reinterpret_cast<f64*>(StartPointer)));
 
748
                                StartPointer += 8;
 
749
                                break;
 
750
                        case EPLYPT_LIST:
 
751
                        case EPLYPT_UNKNOWN:
 
752
                        default:
 
753
                                retVal = 0;
 
754
                                StartPointer++; // ouch!
 
755
                        }
 
756
                }
 
757
                else
 
758
                        retVal = 0;
 
759
        }
 
760
        else
 
761
        {
 
762
                c8* word = getNextWord();
 
763
                switch (t)
 
764
                {
 
765
                case EPLYPT_INT8:
 
766
                case EPLYPT_INT16:
 
767
                case EPLYPT_INT32:
 
768
                        retVal = atoi(word);
 
769
                        break;
 
770
                case EPLYPT_FLOAT32:
 
771
                case EPLYPT_FLOAT64:
 
772
                        retVal = u32(atof(word));
 
773
                        break;
 
774
                case EPLYPT_LIST:
 
775
                case EPLYPT_UNKNOWN:
 
776
                default:
 
777
                        retVal = 0;
 
778
                }
 
779
        }
 
780
        return retVal;
 
781
}
 
782
 
 
783
 
 
784
 
 
785
} // end namespace scene
 
786
} // end namespace irr
 
787
 
 
788
#endif // _IRR_COMPILE_WITH_PLY_LOADER_
 
789