Esempio n. 1
0
        // Gets a single timestamp component
        static int GetTimestampVar(FbxNode timestamp, string element)
        {
            var elementNode = timestamp[element];

            if (elementNode != null && elementNode.Properties.Count > 0)
            {
                var prop = elementNode.Properties[0];
                if (prop is int || prop is long)
                {
                    return((int)prop);
                }
            }
            throw new FbxException(timePath, -1, "Timestamp has no " + element);
        }
Esempio n. 2
0
        static void Update <T>(FbxNode node, T[] arr)
        {
            if (arr == null)
            {
                Debug.LogWarning("Array being assigned is null");
                return;
            }

            if (node.Value != null && node.Value.GetType() != arr.GetType())
            {
                Debug.LogWarning("Array being assigned does not match the previous array's type in " + node.Name + "! Required: " + node.Value.GetType() + ", Got: " + arr.GetType());
                return;
            }

            node.Value = arr;
        }
Esempio n. 3
0
        // Gets a single timestamp component
        static int GetTimestampVar(FbxNode timestamp, string element)
        {
            var elementNode = timestamp[element];

            if (elementNode != null && elementNode.Properties.Count > 0)
            {
                var prop = elementNode.Properties[0];
                if (prop is int || prop is long)
                {
                    return((int)prop);
                }
                if (prop is byte)
                {
                    return((int)(byte)prop);
                }
                throw new FbxException(timePath, -1, $"element:{element}, prop={prop} has unrecognised value type : {prop.GetType()}");
            }
            throw new FbxException(timePath, -1, "Timestamp has no " + element);
        }
Esempio n. 4
0
        /// <summary>
        /// Reads a single node.
        /// </summary>
        /// <remarks>
        /// This won't read the file header or footer, and as such will fail if the stream is a full FBX file
        /// </remarks>
        /// <returns>The node</returns>
        /// <exception cref="FbxException">The FBX data was malformed
        /// for the reader's error level</exception>
        public FbxNode ReadNode()
        {
            long endOffset;
            int  endOffset32;
            long numProperties;
            int  numProperties32;
            long propertyListLen;
            int  propertyListLen32;

            // Version 7500 reads qwords instead dwords for properties and property list length
            if (versionNumber == 7500)
            {
                endOffset       = binStream.ReadInt64();
                numProperties   = binStream.ReadInt64();
                propertyListLen = binStream.ReadInt64();
            }
            else
            {
                endOffset32       = binStream.ReadInt32();
                endOffset         = Convert.ToInt64(endOffset32);
                numProperties32   = binStream.ReadInt32();
                numProperties     = Convert.ToInt64(numProperties32);
                propertyListLen32 = binStream.ReadInt32();
                propertyListLen   = Convert.ToInt64(propertyListLen32);
            }

            var nameLen = binStream.ReadByte();
            var name    = nameLen == 0 ? "" : Encoding.ASCII.GetString(binStream.ReadBytes(nameLen));

            if (endOffset == 0)
            {
                // The end offset should only be 0 in a null node
                if (errorLevel >= ErrorLevel.Checked && (numProperties != 0 || propertyListLen != 0 || !string.IsNullOrEmpty(name)))
                {
                    throw new FbxException(binStream.BaseStream.Position,
                                           "Invalid node; expected NULL record");
                }
                return(null);
            }

            var node = new FbxNode {
                Name = name
            };

            var propertyEnd = binStream.BaseStream.Position + propertyListLen;

            // Read properties
            for (int i = 0; i < numProperties; i++)
            {
                node.Properties.Add(ReadProperty());
            }

            if (errorLevel >= ErrorLevel.Checked && binStream.BaseStream.Position != propertyEnd)
            {
                throw new FbxException(binStream.BaseStream.Position,
                                       "Too many bytes in property list, end point is " + propertyEnd);
            }

            // Read nested nodes
            var listLen = endOffset - binStream.BaseStream.Position;

            if (errorLevel >= ErrorLevel.Checked && listLen < 0)
            {
                throw new FbxException(binStream.BaseStream.Position,
                                       "Node has invalid end point");
            }
            if (listLen > 0)
            {
                FbxNode nested;
                do
                {
                    nested = ReadNode();
                    node.Nodes.Add(nested);
                } while (nested != null);
                if (errorLevel >= ErrorLevel.Checked && binStream.BaseStream.Position != endOffset)
                {
                    throw new FbxException(binStream.BaseStream.Position,
                                           "Too many bytes in node, end point is " + endOffset);
                }
            }
            return(node);
        }
Esempio n. 5
0
		/// <summary>
		/// Reads a single node.
		/// </summary>
		/// <remarks>
		/// This won't read the file header or footer, and as such will fail if the stream is a full FBX file
		/// </remarks>
		/// <returns>The node</returns>
		/// <exception cref="FbxException">The FBX data was malformed
		/// for the reader's error level</exception>
		public FbxNode ReadNode()
		{
			var endOffset = stream.ReadInt32();
			var numProperties = stream.ReadInt32();
			var propertyListLen = stream.ReadInt32();
			var nameLen = stream.ReadByte();
			var name = nameLen == 0 ? "" : Encoding.ASCII.GetString(stream.ReadBytes(nameLen));

			if (endOffset == 0)
			{
				// The end offset should only be 0 in a null node
				if(errorLevel >= ErrorLevel.Checked && (numProperties != 0 || propertyListLen != 0 || !string.IsNullOrEmpty(name)))
					throw new FbxException(stream.BaseStream.Position,
						"Invalid node; expected NULL record");
				return null;
			}

			var node = new FbxNode {Name = name};

			var propertyEnd = stream.BaseStream.Position + propertyListLen;
			// Read properties
			for (int i = 0; i < numProperties; i++)
				node.Properties.Add(ReadProperty());

			if(errorLevel >= ErrorLevel.Checked && stream.BaseStream.Position != propertyEnd)
				throw new FbxException(stream.BaseStream.Position,
					"Too many bytes in property list, end point is " + propertyEnd);

			// Read nested nodes
			var listLen = endOffset - stream.BaseStream.Position;
			if(errorLevel >= ErrorLevel.Checked && listLen < 0)
				throw new FbxException(stream.BaseStream.Position,
					"Node has invalid end point");
			if (listLen > 0)
			{
				FbxNode nested;
				do
				{
					nested = ReadNode();
					node.Nodes.Add(nested);
				} while (nested != null);
				if (errorLevel >= ErrorLevel.Checked && stream.BaseStream.Position != endOffset)
					throw new FbxException(stream.BaseStream.Position,
						"Too many bytes in node, end point is " + endOffset);
			}
			return node;
		}
Esempio n. 6
0
        /// <summary>
        /// Reads the next node from the stream
        /// </summary>
        /// <returns>The read node, or <c>null</c></returns>
        public FbxNode ReadNode()
        {
            var first = ReadToken();
            var id    = first as Identifier;

            if (id == null)
            {
                if (first is EndOfStream)
                {
                    return(null);
                }
                throw new FbxException(line, column,
                                       "Unexpected '" + first + "', expected an identifier");
            }
            var node = new FbxNode {
                Name = id.String
            };

            // Read properties
            object token;
            bool   expectComma = false;

            while (!'{'.Equals(token = ReadToken()) && !(token is Identifier) && !'}'.Equals(token))
            {
                if (expectComma)
                {
                    if (!','.Equals(token))
                    {
                        throw new FbxException(line, column,
                                               "Unexpected '" + token + "', expected a ','");
                    }
                    expectComma = false;
                    continue;
                }
                if (token is char)
                {
                    var c = (char)token;
                    switch (c)
                    {
                    case '*':
                        token = ReadArray();
                        break;

                    case '}':
                    case ':':
                    case ',':
                        throw new FbxException(line, column,
                                               "Unexpected '" + c + "' in property list");
                    }
                }
                node.Properties.Add(token);
                expectComma = true; // The final comma before the open brace isn't required
            }
            // TODO: Merge property list into an array as necessary
            // Now we're either at an open brace, close brace or a new node
            if (token is Identifier || '}'.Equals(token))
            {
                prevToken = token;
                return(node);
            }
            // The while loop can't end unless we're at an open brace, so we can continue right on
            object endBrace;

            while (!'}'.Equals(endBrace = ReadToken()))
            {
                prevToken = endBrace; // If it's not an end brace, the next node will need it
                node.Nodes.Add(ReadNode());
            }
            if (node.Nodes.Count < 1) // If there's an open brace, we want that to be preserved
            {
                node.Nodes.Add(null);
            }
            return(node);
        }
Esempio n. 7
0
        // Writes a single document to the buffer
        void WriteNode(FbxDocument document, FbxNode node)
        {
            if (node == null)
            {
                var data = document.Version >= FbxVersion.v7_5 ? nullData7500 : nullData;
                stream.BaseStream.Write(data, 0, data.Length);
            }
            else
            {
                nodePath.Push(node.Name ?? "");
                var name = string.IsNullOrEmpty(node.Name) ? null : Encoding.ASCII.GetBytes(node.Name);
                if (name != null && name.Length > byte.MaxValue)
                {
                    throw new FbxException(stream.BaseStream.Position, "Node name is too long");
                }

                // Header
                var  endOffsetPos = stream.BaseStream.Position;
                long propertyLengthPos;
                if (document.Version >= FbxVersion.v7_5)
                {
                    stream.Write((long)0);                     // End offset placeholder
                    stream.Write((long)node.Properties.Count);
                    propertyLengthPos = stream.BaseStream.Position;
                    stream.Write((long)0);                     // Property length placeholder
                }
                else
                {
                    stream.Write(0);                     // End offset placeholder
                    stream.Write(node.Properties.Count);
                    propertyLengthPos = stream.BaseStream.Position;
                    stream.Write(0);                     // Property length placeholder
                }

                stream.Write((byte)(name?.Length ?? 0));
                if (name != null)
                {
                    stream.Write(name);
                }

                // Write properties and length
                var propertyBegin = stream.BaseStream.Position;
                for (int i = 0; i < node.Properties.Count; i++)
                {
                    WriteProperty(node.Properties[i], i);
                }
                var propertyEnd = stream.BaseStream.Position;
                stream.BaseStream.Position = propertyLengthPos;

                if (document.Version >= FbxVersion.v7_5)
                {
                    stream.Write((long)(propertyEnd - propertyBegin));
                }
                else
                {
                    stream.Write((int)(propertyEnd - propertyBegin));
                }

                stream.BaseStream.Position = propertyEnd;

                // Write child nodes
                if (node.Nodes.Count > 0)
                {
                    foreach (var n in node.Nodes)
                    {
                        if (n == null)
                        {
                            continue;
                        }

                        WriteNode(document, n);
                    }
                    WriteNode(document, null);
                }

                // Write end offset
                var dataEnd = stream.BaseStream.Position;
                stream.BaseStream.Position = endOffsetPos;
                if (document.Version >= FbxVersion.v7_5)
                {
                    stream.Write((long)dataEnd);
                }
                else
                {
                    stream.Write((int)dataEnd);
                }

                stream.BaseStream.Position = dataEnd;

                nodePath.Pop();
            }
        }
Esempio n. 8
0
		/// <summary>
		/// Reads the next node from the stream
		/// </summary>
		/// <returns>The read node, or <c>null</c></returns>
		public FbxNode ReadNode()
		{
			var first = ReadToken();
			var id = first as Identifier;
			if (id == null)
			{
				if (first is EndOfStream)
					return null;
				throw new FbxException(line, column,
					"Unexpected '" + first + "', expected an identifier");
			}
			var node = new FbxNode {Name = id.String};

			// Read properties
			object token;
			bool expectComma = false;
			while (!'{'.Equals(token = ReadToken()) && !(token is Identifier) && !'}'.Equals(token))
			{
				if (expectComma)
				{
					if (!','.Equals(token)) 
						throw new FbxException(line, column,
							"Unexpected '" + token + "', expected a ','");
					expectComma = false;
					continue;
				}
				if (token is char)
				{
					var c = (char) token;
					switch (c)
					{
						case '*':
							token = ReadArray();
							break;
						case '}':
						case ':':
						case ',':
							throw new FbxException(line, column,
								"Unexpected '" + c + "' in property list");
					}
				}
				node.Properties.Add(token);
				expectComma = true; // The final comma before the open brace isn't required
			}
			// TODO: Merge property list into an array as necessary
			// Now we're either at an open brace, close brace or a new node
			if (token is Identifier || '}'.Equals(token))
			{
				prevToken = token;
				return node;
			}
			// The while loop can't end unless we're at an open brace, so we can continue right on
			object endBrace;
			while(!'}'.Equals(endBrace = ReadToken()))
			{
				prevToken = endBrace; // If it's not an end brace, the next node will need it
				node.Nodes.Add(ReadNode());
			}
			if(node.Nodes.Count < 1) // If there's an open brace, we want that to be preserved
				node.Nodes.Add(null);
			return node;
		}
Esempio n. 9
0
        /// <summary>
        /// Reads a single node.
        /// </summary>
        /// <remarks>
        /// This won't read the file header or footer, and as such will fail if the stream is a full FBX file
        /// </remarks>
        /// <returns>The node</returns>
        /// <exception cref="FbxException">The FBX data was malformed
        /// for the reader's error level</exception>
        public FbxNode ReadNode()
        {
            var endOffset       = stream.ReadInt32();
            var numProperties   = stream.ReadInt32();
            var propertyListLen = stream.ReadInt32();
            var nameLen         = stream.ReadByte();
            var name            = nameLen == 0 ? "" : Encoding.ASCII.GetString(stream.ReadBytes(nameLen));

            if (endOffset == 0)
            {
                // The end offset should only be 0 in a null node
                if (errorLevel >= ErrorLevel.Checked && (numProperties != 0 || propertyListLen != 0 || !string.IsNullOrEmpty(name)))
                {
                    throw new FbxException(stream.BaseStream.Position,
                                           "Invalid node; expected NULL record");
                }
                return(null);
            }

            var node = new FbxNode {
                Name = name
            };

            var propertyEnd = stream.BaseStream.Position + propertyListLen;

            // Read properties
            for (int i = 0; i < numProperties; i++)
            {
                node.Properties.Add(ReadProperty());
            }

            if (errorLevel >= ErrorLevel.Checked && stream.BaseStream.Position != propertyEnd)
            {
                throw new FbxException(stream.BaseStream.Position,
                                       "Too many bytes in property list, end point is " + propertyEnd);
            }

            // Read nested nodes
            var listLen = endOffset - stream.BaseStream.Position;

            if (errorLevel >= ErrorLevel.Checked && listLen < 0)
            {
                throw new FbxException(stream.BaseStream.Position,
                                       "Node has invalid end point");
            }
            if (listLen > 0)
            {
                FbxNode nested;
                do
                {
                    nested = ReadNode();
                    node.Nodes.Add(nested);
                } while (nested != null);
                if (errorLevel >= ErrorLevel.Checked && stream.BaseStream.Position != endOffset)
                {
                    throw new FbxException(stream.BaseStream.Position,
                                           "Too many bytes in node, end point is " + endOffset);
                }
            }
            return(node);
        }
Esempio n. 10
0
		// Writes a single document to the buffer
		void WriteNode(FbxNode node)
		{
			if (node == null)
			{
				stream.BaseStream.Write(nullData, 0, nullData.Length);
			} else
			{
				nodePath.Push(node.Name ?? "");
				var name = string.IsNullOrEmpty(node.Name) ? null : Encoding.ASCII.GetBytes(node.Name);
				if(name != null && name.Length > byte.MaxValue)
					throw new FbxException(stream.BaseStream.Position,
						"Node name is too long");

				// Header
				var endOffsetPos = stream.BaseStream.Position;
				stream.Write(0); // End offset placeholder
				stream.Write(node.Properties.Count);
				var propertyLengthPos = stream.BaseStream.Position;
				stream.Write(0); // Property length placeholder
				stream.Write((byte)(name?.Length ?? 0));
				if(name != null)
					stream.Write(name);

				// Write properties and length
				var propertyBegin = stream.BaseStream.Position;
				for(int i = 0; i < node.Properties.Count; i++)
				{
					WriteProperty(node.Properties[i], i);
				}
				var propertyEnd = stream.BaseStream.Position;
				stream.BaseStream.Position = propertyLengthPos;
				stream.Write((int)(propertyEnd - propertyBegin));
				stream.BaseStream.Position = propertyEnd;

				// Write child nodes
				if (node.Nodes.Count > 0)
				{
					foreach (var n in node.Nodes)
					{
						if(n == null)
							continue;
						WriteNode(n);
					}
					WriteNode(null);
				}

				// Write end offset
				var dataEnd = stream.BaseStream.Position;
				stream.BaseStream.Position = endOffsetPos;
				stream.Write((int)dataEnd);
				stream.BaseStream.Position = dataEnd;

				nodePath.Pop();
			}
		}
Esempio n. 11
0
        // Adds the given node text to the string
        void BuildString(FbxNode node, StringBuilder sb, bool writeArrayLength, int indentLevel = 0)
        {
            nodePath.Push(node.Name ?? "");
            int lineStart = sb.Length;

            // Write identifier
            for (int i = 0; i < indentLevel; i++)
            {
                sb.Append('\t');
            }

            sb.Append(node.Name).Append(':');

            // Write properties
            var first = true;

            for (int j = 0; j < node.Properties.Count; j++)
            {
                var p = node.Properties[j];
                if (p == null)
                {
                    continue;
                }

                if (!first)
                {
                    sb.Append(',');
                }

                sb.Append(' ');

                if (p is string)
                {
                    sb.Append('"').Append(p).Append('"');
                }
                else if (p is Array)
                {
                    var array       = (Array)p;
                    var elementType = p.GetType().GetElementType();

                    // ReSharper disable once PossibleNullReferenceException
                    // We know it's an array, so we don't need to check for null

                    if (array.Rank != 1 || !elementType.IsPrimitive)
                    {
                        throw new FbxException(nodePath, j, "Invalid array type " + p.GetType());
                    }

                    if (writeArrayLength)
                    {
                        sb.Append('*').Append(array.Length).Append(" {\n");
                        lineStart = sb.Length;
                        for (int i = -1; i < indentLevel; i++)
                        {
                            sb.Append('\t');
                        }
                        sb.Append("a: ");
                    }
                    bool pFirst = true;
                    foreach (var v in (Array)p)
                    {
                        if (!pFirst)
                        {
                            sb.Append(',');
                        }

                        var vstr = v.ToString();
                        if ((sb.Length - lineStart) + vstr.Length >= MaxLineLength)
                        {
                            sb.Append('\n');
                            lineStart = sb.Length;
                        }
                        sb.Append(vstr);
                        pFirst = false;
                    }
                    if (writeArrayLength)
                    {
                        sb.Append('\n');
                        for (int i = 0; i < indentLevel; i++)
                        {
                            sb.Append('\t');
                        }
                        sb.Append('}');
                    }
                }
                else if (p is char)
                {
                    sb.Append((char)p);
                }
                else if (p.GetType().IsPrimitive&& p is IFormattable)
                {
                    sb.Append(p);
                }
                else
                {
                    throw new FbxException(nodePath, j, "Invalid property type " + p.GetType());
                }

                first = false;
            }

            // Write child nodes
            if (node.Nodes.Count > 0)
            {
                sb.Append(" {\n");
                foreach (var n in node.Nodes)
                {
                    if (n == null)
                    {
                        continue;
                    }

                    BuildString(n, sb, writeArrayLength, indentLevel + 1);
                }

                for (int i = 0; i < indentLevel; i++)
                {
                    sb.Append('\t');
                }
                sb.Append('}');
            }

            sb.Append('\n');
            nodePath.Pop();
        }
Esempio n. 12
0
		// Gets a single timestamp component
		static int GetTimestampVar(FbxNode timestamp, string element)
		{
			var elementNode = timestamp[element];
			if (elementNode != null && elementNode.Properties.Count > 0)
			{
				var prop = elementNode.Properties[0];
				if (prop is int || prop is long)
					return (int)prop;
			}
			throw new FbxException(timePath, -1, "Timestamp has no " + element);
		}
Esempio n. 13
0
		// Adds the given node text to the string
		void BuildString(FbxNode node, StringBuilder sb, bool writeArrayLength, int indentLevel = 0)
		{
			nodePath.Push(node.Name ?? "");
			int lineStart = sb.Length;
			// Write identifier
			for (int i = 0; i < indentLevel; i++)
				sb.Append('\t');
			sb.Append(node.Name).Append(':');

			// Write properties
			var first = true;
			for(int j = 0; j < node.Properties.Count; j++)
			{
				var p = node.Properties[j];
				if(p == null)
					continue;
				if (!first)
					sb.Append(',');
				sb.Append(' ');
				if (p is string)
				{
					sb.Append('"').Append(p).Append('"');
				} else if (p is Array)
				{
					var array = (Array) p;
					var elementType = p.GetType().GetElementType();
					// ReSharper disable once PossibleNullReferenceException
					// We know it's an array, so we don't need to check for null
					if (array.Rank != 1 || !elementType.IsPrimitive)
						throw new FbxException(nodePath, j,
							"Invalid array type " + p.GetType());
					if (writeArrayLength)
					{
						sb.Append('*').Append(array.Length).Append(" {\n");
						lineStart = sb.Length;
						for (int i = -1; i < indentLevel; i++)
							sb.Append('\t');
						sb.Append("a: ");
					}
					bool pFirst = true;
					foreach (var v in (Array) p)
					{
						if (!pFirst)
							sb.Append(',');
						var vstr = v.ToString();
						if ((sb.Length - lineStart) + vstr.Length >= MaxLineLength)
						{
							sb.Append('\n');
							lineStart = sb.Length;
						}
						sb.Append(vstr);
						pFirst = false;
					}
					if (writeArrayLength)
					{
						sb.Append('\n');
						for (int i = 0; i < indentLevel; i++)
							sb.Append('\t');
						sb.Append('}');
					}
				} else if (p is char)
					sb.Append((char) p);
				else if(p.GetType().IsPrimitive && p is IFormattable)
					sb.Append(p);
				else
					throw new FbxException(nodePath, j,
						"Invalid property type " + p.GetType());
				first = false;
			}

			// Write child nodes
			if (node.Nodes.Count > 0)
			{
				sb.Append(" {\n");
				foreach (var n in node.Nodes)
				{
					if (n == null)
						continue;
					BuildString(n, sb, writeArrayLength, indentLevel + 1);
				}
				for (int i = 0; i < indentLevel; i++)
					sb.Append('\t');
				sb.Append('}');
			}
			sb.Append('\n');

			nodePath.Pop();
		}
Esempio n. 14
0
 public NodeLink(FbxNodeList parent, FbxNode node)
 {
     this.parent = parent;
     this.node   = node;
 }
Esempio n. 15
0
        /// <summary>Parse Node Property</summary>
        /// <param name="reader">Binary Reader</param>
        /// <param name="node">current node</param>
        private void ParseProperty(BinaryReader reader, FbxNode node)
        {
            #region local func GetArrayProperty
            byte[] GetArrayProperty(BinaryReader r, int typeSize)
            {
                var len            = (int)r.ReadUInt32();
                var encoded        = r.ReadUInt32() != 0;
                var compressedSize = (int)r.ReadUInt32();

                if (encoded)
                {
                    var       deflateMetaData     = r.ReadInt16();
                    const int deflateMetaDataSize = 2;
                    var       byteArray           = r.ReadBytes(compressedSize - deflateMetaDataSize);
                    using (var ms = new MemoryStream(byteArray))
                        using (var ds = new DeflateStream(ms, CompressionMode.Decompress))
                        {
                            try
                            {
                                var decompressed = new byte[len * typeSize];
                                if (ds.Read(decompressed, 0, decompressed.Length) != decompressed.Length)
                                {
                                    throw new FormatException();
                                }
                                return(decompressed);
                            }
                            catch (InvalidDataException ex)
                            {
                                throw new FormatException("Parse fail", ex);
                            }
                        }
                }
                else
                {
                    var byteArray = r.ReadBytes(compressedSize);
                    return(byteArray);
                }
            }

            #endregion

            var propertyType = reader.ReadByte();
            switch (propertyType)
            {
            case INT16_PROPERTY:
            {
                var value = reader.ReadInt16();
                node.Properties.Add(new FbxShortProperty()
                    {
                        Value = value
                    });
                break;
            }

            case BOOL_PROPERTY:
            {
                var tmp = reader.ReadByte();
                // two types format exists. (Oh my gosh !! Fuuuuuuuu*k !!)
                // blender             -> true/false = 0x01/0x00
                // Autodesk production -> true/false = 'Y'/'T' = 0x59/0x54
                var value = (tmp == 0x00 || tmp == 0x54) ? false : true;
                node.Properties.Add(new FbxBoolProperty()
                    {
                        Value = value
                    });
                break;
            }

            case INT32_PROPERTY:
            {
                var value = reader.ReadInt32();
                node.Properties.Add(new FbxIntProperty()
                    {
                        Value = value
                    });
                break;
            }

            case FLOAT_PROPERTY:
            {
                var value = reader.ReadSingle();
                node.Properties.Add(new FbxFloatProperty()
                    {
                        Value = value
                    });
                break;
            }

            case DOUBLE_PROPERTY:
            {
                var value = reader.ReadDouble();
                node.Properties.Add(new FbxDoubleProperty()
                    {
                        Value = value
                    });
                break;
            }

            case INT64_PROPERTY:
            {
                var value = reader.ReadInt64();
                node.Properties.Add(new FbxLongProperty()
                    {
                        Value = value
                    });
                break;
            }

            case STRING_PROPERTY:
            {
                var len   = (int)reader.ReadUInt32();
                var value = GetAsciiString(reader.ReadBytes(len));
                node.Properties.Add(new FbxStringProperty()
                    {
                        Value = value
                    });
                break;
            }

            case BOOL_ARRAY_PROPERTY:
            {
                var byteArray = GetArrayProperty(reader, 1);
                var prop      = new FbxBoolArrayProperty()
                {
                    Value = GetBoolArray(byteArray)
                };
                node.Properties.Add(prop);
                break;
            }

            case INT32_ARRAY_PROPERTY:
            {
                var byteArray = GetArrayProperty(reader, 4);
                var prop      = new FbxIntArrayProperty()
                {
                    Value = GetIntArray(byteArray)
                };
                node.Properties.Add(prop);
                break;
            }

            case FLOAT_ARRAY_PROPERTY:
            {
                var byteArray = GetArrayProperty(reader, 4);
                var prop      = new FbxFloatArrayProperty()
                {
                    Value = GetFloatArray(byteArray)
                };
                node.Properties.Add(prop);
                break;
            }

            case DOUBLE_ARRAY_PROPERTY:
            {
                var byteArray = GetArrayProperty(reader, 8);
                var prop      = new FbxDoubleArrayProperty()
                {
                    Value = GetDoubleArray(byteArray)
                };
                node.Properties.Add(prop);
                break;
            }

            case INT64_ARRAY_PROPERTY:
            {
                var byteArray = GetArrayProperty(reader, 8);
                var prop      = new FbxLongArrayProperty()
                {
                    Value = GetLongArray(byteArray)
                };
                node.Properties.Add(prop);
                break;
            }

            case RAW_BINARY_PROPERTY:
            {
                var len   = (int)reader.ReadUInt32();
                var value = reader.ReadBytes(len);
                var prop  = new FbxBinaryProperty()
                {
                    Value = value
                };
                node.Properties.Add(prop);
                break;
            }

            default:
            {
                Debug.WriteLine($"[Skip Unknow Type Property] Position : {reader.BaseStream.Position}, type : {propertyType}");
                break;
            }
            }
        }