diff options
author | cutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475> | 2020-01-03 19:05:16 +0000 |
---|---|---|
committer | cutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475> | 2020-01-03 19:05:16 +0000 |
commit | 2ae2a551a6290f46734307bbfdafea4b1a2cf2ba (patch) | |
tree | ba2f0b468640e44899fed3df2d4cc58795f4a003 /source/Irrlicht/CPLYMeshFileLoader.cpp | |
download | irrlicht-2ae2a551a6290f46734307bbfdafea4b1a2cf2ba.tar.xz |
Merging r5975 through r6036 from trunk to ogl-es branch.
GLES drivers adapted, but only did make compile-tests.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475
Diffstat (limited to 'source/Irrlicht/CPLYMeshFileLoader.cpp')
-rw-r--r-- | source/Irrlicht/CPLYMeshFileLoader.cpp | 818 |
1 files changed, 818 insertions, 0 deletions
diff --git a/source/Irrlicht/CPLYMeshFileLoader.cpp b/source/Irrlicht/CPLYMeshFileLoader.cpp new file mode 100644 index 0000000..03b3e47 --- /dev/null +++ b/source/Irrlicht/CPLYMeshFileLoader.cpp @@ -0,0 +1,818 @@ +// Copyright (C) 2009-2012 Gaz Davidson
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "IrrCompileConfig.h"
+#ifdef _IRR_COMPILE_WITH_PLY_LOADER_
+
+#include "CPLYMeshFileLoader.h"
+#include "IMeshManipulator.h"
+#include "SMesh.h"
+#include "CDynamicMeshBuffer.h"
+#include "SAnimatedMesh.h"
+#include "IReadFile.h"
+#include "fast_atof.h"
+#include "os.h"
+
+namespace irr
+{
+namespace scene
+{
+
+// input buffer must be at least twice as long as the longest line in the file
+#define PLY_INPUT_BUFFER_SIZE 51200 // file is loaded in 50k chunks
+
+// constructor
+CPLYMeshFileLoader::CPLYMeshFileLoader(scene::ISceneManager* smgr)
+: SceneManager(smgr), File(0), Buffer(0)
+{
+}
+
+
+CPLYMeshFileLoader::~CPLYMeshFileLoader()
+{
+ // delete the buffer in case we didn't earlier
+ // (we do, but this could be disabled to increase the speed of loading hundreds of meshes)
+ if (Buffer)
+ {
+ delete [] Buffer;
+ Buffer = 0;
+ }
+
+ // Destroy the element list if it exists
+ for (u32 i=0; i<ElementList.size(); ++i)
+ delete ElementList[i];
+ ElementList.clear();
+}
+
+
+//! returns true if the file maybe is able to be loaded by this class
+bool CPLYMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
+{
+ return core::hasFileExtension(filename, "ply");
+}
+
+
+//! creates/loads an animated mesh from the file.
+IAnimatedMesh* CPLYMeshFileLoader::createMesh(io::IReadFile* file)
+{
+ if (!file)
+ return 0;
+
+ File = file;
+ File->grab();
+
+ // attempt to allocate the buffer and fill with data
+ if (!allocateBuffer())
+ {
+ File->drop();
+ File = 0;
+ return 0;
+ }
+
+ // start with empty mesh
+ SAnimatedMesh* animMesh = 0;
+ u32 vertCount=0;
+
+ // Currently only supports ASCII meshes
+ if (strcmp(getNextLine(), "ply"))
+ {
+ os::Printer::log("Not a valid PLY file", file->getFileName().c_str(), ELL_ERROR);
+ }
+ else
+ {
+ // cut the next line out
+ getNextLine();
+ // grab the word from this line
+ c8 *word = getNextWord();
+
+ // ignore comments
+ while (strcmp(word, "comment") == 0)
+ {
+ getNextLine();
+ word = getNextWord();
+ }
+
+ bool readingHeader = true;
+ bool continueReading = true;
+ IsBinaryFile = false;
+ IsWrongEndian= false;
+
+ do
+ {
+ if (strcmp(word, "format") == 0)
+ {
+ word = getNextWord();
+
+ if (strcmp(word, "binary_little_endian") == 0)
+ {
+ IsBinaryFile = true;
+#ifdef __BIG_ENDIAN__
+ IsWrongEndian = true;
+#endif
+
+ }
+ else if (strcmp(word, "binary_big_endian") == 0)
+ {
+ IsBinaryFile = true;
+#ifndef __BIG_ENDIAN__
+ IsWrongEndian = true;
+#endif
+ }
+ else if (strcmp(word, "ascii"))
+ {
+ // abort if this isn't an ascii or a binary mesh
+ os::Printer::log("Unsupported PLY mesh format", word, ELL_ERROR);
+ continueReading = false;
+ }
+
+ if (continueReading)
+ {
+ word = getNextWord();
+ if (strcmp(word, "1.0"))
+ {
+ os::Printer::log("Unsupported PLY mesh version", word, ELL_WARNING);
+ }
+ }
+ }
+ else if (strcmp(word, "property") == 0)
+ {
+ word = getNextWord();
+
+ if (!ElementList.size())
+ {
+ os::Printer::log("PLY property found before element", word, ELL_WARNING);
+ }
+ else
+ {
+ // get element
+ SPLYElement* el = ElementList[ElementList.size()-1];
+
+ // fill property struct
+ SPLYProperty prop;
+ prop.Type = getPropertyType(word);
+ el->KnownSize += prop.size();
+
+ if (prop.Type == EPLYPT_LIST)
+ {
+ el->IsFixedWidth = false;
+
+ word = getNextWord();
+
+ prop.Data.List.CountType = getPropertyType(word);
+ if (IsBinaryFile && prop.Data.List.CountType == EPLYPT_UNKNOWN)
+ {
+ os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR);
+ continueReading = false;
+ }
+ else
+ {
+ word = getNextWord();
+ prop.Data.List.ItemType = getPropertyType(word);
+ if (IsBinaryFile && prop.Data.List.ItemType == EPLYPT_UNKNOWN)
+ {
+ os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR);
+ continueReading = false;
+ }
+ }
+ }
+ else if (IsBinaryFile && prop.Type == EPLYPT_UNKNOWN)
+ {
+ os::Printer::log("Cannot read binary PLY file containing data types of unknown length", word, ELL_ERROR);
+ continueReading = false;
+ }
+
+ prop.Name = getNextWord();
+
+ // add property to element
+ el->Properties.push_back(prop);
+ }
+ }
+ else if (strcmp(word, "element") == 0)
+ {
+ SPLYElement* el = new SPLYElement;
+ el->Name = getNextWord();
+ el->Count = atoi(getNextWord());
+ el->IsFixedWidth = true;
+ el->KnownSize = 0;
+ ElementList.push_back(el);
+
+ if (el->Name == "vertex")
+ vertCount = el->Count;
+
+ }
+ else if (strcmp(word, "end_header") == 0)
+ {
+ readingHeader = false;
+ if (IsBinaryFile)
+ {
+ StartPointer = LineEndPointer + 1;
+ }
+ }
+ else if (strcmp(word, "comment") == 0)
+ {
+ // ignore line
+ }
+ else
+ {
+ os::Printer::log("Unknown item in PLY file", word, ELL_WARNING);
+ }
+
+ if (readingHeader && continueReading)
+ {
+ getNextLine();
+ word = getNextWord();
+ }
+ }
+ while (readingHeader && continueReading);
+
+ // now to read the actual data from the file
+ if (continueReading)
+ {
+ // create a mesh buffer
+ CDynamicMeshBuffer *mb = new CDynamicMeshBuffer(video::EVT_STANDARD, vertCount > 65565 ? video::EIT_32BIT : video::EIT_16BIT);
+ mb->getVertexBuffer().reallocate(vertCount);
+ mb->getIndexBuffer().reallocate(vertCount);
+ mb->setHardwareMappingHint(EHM_STATIC);
+
+ bool hasNormals=true;
+ // loop through each of the elements
+ for (u32 i=0; i<ElementList.size(); ++i)
+ {
+ // do we want this element type?
+ if (ElementList[i]->Name == "vertex")
+ {
+ // loop through vertex properties
+ for (u32 j=0; j < ElementList[i]->Count; ++j)
+ hasNormals &= readVertex(*ElementList[i], mb);
+ }
+ else if (ElementList[i]->Name == "face")
+ {
+ // read faces
+ for (u32 j=0; j < ElementList[i]->Count; ++j)
+ readFace(*ElementList[i], mb);
+ }
+ else
+ {
+ // skip these elements
+ for (u32 j=0; j < ElementList[i]->Count; ++j)
+ skipElement(*ElementList[i]);
+ }
+ }
+ mb->recalculateBoundingBox();
+ if (!hasNormals)
+ SceneManager->getMeshManipulator()->recalculateNormals(mb);
+ SMesh* m = new SMesh();
+ m->addMeshBuffer(mb);
+ m->recalculateBoundingBox();
+ mb->drop();
+ animMesh = new SAnimatedMesh();
+ animMesh->addMesh(m);
+ animMesh->recalculateBoundingBox();
+ m->drop();
+ }
+ }
+
+
+ // free the buffer
+ delete [] Buffer;
+ Buffer = 0;
+ File->drop();
+ File = 0;
+
+ // if we managed to create a mesh, return it
+ return animMesh;
+}
+
+
+bool CPLYMeshFileLoader::readVertex(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb)
+{
+ if (!IsBinaryFile)
+ getNextLine();
+
+ video::S3DVertex vert;
+ vert.Color.set(255,255,255,255);
+ vert.TCoords.X = 0.0f;
+ vert.TCoords.Y = 0.0f;
+ vert.Normal.X = 0.0f;
+ vert.Normal.Y = 1.0f;
+ vert.Normal.Z = 0.0f;
+
+ bool result=false;
+ for (u32 i=0; i < Element.Properties.size(); ++i)
+ {
+ E_PLY_PROPERTY_TYPE t = Element.Properties[i].Type;
+
+ if (Element.Properties[i].Name == "x")
+ vert.Pos.X = getFloat(t);
+ else if (Element.Properties[i].Name == "y")
+ vert.Pos.Z = getFloat(t);
+ else if (Element.Properties[i].Name == "z")
+ vert.Pos.Y = getFloat(t);
+ else if (Element.Properties[i].Name == "nx")
+ {
+ vert.Normal.X = getFloat(t);
+ result=true;
+ }
+ else if (Element.Properties[i].Name == "ny")
+ {
+ vert.Normal.Z = getFloat(t);
+ result=true;
+ }
+ else if (Element.Properties[i].Name == "nz")
+ {
+ vert.Normal.Y = getFloat(t);
+ result=true;
+ }
+ // there isn't a single convention for the UV, some software like Blender or Assimp uses "st" instead of "uv"
+ else if (Element.Properties[i].Name == "u" || Element.Properties[i].Name == "s")
+ vert.TCoords.X = getFloat(t);
+ else if (Element.Properties[i].Name == "v" || Element.Properties[i].Name == "t")
+ vert.TCoords.Y = getFloat(t);
+ else if (Element.Properties[i].Name == "red")
+ {
+ u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
+ vert.Color.setRed(value);
+ }
+ else if (Element.Properties[i].Name == "green")
+ {
+ u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
+ vert.Color.setGreen(value);
+ }
+ else if (Element.Properties[i].Name == "blue")
+ {
+ u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
+ vert.Color.setBlue(value);
+ }
+ else if (Element.Properties[i].Name == "alpha")
+ {
+ u32 value = Element.Properties[i].isFloat() ? (u32)(getFloat(t)*255.0f) : getInt(t);
+ vert.Color.setAlpha(value);
+ }
+ else
+ skipProperty(Element.Properties[i]);
+ }
+
+ mb->getVertexBuffer().push_back(vert);
+
+ return result;
+}
+
+
+bool CPLYMeshFileLoader::readFace(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb)
+{
+ if (!IsBinaryFile)
+ getNextLine();
+
+ for (u32 i=0; i < Element.Properties.size(); ++i)
+ {
+ if ( (Element.Properties[i].Name == "vertex_indices" ||
+ Element.Properties[i].Name == "vertex_index") && Element.Properties[i].Type == EPLYPT_LIST)
+ {
+ // get count
+ s32 count = getInt(Element.Properties[i].Data.List.CountType);
+ u32 a = getInt(Element.Properties[i].Data.List.ItemType),
+ b = getInt(Element.Properties[i].Data.List.ItemType),
+ c = getInt(Element.Properties[i].Data.List.ItemType);
+ s32 j = 3;
+
+ mb->getIndexBuffer().push_back(a);
+ mb->getIndexBuffer().push_back(c);
+ mb->getIndexBuffer().push_back(b);
+
+ for (; j < count; ++j)
+ {
+ b = c;
+ c = getInt(Element.Properties[i].Data.List.ItemType);
+ mb->getIndexBuffer().push_back(a);
+ mb->getIndexBuffer().push_back(c);
+ mb->getIndexBuffer().push_back(b);
+ }
+ }
+ else if (Element.Properties[i].Name == "intensity")
+ {
+ // todo: face intensity
+ skipProperty(Element.Properties[i]);
+ }
+ else
+ skipProperty(Element.Properties[i]);
+ }
+ return true;
+}
+
+
+// skips an element and all properties. return false on EOF
+void CPLYMeshFileLoader::skipElement(const SPLYElement &Element)
+{
+ if (IsBinaryFile)
+ if (Element.IsFixedWidth)
+ moveForward(Element.KnownSize);
+ else
+ for (u32 i=0; i < Element.Properties.size(); ++i)
+ skipProperty(Element.Properties[i]);
+ else
+ getNextLine();
+}
+
+
+void CPLYMeshFileLoader::skipProperty(const SPLYProperty &Property)
+{
+ if (Property.Type == EPLYPT_LIST)
+ {
+ s32 count = getInt(Property.Data.List.CountType);
+
+ for (s32 i=0; i < count; ++i)
+ getInt(Property.Data.List.CountType);
+ }
+ else
+ {
+ if (IsBinaryFile)
+ moveForward(Property.size());
+ else
+ getNextWord();
+ }
+}
+
+
+bool CPLYMeshFileLoader::allocateBuffer()
+{
+ // Destroy the element list if it exists
+ for (u32 i=0; i<ElementList.size(); ++i)
+ delete ElementList[i];
+ ElementList.clear();
+
+ if (!Buffer)
+ Buffer = new c8[PLY_INPUT_BUFFER_SIZE];
+
+ // not enough memory?
+ if (!Buffer)
+ return false;
+
+ // blank memory
+ memset(Buffer, 0, PLY_INPUT_BUFFER_SIZE);
+
+ StartPointer = Buffer;
+ EndPointer = Buffer;
+ LineEndPointer = Buffer-1;
+ WordLength = -1;
+ EndOfFile = false;
+
+ // get data from the file
+ fillBuffer();
+
+ return true;
+}
+
+
+// gets more data from the file. returns false on EOF
+void CPLYMeshFileLoader::fillBuffer()
+{
+ if (EndOfFile)
+ return;
+
+ size_t length = (size_t)(EndPointer - StartPointer);
+ if (length && StartPointer != Buffer)
+ {
+ // copy the remaining data to the start of the buffer
+ memcpy(Buffer, StartPointer, length);
+ }
+ // reset start position
+ StartPointer = Buffer;
+ EndPointer = StartPointer + length;
+
+ if (File->getPos() == File->getSize())
+ {
+ EndOfFile = true;
+ }
+ else
+ {
+ // read data from the file
+ size_t count = File->read(EndPointer, PLY_INPUT_BUFFER_SIZE - length);
+
+ // increment the end pointer by the number of bytes read
+ EndPointer = EndPointer + count;
+
+ // if we didn't completely fill the buffer
+ if (count != PLY_INPUT_BUFFER_SIZE - length)
+ {
+ // blank the rest of the memory
+ memset(EndPointer, 0, Buffer + PLY_INPUT_BUFFER_SIZE - EndPointer);
+
+ // end of file
+ EndOfFile = true;
+ }
+ }
+}
+
+
+// skips x bytes in the file, getting more data if required
+void CPLYMeshFileLoader::moveForward(u32 bytes)
+{
+ if (StartPointer + bytes >= EndPointer)
+ fillBuffer();
+ if (StartPointer + bytes < EndPointer)
+ StartPointer += bytes;
+ else
+ StartPointer = EndPointer;
+}
+
+
+E_PLY_PROPERTY_TYPE CPLYMeshFileLoader::getPropertyType(const c8* typeString) const
+{
+ if (strcmp(typeString, "char") == 0 ||
+ strcmp(typeString, "uchar") == 0 ||
+ strcmp(typeString, "int8") == 0 ||
+ strcmp(typeString, "uint8") == 0)
+ {
+ return EPLYPT_INT8;
+ }
+ else if (strcmp(typeString, "uint") == 0 ||
+ strcmp(typeString, "int16") == 0 ||
+ strcmp(typeString, "uint16") == 0 ||
+ strcmp(typeString, "short") == 0 ||
+ strcmp(typeString, "ushort") == 0)
+ {
+ return EPLYPT_INT16;
+ }
+ else if (strcmp(typeString, "int") == 0 ||
+ strcmp(typeString, "long") == 0 ||
+ strcmp(typeString, "ulong") == 0 ||
+ strcmp(typeString, "int32") == 0 ||
+ strcmp(typeString, "uint32") == 0)
+ {
+ return EPLYPT_INT32;
+ }
+ else if (strcmp(typeString, "float") == 0 ||
+ strcmp(typeString, "float32") == 0)
+ {
+ return EPLYPT_FLOAT32;
+ }
+ else if (strcmp(typeString, "float64") == 0 ||
+ strcmp(typeString, "double") == 0)
+ {
+ return EPLYPT_FLOAT64;
+ }
+ else if ( strcmp(typeString, "list") == 0 )
+ {
+ return EPLYPT_LIST;
+ }
+ else
+ {
+ // unsupported type.
+ // cannot be loaded in binary mode
+ return EPLYPT_UNKNOWN;
+ }
+}
+
+
+// Split the string data into a line in place by terminating it instead of copying.
+c8* CPLYMeshFileLoader::getNextLine()
+{
+ // move the start pointer along
+ StartPointer = LineEndPointer + 1;
+
+ // crlf split across buffer move
+ if (*StartPointer == '\n')
+ {
+ *StartPointer = '\0';
+ ++StartPointer;
+ }
+
+ // begin at the start of the next line
+ c8* pos = StartPointer;
+ while (pos < EndPointer && *pos && *pos != '\r' && *pos != '\n')
+ ++pos;
+
+ if ( pos < EndPointer && ( *(pos+1) == '\r' || *(pos+1) == '\n') )
+ {
+ *pos = '\0';
+ ++pos;
+ }
+
+ // we have reached the end of the buffer
+ if (pos >= EndPointer)
+ {
+ // get data from the file
+ if (!EndOfFile)
+ {
+ fillBuffer();
+ // reset line end pointer
+ LineEndPointer = StartPointer - 1;
+
+ if (StartPointer != EndPointer)
+ return getNextLine();
+ else
+ return Buffer;
+ }
+ else
+ {
+ // EOF
+ StartPointer = EndPointer-1;
+ *StartPointer = '\0';
+ return StartPointer;
+ }
+ }
+ else
+ {
+ // null terminate the string in place
+ *pos = '\0';
+ LineEndPointer = pos;
+ WordLength = -1;
+ // return pointer to the start of the line
+ return StartPointer;
+ }
+}
+
+
+// null terminate the next word on the previous line and move the next word pointer along
+// since we already have a full line in the buffer, we never need to retrieve more data
+c8* CPLYMeshFileLoader::getNextWord()
+{
+ // move the start pointer along
+ StartPointer += WordLength + 1;
+
+ if (StartPointer == LineEndPointer)
+ {
+ WordLength = -1; //
+ return LineEndPointer;
+ }
+ // begin at the start of the next word
+ c8* pos = StartPointer;
+ while (*pos && pos < LineEndPointer && pos < EndPointer && *pos != ' ' && *pos != '\t')
+ ++pos;
+
+ while(*pos && pos < LineEndPointer && pos < EndPointer && (*pos == ' ' || *pos == '\t') )
+ {
+ // null terminate the string in place
+ *pos = '\0';
+ ++pos;
+ }
+ --pos;
+ WordLength = (s32)(pos-StartPointer);
+ // return pointer to the start of the word
+ return StartPointer;
+}
+
+
+// read the next float from the file and move the start pointer along
+f32 CPLYMeshFileLoader::getFloat(E_PLY_PROPERTY_TYPE t)
+{
+ f32 retVal = 0.0f;
+
+ if (IsBinaryFile)
+ {
+ if (EndPointer - StartPointer < 8)
+ fillBuffer();
+
+ if (EndPointer - StartPointer > 0)
+ {
+ switch (t)
+ {
+ case EPLYPT_INT8:
+ retVal = *StartPointer;
+ StartPointer++;
+ break;
+ case EPLYPT_INT16:
+ if (IsWrongEndian)
+ retVal = os::Byteswap::byteswap(*(reinterpret_cast<s16*>(StartPointer)));
+ else
+ retVal = *(reinterpret_cast<s16*>(StartPointer));
+ StartPointer += 2;
+ break;
+ case EPLYPT_INT32:
+ if (IsWrongEndian)
+ retVal = f32(os::Byteswap::byteswap(*(reinterpret_cast<s32*>(StartPointer))));
+ else
+ retVal = f32(*(reinterpret_cast<s32*>(StartPointer)));
+ StartPointer += 4;
+ break;
+ case EPLYPT_FLOAT32:
+ if (IsWrongEndian)
+ retVal = os::Byteswap::byteswap(*(reinterpret_cast<f32*>(StartPointer)));
+ else
+ retVal = *(reinterpret_cast<f32*>(StartPointer));
+ StartPointer += 4;
+ break;
+ case EPLYPT_FLOAT64:
+ // todo: byteswap 64-bit
+ retVal = f32(*(reinterpret_cast<f64*>(StartPointer)));
+ StartPointer += 8;
+ break;
+ case EPLYPT_LIST:
+ case EPLYPT_UNKNOWN:
+ default:
+ retVal = 0.0f;
+ StartPointer++; // ouch!
+ }
+ }
+ else
+ retVal = 0.0f;
+ }
+ else
+ {
+ c8* word = getNextWord();
+ switch (t)
+ {
+ case EPLYPT_INT8:
+ case EPLYPT_INT16:
+ case EPLYPT_INT32:
+ retVal = f32(atoi(word));
+ break;
+ case EPLYPT_FLOAT32:
+ case EPLYPT_FLOAT64:
+ retVal = f32(atof(word));
+ break;
+ case EPLYPT_LIST:
+ case EPLYPT_UNKNOWN:
+ default:
+ retVal = 0.0f;
+ }
+ }
+ return retVal;
+}
+
+
+// read the next int from the file and move the start pointer along
+u32 CPLYMeshFileLoader::getInt(E_PLY_PROPERTY_TYPE t)
+{
+ u32 retVal = 0;
+
+ if (IsBinaryFile)
+ {
+ if (!EndOfFile && EndPointer - StartPointer < 8)
+ fillBuffer();
+
+ if (EndPointer - StartPointer)
+ {
+ switch (t)
+ {
+ case EPLYPT_INT8:
+ retVal = *StartPointer;
+ StartPointer++;
+ break;
+ case EPLYPT_INT16:
+ if (IsWrongEndian)
+ retVal = os::Byteswap::byteswap(*(reinterpret_cast<u16*>(StartPointer)));
+ else
+ retVal = *(reinterpret_cast<u16*>(StartPointer));
+ StartPointer += 2;
+ break;
+ case EPLYPT_INT32:
+ if (IsWrongEndian)
+ retVal = os::Byteswap::byteswap(*(reinterpret_cast<s32*>(StartPointer)));
+ else
+ retVal = *(reinterpret_cast<s32*>(StartPointer));
+ StartPointer += 4;
+ break;
+ case EPLYPT_FLOAT32:
+ if (IsWrongEndian)
+ retVal = (u32)os::Byteswap::byteswap(*(reinterpret_cast<f32*>(StartPointer)));
+ else
+ retVal = (u32)(*(reinterpret_cast<f32*>(StartPointer)));
+ StartPointer += 4;
+ break;
+ case EPLYPT_FLOAT64:
+ // todo: byteswap 64-bit
+ retVal = (u32)(*(reinterpret_cast<f64*>(StartPointer)));
+ StartPointer += 8;
+ break;
+ case EPLYPT_LIST:
+ case EPLYPT_UNKNOWN:
+ default:
+ retVal = 0;
+ StartPointer++; // ouch!
+ }
+ }
+ else
+ retVal = 0;
+ }
+ else
+ {
+ c8* word = getNextWord();
+ switch (t)
+ {
+ case EPLYPT_INT8:
+ case EPLYPT_INT16:
+ case EPLYPT_INT32:
+ retVal = atoi(word);
+ break;
+ case EPLYPT_FLOAT32:
+ case EPLYPT_FLOAT64:
+ retVal = u32(atof(word));
+ break;
+ case EPLYPT_LIST:
+ case EPLYPT_UNKNOWN:
+ default:
+ retVal = 0;
+ }
+ }
+ return retVal;
+}
+
+
+
+} // end namespace scene
+} // end namespace irr
+
+#endif // _IRR_COMPILE_WITH_PLY_LOADER_
+
|