1 // Copyright (C) 2009-2012 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 #ifndef __C_PLY_MESH_FILE_LOADER_H_INCLUDED__
6 #define __C_PLY_MESH_FILE_LOADER_H_INCLUDED__
7 
8 #include "IMeshLoader.h"
9 #include "ISceneManager.h"
10 #include "CDynamicMeshBuffer.h"
11 
12 namespace irr
13 {
14 namespace scene
15 {
16 
17 enum E_PLY_PROPERTY_TYPE
18 {
19 	EPLYPT_INT8  = 0,
20 	EPLYPT_INT16,
21 	EPLYPT_INT32,
22 	EPLYPT_FLOAT32,
23 	EPLYPT_FLOAT64,
24 	EPLYPT_LIST,
25 	EPLYPT_UNKNOWN
26 };
27 
28 //! Meshloader capable of loading obj meshes.
29 class CPLYMeshFileLoader : public IMeshLoader
30 {
31 public:
32 
33 	//! Constructor
34 	CPLYMeshFileLoader(scene::ISceneManager* smgr);
35 
36 	//! Destructor
37 	virtual ~CPLYMeshFileLoader();
38 
39 	//! returns true if the file maybe is able to be loaded by this class
40 	//! based on the file extension (e.g. ".ply")
41 	virtual bool isALoadableFileExtension(const io::path& filename) const;
42 
43 	//! creates/loads an animated mesh from the file.
44 	virtual IAnimatedMesh* createMesh(io::IReadFile* file);
45 
46 private:
47 
48 	struct SPLYProperty
49 	{
50 		core::stringc Name;
51 		E_PLY_PROPERTY_TYPE Type;
52 		union
53 		{
54 			u8  Int8;
55 			u16 Int16;
56 			u32 Int32;
57 			f32 Float32;
58 			f64 Double;
59 			struct SPLYListProperty
60 			{
61 				E_PLY_PROPERTY_TYPE CountType;
62 				E_PLY_PROPERTY_TYPE ItemType;
63 			} List;
64 
65 		} Data;
66 
sizeSPLYProperty67 		inline u32 size() const
68 		{
69 			switch(Type)
70 			{
71 			case EPLYPT_INT8:
72 				return 1;
73 			case EPLYPT_INT16:
74 				return 2;
75 			case EPLYPT_INT32:
76 			case EPLYPT_FLOAT32:
77 				return 4;
78 			case EPLYPT_FLOAT64:
79 				return 8;
80 			case EPLYPT_LIST:
81 			case EPLYPT_UNKNOWN:
82 			default:
83 				return 0;
84 			}
85 		}
86 
isFloatSPLYProperty87 		inline bool isFloat() const
88 		{
89 			switch(Type)
90 			{
91 			case EPLYPT_FLOAT32:
92 			case EPLYPT_FLOAT64:
93 				return true;
94 			case EPLYPT_INT8:
95 			case EPLYPT_INT16:
96 			case EPLYPT_INT32:
97 			case EPLYPT_LIST:
98 			case EPLYPT_UNKNOWN:
99 			default:
100 				return false;
101 			}
102 		}
103 	};
104 
105 	struct SPLYElement
106 	{
107 		// name of the element. We only want "vertex" and "face" elements
108 		// but we have to parse the others anyway.
109 		core::stringc Name;
110 		// The number of elements in the file
111 		u32 Count;
112 		// Properties of this element
113 		core::array<SPLYProperty> Properties;
114 		// in binary files, true if this is a fixed size
115 		bool IsFixedWidth;
116 		// known size in bytes, 0 if unknown
117 		u32 KnownSize;
118 	};
119 
120 	bool allocateBuffer();
121 	c8* getNextLine();
122 	c8* getNextWord();
123 	void fillBuffer();
124 	E_PLY_PROPERTY_TYPE getPropertyType(const c8* typeString) const;
125 
126 	bool readVertex(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb);
127 	bool readFace(const SPLYElement &Element, scene::CDynamicMeshBuffer* mb);
128 	void skipElement(const SPLYElement &Element);
129 	void skipProperty(const SPLYProperty &Property);
130 	f32 getFloat(E_PLY_PROPERTY_TYPE t);
131 	u32 getInt(E_PLY_PROPERTY_TYPE t);
132 	void moveForward(u32 bytes);
133 
134 	core::array<SPLYElement*> ElementList;
135 
136 	scene::ISceneManager* SceneManager;
137 	io::IReadFile *File;
138 	c8 *Buffer;
139 	bool IsBinaryFile, IsWrongEndian, EndOfFile;
140 	s32 LineLength, WordLength;
141 	c8 *StartPointer, *EndPointer, *LineEndPointer;
142 };
143 
144 } // end namespace scene
145 } // end namespace irr
146 
147 #endif
148 
149