Selaa lähdekoodia

Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-ablake

Conflicts:
	gameplay/src/Font.cpp
Adam Blake 14 vuotta sitten
vanhempi
sitoutus
1d0f285d01
100 muutettua tiedostoa jossa 2378 lisäystä ja 2749 poistoa
  1. 1 0
      .gitignore
  2. 11 13
      README.md
  3. 0 1789
      gameplay-api.doxyfile
  4. 155 0
      gameplay-codestyle.xml
  5. 3 1
      gameplay-encoder/gameplay-binary.txt
  6. 10 2
      gameplay-encoder/gameplay-encoder.vcxproj
  7. 10 6
      gameplay-encoder/gameplay-encoder.vcxproj.filters
  8. 50 23
      gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj
  9. 6 0
      gameplay-encoder/src/Animation.cpp
  10. 8 0
      gameplay-encoder/src/Animation.h
  11. 37 6
      gameplay-encoder/src/AnimationChannel.cpp
  12. 8 4
      gameplay-encoder/src/AnimationChannel.h
  13. 11 0
      gameplay-encoder/src/Animations.cpp
  14. 4 0
      gameplay-encoder/src/Animations.h
  15. 31 10
      gameplay-encoder/src/Base.h
  16. 137 0
      gameplay-encoder/src/BoundingVolume.cpp
  17. 57 0
      gameplay-encoder/src/BoundingVolume.h
  18. 1 1
      gameplay-encoder/src/Camera.cpp
  19. 1 0
      gameplay-encoder/src/Camera.h
  20. 2 1
      gameplay-encoder/src/CameraInstance.cpp
  21. 3 0
      gameplay-encoder/src/CameraInstance.h
  22. 2 2
      gameplay-encoder/src/DAEChannelTarget.cpp
  23. 0 12
      gameplay-encoder/src/DAEChannelTarget.h
  24. 7 4
      gameplay-encoder/src/DAEOptimizer.cpp
  25. 5 11
      gameplay-encoder/src/DAEOptimizer.h
  26. 16 19
      gameplay-encoder/src/DAESceneEncoder.cpp
  27. 4 20
      gameplay-encoder/src/DAESceneEncoder.h
  28. 8 3
      gameplay-encoder/src/DAEUtil.cpp
  29. 6 21
      gameplay-encoder/src/DAEUtil.h
  30. 4 1
      gameplay-encoder/src/Effect.cpp
  31. 1 2
      gameplay-encoder/src/Effect.h
  32. 6 1
      gameplay-encoder/src/EncoderArguments.cpp
  33. 4 2
      gameplay-encoder/src/EncoderArguments.h
  34. 2 2
      gameplay-encoder/src/FileIO.cpp
  35. 1 3
      gameplay-encoder/src/FileIO.h
  36. 2 1
      gameplay-encoder/src/Font.cpp
  37. 1 2
      gameplay-encoder/src/Font.h
  38. 2 1
      gameplay-encoder/src/GPBDecoder.cpp
  39. 1 8
      gameplay-encoder/src/GPBDecoder.h
  40. 15 2
      gameplay-encoder/src/GPBFile.cpp
  41. 14 12
      gameplay-encoder/src/GPBFile.h
  42. 5 3
      gameplay-encoder/src/Glyph.cpp
  43. 1 0
      gameplay-encoder/src/Glyph.h
  44. 2 1
      gameplay-encoder/src/Light.cpp
  45. 1 3
      gameplay-encoder/src/Light.h
  46. 2 2
      gameplay-encoder/src/LightInstance.cpp
  47. 3 1
      gameplay-encoder/src/LightInstance.h
  48. 2 1
      gameplay-encoder/src/Material.cpp
  49. 1 2
      gameplay-encoder/src/Material.h
  50. 2 1
      gameplay-encoder/src/MaterialParameter.cpp
  51. 1 2
      gameplay-encoder/src/MaterialParameter.h
  52. 57 3
      gameplay-encoder/src/Matrix.cpp
  53. 23 2
      gameplay-encoder/src/Matrix.h
  54. 35 16
      gameplay-encoder/src/Mesh.cpp
  55. 13 8
      gameplay-encoder/src/Mesh.h
  56. 2 1
      gameplay-encoder/src/MeshPart.cpp
  57. 1 5
      gameplay-encoder/src/MeshPart.h
  58. 342 16
      gameplay-encoder/src/MeshSkin.cpp
  59. 15 10
      gameplay-encoder/src/MeshSkin.h
  60. 20 1
      gameplay-encoder/src/Model.cpp
  61. 2 3
      gameplay-encoder/src/Model.h
  62. 23 6
      gameplay-encoder/src/Node.cpp
  63. 14 5
      gameplay-encoder/src/Node.h
  64. 2 1
      gameplay-encoder/src/Object.cpp
  65. 2 2
      gameplay-encoder/src/Object.h
  66. 1 5
      gameplay-encoder/src/Quaternion.cpp
  67. 2 5
      gameplay-encoder/src/Quaternion.h
  68. 2 1
      gameplay-encoder/src/Reference.cpp
  69. 1 0
      gameplay-encoder/src/Reference.h
  70. 2 1
      gameplay-encoder/src/ReferenceTable.cpp
  71. 1 3
      gameplay-encoder/src/ReferenceTable.h
  72. 3 3
      gameplay-encoder/src/Scene.cpp
  73. 1 0
      gameplay-encoder/src/Scene.h
  74. 2 3
      gameplay-encoder/src/StringUtil.cpp
  75. 1 2
      gameplay-encoder/src/StringUtil.h
  76. 8 3
      gameplay-encoder/src/TTFFontEncoder.cpp
  77. 5 7
      gameplay-encoder/src/TTFFontEncoder.h
  78. 2 0
      gameplay-encoder/src/Transform.cpp
  79. 3 9
      gameplay-encoder/src/Vector2.cpp
  80. 1 5
      gameplay-encoder/src/Vector2.h
  81. 3 7
      gameplay-encoder/src/Vector3.cpp
  82. 0 7
      gameplay-encoder/src/Vector3.h
  83. 3 7
      gameplay-encoder/src/Vector4.cpp
  84. 1 5
      gameplay-encoder/src/Vector4.h
  85. 2 1
      gameplay-encoder/src/Vertex.cpp
  86. 1 0
      gameplay-encoder/src/Vertex.h
  87. 2 1
      gameplay-encoder/src/VertexElement.cpp
  88. 1 0
      gameplay-encoder/src/VertexElement.h
  89. 1 3
      gameplay-encoder/src/main.cpp
  90. BIN
      gameplay-tutorials/sample01-longboard.pdf
  91. BIN
      gameplay-tutorials/sample02-spaceship.pdf
  92. 0 13
      gameplay.sln
  93. 14 7
      gameplay/.cproject
  94. 12 7
      gameplay/gameplay.vcxproj
  95. 15 6
      gameplay/gameplay.vcxproj.filters
  96. 610 465
      gameplay/gameplay.xcodeproj/project.pbxproj
  97. 83 46
      gameplay/src/Animation.cpp
  98. 11 7
      gameplay/src/Animation.h
  99. 324 26
      gameplay/src/AnimationClip.cpp
  100. 42 14
      gameplay/src/AnimationClip.h

+ 1 - 0
.gitignore

@@ -25,6 +25,7 @@
 /gameplay/Device-Release
 /gameplay-encoder/Debug
 /gameplay-encoder/Release
+/gameplay-internal
 /gameplay-samples/sample00-mesh/Debug
 /gameplay-samples/sample00-mesh/DebugMem
 /gameplay-samples/sample00-mesh/Release

+ 11 - 13
README.md

@@ -1,19 +1,18 @@
-## GamePlay v1.0.1
+## GamePlay v1.1.0
 GamePlay is a open-source, cross-platform 3D native gaming framework making it easy to learn and write mobile and desktop games. 
 
 ## Supported Platforms
-- Microsoft Windows 7 (using Microsoft Visual Studio 2010)
- * Requires OpenAL 1.1 (http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx)
-- BlackBerry PlayBook 1.0/2.0 (using BlackBerry Native SDK 1.0)
+- BlackBerry PlayBook 1.0/2.0 (using BlackBerry Native SDK 1.0/2.0)
+- Apple MacOS X (using Apple XCode 4.0)
+- Microsoft Windows 7 (using Microsoft Visual Studio 2010 Pro/Express)
+	* Requires OpenAL 1.1 (http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx)
 
-## Roadmap
-- Apple Mac OS X support (using XCode 4.0)
-- Physics support with Bullet Physics
-- Encoded audio support with Ogg Vorbis
-- FrameBuffer's (RenderTarget + DepthStencilTarget)
-- Shadow and Light map generation.
-- Spatial Partitioning with Octree (Visibility Testing and Light Determination)
-- UI Forms
+## Roadmap for 'next' branch
+- UI Forms with Themed Overlays.
+- Improvements to Lighting.
+- Developer Guide.
+- More Samples and Tutorials.
+- Apple iOS 5 Support.
 
 ## Bug Reporting and Feature Requests
 If you find a bug in a Sample, or have an enhancement request, simply file an 
@@ -22,7 +21,6 @@ to the Committers to the project to let them know that you have filed
 an [Issue](https://github.com/blackberry/GamePlay/issues).
 
 ## Disclaimer
-
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 

+ 0 - 1789
gameplay-api.doxyfile

@@ -1,1789 +0,0 @@
-# Doxyfile 1.7.5.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file 
-# that follow. The default is UTF-8 which is also the encoding used for all 
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
-# iconv built into libc) for the transcoding. See 
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or sequence of words) that should 
-# identify the project. Note that if you do not use Doxywizard you need 
-# to put quotes around the project name if it contains spaces.
-
-PROJECT_NAME           = GamePlay
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 1.1.0
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description 
-# for a project that appears at the top of each page and should give viewer 
-# a quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF          = 
-
-# With the PROJECT_LOGO tag one can specify an logo or icon that is 
-# included in the documentation. The maximum height of the logo should not 
-# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
-# Doxygen will copy the logo to the output directory.
-
-PROJECT_LOGO           = 
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = ./gameplay-api
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       = "The $name class" \
-                         "The $name widget" \
-                         "The $name file" \
-                         is \
-                         provides \
-                         specifies \
-                         contains \
-                         represents \
-                         a \
-                         an \
-                         the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH        = 
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful if your file system 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like regular Qt-style comments 
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF      = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
-# interpret the first line (until the first dot) of a Qt-style 
-# comment as the brief description. If set to NO, the comments 
-# will behave just like regular Qt-style comments (thus requiring 
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF           = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 8
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Java. For instance, namespaces will be presented as packages, qualified 
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
-# sources. Doxygen will then generate output that is tailored for 
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it 
-# parses. With this tag you can assign which parser to use for a given extension. 
-# Doxygen has a built-in mapping, but you can override or extend it using this 
-# tag. The format is ext=language, where ext is a file extension, and language 
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 
-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
-
-EXTENSION_MAPPING      = 
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
-# to include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also makes the inheritance and collaboration 
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to 
-# enable parsing support.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
-# Doxygen will parse them like normal C++ but will assume all classes use public 
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter 
-# and setter methods for a property. Setting this option to YES (the default) 
-# will make doxygen replace the get and set methods by a property in the 
-# documentation. This will only work if the methods are indeed getting or 
-# setting a simple type. If this is not the case, or you want to show the 
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
-# unions are shown inside the group in which they are included (e.g. using 
-# @ingroup) instead of on a separate page (for HTML and Man pages) or 
-# section (for LaTeX and RTF).
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
-# unions with only public data fields will be shown inline in the documentation 
-# of the scope in which they are defined (i.e. file, namespace, or group 
-# documentation), provided this scope is documented. If set to NO (the default), 
-# structs, classes, and unions are shown on a separate page (for HTML and Man 
-# pages) or section (for LaTeX and RTF).
-
-INLINE_SIMPLE_STRUCTS  = NO
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
-# is documented as struct, union, or enum with the name of the typedef. So 
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
-# with name TypeT. When disabled the typedef will appear as a member of a file, 
-# namespace, or class. And the struct will be named TypeS. This can typically 
-# be useful for C code in case the coding convention dictates that all compound 
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
-# determine which symbols to keep in memory and which to flush to disk. 
-# When the cache is full, less often used symbols will be written to disk. 
-# For small to medium size projects (<1000 input files) the default value is 
-# probably good enough. For larger projects a too small cache size can cause 
-# doxygen to be busy swapping symbols to and from disk most of the time 
-# causing a significant performance penalty. 
-# If the system has enough physical memory increasing the cache will improve the 
-# performance by keeping more symbols in memory. Note that the value works on 
-# a logarithmic scale so increasing the size by one will roughly double the 
-# memory usage. The cache size is given by this formula: 
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be 
-# extracted and appear in the documentation as a namespace called 
-# 'anonymous_namespace{file}', where file will be replaced with the base 
-# name of the file that contains the anonymous namespace. By default 
-# anonymous namespaces are hidden.
-
-EXTRACT_ANON_NSPACES   = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
-# will list include files with double quotes in the documentation 
-# rather than with sharp brackets.
-
-FORCE_LOCAL_INCLUDES   = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
-# will sort the (brief and detailed) documentation of class members so that 
-# constructors and destructors are listed first. If set to NO (the default) 
-# the constructors will appear in the respective orders defined by 
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
-# hierarchy of group names into alphabetical order. If set to NO (the default) 
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
-# do proper type resolution of all parameters of a function it will reject a 
-# match between the prototype and the implementation of a member function even 
-# if there is only one candidate or it is obvious which candidate to choose 
-# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
-# will still accept a match between prototype and implementation in such cases.
-
-STRICT_PROTO_MATCHING  = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or macro consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and macros in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
-# This will remove the Files entry from the Quick Index and from the 
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
-# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES        = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from 
-# the version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER    = 
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
-# by doxygen. The layout file controls the global structure of the generated 
-# output files in an output format independent way. The create the layout file 
-# that represents doxygen's defaults, run doxygen with the -l option. 
-# You can optionally specify a file name after the option, if omitted 
-# DoxygenLayout.xml will be used as the name of the layout file.
-
-LAYOUT_FILE            = 
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files 
-# containing the references data. This must be a list of .bib files. The 
-# .bib extension is automatically appended if omitted. Using this command 
-# requires the bibtex tool to be installed. See also 
-# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
-# of the bibliography can be controlled using LATEX_BIB_STYLE.
-
-CITE_BIB_FILES         = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
-# documentation.
-
-WARN_NO_PARAMDOC       = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = ./gameplay/src
-
-# This tag can be used to specify the character encoding of the source files 
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
-# also the default input encoding. Doxygen uses libiconv (or the iconv built 
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
-# the list of possible encodings.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
-# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
-# *.f90 *.f *.for *.vhd *.vhdl
-
-FILE_PATTERNS          = *.c \
-                         *.cc \
-                         *.cxx \
-                         *.cpp \
-                         *.c++ \
-                         *.d \
-                         *.java \
-                         *.ii \
-                         *.ixx \
-                         *.ipp \
-                         *.i++ \
-                         *.inl \
-                         *.h \
-                         *.hh \
-                         *.hxx \
-                         *.hpp \
-                         *.h++ \
-                         *.idl \
-                         *.odl \
-                         *.cs \
-                         *.php \
-                         *.php3 \
-                         *.inc \
-                         *.m \
-                         *.mm \
-                         *.dox \
-                         *.py \
-                         *.f90 \
-                         *.f \
-                         *.for \
-                         *.vhd \
-                         *.vhdl
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag. 
-# Note that relative paths are relative to directory from which doxygen is run.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix file system feature) are excluded 
-# from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = 
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
-# (namespaces, classes, functions, etc.) that should be excluded from the 
-# output. The symbol name can be a fully qualified name, a word, or if the 
-# wildcard * is used, a substring. Examples: ANamespace, AClass, 
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS        = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = *
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER           = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty or if 
-# non of the patterns match the file name, INPUT_FILTER is applied.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
-# and it is also possible to disable source filtering for a specific pattern 
-# using *.ext= (so without naming a filter). This option only has effect when 
-# FILTER_SOURCE_FILES is enabled.
-
-FILTER_SOURCE_PATTERNS = 
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
-# link to the source code.  Otherwise they will link to the documentation.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
-# will need version 4.8.6 or higher.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header. Note that when using a custom header you are responsible  
-# for the proper inclusion of any scripts and style sheets that doxygen 
-# needs, which is dependent on the configuration options used. 
-# It is adviced to generate a default header using "doxygen -w html 
-# header.html footer.html stylesheet.css YourConfigFile" and then modify 
-# that header. Note that the header is subject to change so you typically 
-# have to redo this when upgrading to a newer version of doxygen or when 
-# changing the value of configuration settings such as GENERATE_TREEVIEW!
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        = 
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
-# other source files which should be copied to the HTML output directory. Note 
-# that these files will be copied to the base HTML output directory. Use the 
-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
-# the files will be copied as-is; there are no commands or markers available.
-
-HTML_EXTRA_FILES       = 
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
-# Doxygen will adjust the colors in the stylesheet and background images 
-# according to this color. Hue is specified as an angle on a colorwheel, 
-# see http://en.wikipedia.org/wiki/Hue for more information. 
-# For instance the value 0 represents red, 60 is yellow, 120 is green, 
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
-# The allowed range is 0 to 359.
-
-HTML_COLORSTYLE_HUE    = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
-# the colors in the HTML output. For a value of 0 the output will use 
-# grayscales only. A value of 255 will produce the most vivid colors.
-
-HTML_COLORSTYLE_SAT    = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
-# the luminance component of the colors in the HTML output. Values below 
-# 100 gradually make the output lighter, whereas values above 100 make 
-# the output darker. The value divided by 100 is the actual gamma applied, 
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
-# and 100 does not change the gamma.
-
-HTML_COLORSTYLE_GAMMA  = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
-# page will contain the date and time when the page was generated. Setting 
-# this to NO can help when comparing the output of multiple runs.
-
-HTML_TIMESTAMP         = YES
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
-# documentation will contain sections that can be hidden and shown after the 
-# page has loaded. For this to work a browser that supports 
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files 
-# will be generated that can be used as input for Apple's Xcode 3 
-# integrated development environment, introduced with OSX 10.5 (Leopard). 
-# To create a documentation set, doxygen will generate a Makefile in the 
-# HTML output directory. Running make will produce the docset in that 
-# directory and running "make install" will install the docset in 
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
-# it at startup. 
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
-# for more information.
-
-GENERATE_DOCSET        = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
-# feed. A documentation feed provides an umbrella under which multiple 
-# documentation sets from a single provider (such as a company or product suite) 
-# can be grouped.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
-# should uniquely identify the documentation set bundle. This should be a 
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 
-# the documentation publisher. This should be a reverse domain-name style 
-# string, e.g. com.mycompany.MyDocSet.documentation.
-
-DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
-
-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
-
-DOCSET_PUBLISHER_NAME  = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
-# content.
-
-CHM_INDEX_ENCODING     = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
-# that can be used as input for Qt's qhelpgenerator to generate a 
-# Qt Compressed Help (.qch) of the generated HTML documentation.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
-# be used to specify the file name of the resulting .qch file. 
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE               = 
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating 
-# Qt Help Project output. For more information please see 
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
-# Qt Help Project output. For more information please see 
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
-# add. For more information please see 
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME   = 
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
-# custom filter to add. For more information please see 
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
-# Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS  = 
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
-# project's 
-# filter section matches. 
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
-# Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS  = 
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
-# be used to specify the location of Qt's qhelpgenerator. 
-# If non-empty doxygen will try to run qhelpgenerator on the generated 
-# .qhp file.
-
-QHG_LOCATION           = 
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
-# will be generated, which together with the HTML files, form an Eclipse help 
-# plugin. To install this plugin and make it available under the help contents 
-# menu in Eclipse, the contents of the directory containing the HTML and XML 
-# files needs to be copied into the plugins directory of eclipse. The name of 
-# the directory within the plugins directory should be the same as 
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
-# the help appears.
-
-GENERATE_ECLIPSEHELP   = NO
-
-# A unique identifier for the eclipse help plugin. When installing the plugin 
-# the directory name containing the HTML and XML files should also have 
-# this name.
-
-ECLIPSE_DOC_ID         = org.doxygen.Project
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
-# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
-# documentation. Note that a value of 0 will completely suppress the enum 
-# values from appearing in the overview section.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
-# structure should be generated to display hierarchical information. 
-# If the tag value is set to YES, a side panel will be generated 
-# containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
-# Windows users are probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = YES
-
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES       = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
-# links to external symbols imported via tag files in a separate window.
-
-EXT_LINKS_IN_WINDOW    = NO
-
-# Use this tag to change the font size of Latex formulas included 
-# as images in the HTML documentation. The default is 10. Note that 
-# when you change the font size after a successful doxygen run you need 
-# to manually remove any form_*.png images from the HTML output directory 
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE       = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
-# generated for formulas are transparent PNGs. Transparent PNGs are 
-# not supported properly for IE 6.0, but are supported on all modern browsers. 
-# Note that when changing this option you need to delete any form_*.png files 
-# in the HTML output before the changes have effect.
-
-FORMULA_TRANSPARENT    = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
-# (see http://www.mathjax.org) which uses client side Javascript for the 
-# rendering instead of using prerendered bitmaps. Use this if you do not 
-# have LaTeX installed or if you want to formulas look prettier in the HTML 
-# output. When enabled you also need to install MathJax separately and 
-# configure the path to it using the MATHJAX_RELPATH option.
-
-USE_MATHJAX            = NO
-
-# When MathJax is enabled you need to specify the location relative to the 
-# HTML output directory using the MATHJAX_RELPATH option. The destination 
-# directory should contain the MathJax.js script. For instance, if the mathjax 
-# directory is located at the same level as the HTML output directory, then 
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the 
-# mathjax.org site, so you can quickly see the result without installing 
-# MathJax, but it is strongly recommended to install a local copy of MathJax 
-# before deployment.
-
-MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
-# names that should be enabled during MathJax rendering.
-
-MATHJAX_EXTENSIONS     = 
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
-# for the HTML output. The underlying search engine uses javascript 
-# and DHTML and should work on any modern browser. Note that when using 
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
-# (GENERATE_DOCSET) there is already a search function so this one should 
-# typically be disabled. For large projects the javascript based search engine 
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-
-SEARCHENGINE           = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
-# implemented using a PHP enabled web server instead of at the web client 
-# using Javascript. Doxygen will generate the search PHP script and index 
-# file to put on the web server. The advantage of the server 
-# based approach is that it scales better to large projects and allows 
-# full text search. The disadvantages are that it is more difficult to setup 
-# and does not have live searching capabilities.
-
-SERVER_BASED_SEARCH    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name. 
-# Note that when enabling USE_PDFLATEX this option is only used for 
-# generating bitmaps for formulas in the HTML output, but not in the 
-# Makefile that is written to the output directory.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
-# the generated latex document. The footer should contain everything after 
-# the last chapter. If it is left blank doxygen will generate a 
-# standard footer. Notice: only use this tag if you know what you are doing!
-
-LATEX_FOOTER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
-# source code with syntax highlighting in the LaTeX output. 
-# Note that which sources are shown also depends on other settings 
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE      = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
-# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
-# http://en.wikipedia.org/wiki/BibTeX for more info.
-
-LATEX_BIB_STYLE        = plain
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# pointed to by INCLUDE_PATH will be searched when a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition that 
-# overrules the definition found in the source code.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all references to function-like macros 
-# that are alone on a line, have an all uppercase name, and do not end with a 
-# semicolon, because these will confuse the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links. 
-# Note that each tag file must have a unique name 
-# (where the name does NOT include the path) 
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option also works with HAVE_DOT disabled, but it is recommended to 
-# install and use dot, since it yields more powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# You can define message sequence charts within doxygen comments using the \msc 
-# command. Doxygen will then run the mscgen tool (see 
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
-# the mscgen tool resides. If left empty the tool is assumed to be found in the 
-# default search path.
-
-MSCGEN_PATH            = 
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
-# allowed to run in parallel. When set to 0 (the default) doxygen will 
-# base this on the number of processors available in the system. You can set it 
-# explicitly to a value larger than 0 to get control over the balance 
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS        = 0
-
-# By default doxygen will use the Helvetica font for all dot files that 
-# doxygen generates. When you want a differently looking font you can specify 
-# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
-# the font, which can be done by putting it in a standard location or by setting 
-# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
-# directory containing the font.
-
-DOT_FONTNAME           = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
-# The default size is 10pt.
-
-DOT_FONTSIZE           = 10
-
-# By default doxygen will tell dot to use the Helvetica font. 
-# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
-# set the path where dot can find it.
-
-DOT_FONTPATH           = 
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
-# doxygen will generate a call dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable call graphs 
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
-# doxygen will generate a caller dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable caller 
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include 
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are svg, png, jpg, or gif. 
-# If left blank png will be used. If you choose svg you need to set 
-# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
-# visible in IE 9+ (other browsers do not have this requirement).
-
-DOT_IMAGE_FORMAT       = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
-# enable generation of interactive SVG images that allow zooming and panning. 
-# Note that this requires a modern browser other than Internet Explorer. 
-# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
-# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
-# visible. Older versions of IE do not have SVG support.
-
-INTERACTIVE_SVG        = NO
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that 
-# contain msc files that are included in the documentation (see the 
-# \mscfile command).
-
-MSCFILE_DIRS           = 
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
-# nodes that will be shown in the graph. If the number of nodes in a graph 
-# becomes larger than this value, doxygen will truncate the graph, which is 
-# visualized by representing a node as a red box. Note that doxygen if the 
-# number of direct children of the root node in a graph is already larger than 
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that the size of a graph can be further restricted by 
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, because dot on Windows does not 
-# seem to support this out of the box. Warning: Depending on the platform used, 
-# enabling this option may lead to badly anti-aliased labels on the edges of 
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES

+ 155 - 0
gameplay-codestyle.xml

@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="1">
+<profile kind="CodeFormatterProfile" name="BSD/Allman Gaming" version="1">
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.lineSplit" value="1024"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_enumerator_list" value="49"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_declarator_list" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expression_list" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_compact_if" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="next_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+</profile>
+</profiles>

+ 3 - 1
gameplay-encoder/gameplay-binary.txt

@@ -16,7 +16,7 @@ Section      Name            Type
 ------------------------------------------------------------------------------------------------------
 Header
              Identifier      byte[9]     = { '«', 'G', 'P', 'B', '»', '\r', '\n', '\x1A', '\n' } 
-             Version         byte[2]     = { 1, 0 }
+             Version         byte[2]     = { 1, 1 }
              References      Reference[]
 Data
              Objects         Object[]
@@ -211,6 +211,8 @@ Reference
                 bindShape               float[16]
                 joints                  xref:Node[]
                 jointsBindPoses         float[] // 16 * joints.length
+                boundingBox             BoundingBox { float[3] min, float[3] max }
+                boundingSphere          BoundingSphere { float[3] center, float radius }
 ------------------------------------------------------------------------------------------------------
 128->Font
                 family                  string

+ 10 - 2
gameplay-encoder/gameplay-encoder.vcxproj

@@ -11,9 +11,11 @@
     </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\gameplay\src\Curve.cpp" />
     <ClCompile Include="src\Animation.cpp" />
     <ClCompile Include="src\AnimationChannel.cpp" />
     <ClCompile Include="src\Base.cpp" />
+    <ClCompile Include="src\BoundingVolume.cpp" />
     <ClCompile Include="src\Camera.cpp" />
     <ClCompile Include="src\CameraInstance.cpp" />
     <ClCompile Include="src\EncoderArguments.cpp" />
@@ -54,9 +56,11 @@
     <ClCompile Include="src\VertexElement.cpp" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="..\gameplay\src\Curve.h" />
     <ClInclude Include="src\Animation.h" />
     <ClInclude Include="src\AnimationChannel.h" />
     <ClInclude Include="src\Base.h" />
+    <ClInclude Include="src\BoundingVolume.h" />
     <ClInclude Include="src\Camera.h" />
     <ClInclude Include="src\CameraInstance.h" />
     <ClInclude Include="src\EncoderArguments.h" />
@@ -140,12 +144,15 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;NO_BOOST;NO_ZAE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>../external-deps/freetype2/include;../external-deps/collada-dom/include;../external-deps/collada-dom/include/1.4</AdditionalIncludeDirectories>
+      <DisableLanguageExtensions>
+      </DisableLanguageExtensions>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>;../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32</AdditionalLibraryDirectories>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
     </Link>
     <PostBuildEvent>
       <Command>copy /Y "$(ProjectDir)..\external-deps\collada-dom\lib\win32\*.dll" "$(TargetDir)"</Command>
@@ -168,7 +175,8 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>;../external-deps/freetype2/lib/win32;../external-deps/collada-dom/lib/win32</AdditionalLibraryDirectories>
+      <IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
     </Link>
     <PostBuildEvent>
       <Command>copy /Y "$(ProjectDir)..\external-deps\collada-dom\lib\win32\*.dll" "$(TargetDir)"</Command>

+ 10 - 6
gameplay-encoder/gameplay-encoder.vcxproj.filters

@@ -62,9 +62,6 @@
     </ClCompile>
     <ClCompile Include="src\GPBFile.cpp" />
     <ClCompile Include="src\DAEChannelTarget.cpp" />
-    <ClCompile Include="src\Base.cpp">
-      <Filter>Objects</Filter>
-    </ClCompile>
     <ClCompile Include="src\FileIO.cpp" />
     <ClCompile Include="src\StringUtil.cpp" />
     <ClCompile Include="src\Effect.cpp">
@@ -96,6 +93,11 @@
     <ClCompile Include="src\Animations.cpp">
       <Filter>Objects\Animation</Filter>
     </ClCompile>
+    <ClCompile Include="..\gameplay\src\Curve.cpp" />
+    <ClCompile Include="src\BoundingVolume.cpp">
+      <Filter>Math</Filter>
+    </ClCompile>
+    <ClCompile Include="src\Base.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\DAESceneEncoder.h" />
@@ -158,9 +160,6 @@
     </ClInclude>
     <ClInclude Include="src\GPBFile.h" />
     <ClInclude Include="src\DAEChannelTarget.h" />
-    <ClInclude Include="src\Base.h">
-      <Filter>Objects</Filter>
-    </ClInclude>
     <ClInclude Include="src\FileIO.h" />
     <ClInclude Include="src\StringUtil.h" />
     <ClInclude Include="src\Effect.h">
@@ -192,6 +191,11 @@
     <ClInclude Include="src\Animations.h">
       <Filter>Objects\Animation</Filter>
     </ClInclude>
+    <ClInclude Include="..\gameplay\src\Curve.h" />
+    <ClInclude Include="src\BoundingVolume.h">
+      <Filter>Math</Filter>
+    </ClInclude>
+    <ClInclude Include="src\Base.h" />
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Objects">

+ 50 - 23
gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj

@@ -8,6 +8,8 @@
 
 /* Begin PBXBuildFile section */
 		42475D7C14720ECE00610A6A /* libdom.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42475D7B14720ECE00610A6A /* libdom.a */; };
+		4283905914896E6C00E2B2F5 /* BoundingVolume.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4283905714896E6C00E2B2F5 /* BoundingVolume.cpp */; };
+		4283906314896F1600E2B2F5 /* Curve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4283906114896F1600E2B2F5 /* Curve.cpp */; };
 		42C8EE0A14724CD700E43619 /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDB714724CD700E43619 /* Animation.cpp */; };
 		42C8EE0B14724CD700E43619 /* AnimationChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDB914724CD700E43619 /* AnimationChannel.cpp */; };
 		42C8EE0C14724CD700E43619 /* Animations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C8EDBB14724CD700E43619 /* Animations.cpp */; };
@@ -72,7 +74,11 @@
 
 /* Begin PBXFileReference section */
 		42475CE6147208A000610A6A /* gameplay-encoder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gameplay-encoder"; sourceTree = BUILT_PRODUCTS_DIR; };
-		42475D7B14720ECE00610A6A /* libdom.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdom.a; path = "../external-deps/collada-dom/lib/macosx/libdom.a"; sourceTree = "<group>"; };
+		42475D7B14720ECE00610A6A /* libdom.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdom.a; path = "../external-deps/collada-dom/lib/macos/libdom.a"; sourceTree = "<group>"; };
+		4283905714896E6C00E2B2F5 /* BoundingVolume.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BoundingVolume.cpp; path = src/BoundingVolume.cpp; sourceTree = SOURCE_ROOT; };
+		4283905814896E6C00E2B2F5 /* BoundingVolume.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoundingVolume.h; path = src/BoundingVolume.h; sourceTree = SOURCE_ROOT; };
+		4283906114896F1600E2B2F5 /* Curve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Curve.cpp; path = ../gameplay/src/Curve.cpp; sourceTree = "<group>"; };
+		4283906214896F1600E2B2F5 /* Curve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Curve.h; path = ../gameplay/src/Curve.h; sourceTree = "<group>"; };
 		42C8EDB714724CD700E43619 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Animation.cpp; path = src/Animation.cpp; sourceTree = SOURCE_ROOT; };
 		42C8EDB814724CD700E43619 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = src/Animation.h; sourceTree = SOURCE_ROOT; };
 		42C8EDB914724CD700E43619 /* AnimationChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationChannel.cpp; path = src/AnimationChannel.cpp; sourceTree = SOURCE_ROOT; };
@@ -156,12 +162,12 @@
 		42C8EE0714724CD700E43619 /* Vertex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vertex.h; path = src/Vertex.h; sourceTree = SOURCE_ROOT; };
 		42C8EE0814724CD700E43619 /* VertexElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexElement.cpp; path = src/VertexElement.cpp; sourceTree = SOURCE_ROOT; };
 		42C8EE0914724CD700E43619 /* VertexElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexElement.h; path = src/VertexElement.h; sourceTree = SOURCE_ROOT; };
-		42C8EE341472B60100E43619 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = "../external-deps/freetype2/lib/macosx/libfreetype.a"; sourceTree = "<group>"; };
+		42C8EE341472B60100E43619 /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = "../external-deps/freetype2/lib/macos/libfreetype.a"; sourceTree = "<group>"; };
 		42C8EE361472D7E700E43619 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
 		42C8EE381472DAA300E43619 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		42C8EE3A1472DAAE00E43619 /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = usr/lib/libbz2.dylib; sourceTree = SDKROOT; };
-		42D277571472EFA700D867A4 /* libpcre.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcre.a; path = "../external-deps/pcre/lib/macosx/libpcre.a"; sourceTree = "<group>"; };
-		42D277581472EFA700D867A4 /* libpcrecpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcrecpp.a; path = "../external-deps/pcre/lib/macosx/libpcrecpp.a"; sourceTree = "<group>"; };
+		42D277571472EFA700D867A4 /* libpcre.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcre.a; path = "../external-deps/pcre/lib/macos/libpcre.a"; sourceTree = "<group>"; };
+		42D277581472EFA700D867A4 /* libpcrecpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcrecpp.a; path = "../external-deps/pcre/lib/macos/libpcrecpp.a"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -185,14 +191,9 @@
 		42475CDB147208A000610A6A = {
 			isa = PBXGroup;
 			children = (
-				42D277571472EFA700D867A4 /* libpcre.a */,
-				42D277581472EFA700D867A4 /* libpcrecpp.a */,
-				42C8EE3A1472DAAE00E43619 /* libbz2.dylib */,
-				42C8EE381472DAA300E43619 /* libz.dylib */,
-				42C8EE361472D7E700E43619 /* libxml2.dylib */,
-				42C8EE341472B60100E43619 /* libfreetype.a */,
-				42475D7B14720ECE00610A6A /* libdom.a */,
-				42475CE9147208A000610A6A /* gameplay-encoder */,
+				4283906414896F3000E2B2F5 /* gameplay */,
+				42475CE9147208A000610A6A /* src */,
+				427D4F44147DC9080076760E /* Libraries */,
 				42475CE7147208A000610A6A /* Products */,
 			);
 			sourceTree = "<group>";
@@ -205,7 +206,7 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
-		42475CE9147208A000610A6A /* gameplay-encoder */ = {
+		42475CE9147208A000610A6A /* src */ = {
 			isa = PBXGroup;
 			children = (
 				42C8EDB714724CD700E43619 /* Animation.cpp */,
@@ -216,6 +217,8 @@
 				42C8EDBC14724CD700E43619 /* Animations.h */,
 				42C8EDBD14724CD700E43619 /* Base.cpp */,
 				42C8EDBE14724CD700E43619 /* Base.h */,
+				4283905714896E6C00E2B2F5 /* BoundingVolume.cpp */,
+				4283905814896E6C00E2B2F5 /* BoundingVolume.h */,
 				42C8EDBF14724CD700E43619 /* Camera.cpp */,
 				42C8EDC014724CD700E43619 /* Camera.h */,
 				42C8EDC114724CD700E43619 /* CameraInstance.cpp */,
@@ -292,9 +295,33 @@
 				42C8EE0814724CD700E43619 /* VertexElement.cpp */,
 				42C8EE0914724CD700E43619 /* VertexElement.h */,
 			);
+			name = src;
 			path = "gameplay-encoder";
 			sourceTree = "<group>";
 		};
+		427D4F44147DC9080076760E /* Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				42D277571472EFA700D867A4 /* libpcre.a */,
+				42D277581472EFA700D867A4 /* libpcrecpp.a */,
+				42C8EE3A1472DAAE00E43619 /* libbz2.dylib */,
+				42C8EE381472DAA300E43619 /* libz.dylib */,
+				42C8EE361472D7E700E43619 /* libxml2.dylib */,
+				42C8EE341472B60100E43619 /* libfreetype.a */,
+				42475D7B14720ECE00610A6A /* libdom.a */,
+			);
+			name = Libraries;
+			sourceTree = "<group>";
+		};
+		4283906414896F3000E2B2F5 /* gameplay */ = {
+			isa = PBXGroup;
+			children = (
+				4283906114896F1600E2B2F5 /* Curve.cpp */,
+				4283906214896F1600E2B2F5 /* Curve.h */,
+			);
+			name = gameplay;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -387,6 +414,8 @@
 				42C8EE3114724CD700E43619 /* Vector4.cpp in Sources */,
 				42C8EE3214724CD700E43619 /* Vertex.cpp in Sources */,
 				42C8EE3314724CD700E43619 /* VertexElement.cpp in Sources */,
+				4283905914896E6C00E2B2F5 /* BoundingVolume.cpp in Sources */,
+				4283906314896F1600E2B2F5 /* Curve.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -480,11 +509,10 @@
 				);
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"$(SRCROOT)/../external-deps/freetype2/lib/macosx\"",
-					"\"$(SRCROOT)/../external-deps/collada-dom/lib/macosx\"",
-					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/minizip/mac\"",
-					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/pcre/lib/mac\"",
-					"\"$(SRCROOT)/../external-deps/pcre/lib/macosx\"",
+					"\"$(SRCROOT)/../external-deps/freetype2/lib/macos\"",
+					"\"$(SRCROOT)/../external-deps/collada-dom/lib/macos\"",
+					"\"$(SRCROOT)/../external-deps/pcre/lib/macos\"",
+					"\"$(SRCROOT)/../../../Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug\"",
 				);
 				MACH_O_TYPE = mh_execute;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -508,11 +536,10 @@
 				);
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"$(SRCROOT)/../external-deps/freetype2/lib/macosx\"",
-					"\"$(SRCROOT)/../external-deps/collada-dom/lib/macosx\"",
-					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/minizip/mac\"",
-					"\"$(SRCROOT)/../../../collada-dom/dom/external-libs/pcre/lib/mac\"",
-					"\"$(SRCROOT)/../external-deps/pcre/lib/macosx\"",
+					"\"$(SRCROOT)/../external-deps/freetype2/lib/macos\"",
+					"\"$(SRCROOT)/../external-deps/collada-dom/lib/macos\"",
+					"\"$(SRCROOT)/../external-deps/pcre/lib/macos\"",
+					"\"$(SRCROOT)/../../../Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug\"",
 				);
 				MACH_O_TYPE = mh_execute;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 6 - 0
gameplay-encoder/src/Animation.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Animation.h"
 
 namespace gameplay
@@ -55,4 +56,9 @@ unsigned int Animation::getAnimationChannelCount() const
     return _channels.size();
 }
 
+AnimationChannel* Animation::getAnimationChannel(unsigned int index) const
+{
+    return _channels[index];
+}
+
 }

+ 8 - 0
gameplay-encoder/src/Animation.h

@@ -27,6 +27,7 @@ public:
     virtual void writeText(FILE* file);
 
     void add(AnimationChannel* animationChannel);
+
     /**
      * Returns the number of animation channels contained in this animation.
      * 
@@ -34,9 +35,16 @@ public:
      */
     unsigned int getAnimationChannelCount() const;
 
+    /**
+     * Returns the specified animation channel.
+     */
+    AnimationChannel* getAnimationChannel(unsigned int index) const;
+
 private:
+
     std::vector<AnimationChannel*> _channels;
 };
 
 }
+
 #endif

+ 37 - 6
gameplay-encoder/src/AnimationChannel.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "AnimationChannel.h"
 
 namespace gameplay
@@ -51,7 +52,42 @@ void AnimationChannel::writeText(FILE* file)
     fprintElementEnd(file);
 }
 
-void AnimationChannel::setTargetId(const std::string str)
+const std::string& AnimationChannel::getTargetId() const
+{
+    return _targetId;
+}
+
+unsigned int AnimationChannel::getTargetAttribute() const
+{
+    return _targetAttrib;
+}
+
+const std::vector<float>& AnimationChannel::getKeyValues() const
+{
+    return _keyValues;
+}
+
+const std::vector<float>& AnimationChannel::getKeyTimes() const
+{
+    return _keytimes;
+}
+
+const std::vector<float>& AnimationChannel::getTangentsIn() const
+{
+    return _tangentsIn;
+}
+
+const std::vector<float>& AnimationChannel::getTangentsOut() const
+{
+    return _tangentsOut;
+}
+
+const std::vector<unsigned int>& AnimationChannel::getInterpolationTypes() const
+{
+    return _interpolations;
+}
+
+void AnimationChannel::setTargetId(const std::string& str)
 {
     _targetId = str;
 }
@@ -86,11 +122,6 @@ void AnimationChannel::setInterpolations(const std::vector<unsigned int>& values
     _interpolations = values;
 }
 
-const std::vector<float>& AnimationChannel::getKeyValues() const
-{
-    return _keyValues;
-}
-
 unsigned int AnimationChannel::getInterpolationType(const char* str)
 {
     unsigned int value = 0;

+ 8 - 4
gameplay-encoder/src/AnimationChannel.h

@@ -35,7 +35,8 @@ public:
     virtual void writeBinary(FILE* file);
     virtual void writeText(FILE* file);
 
-    void setTargetId(const std::string str);
+    const std::string& getTargetId() const;
+    void setTargetId(const std::string& str);
     void setTargetAttribute(unsigned int attrib);
 
     void setKeyTimes(const std::vector<float>& values);
@@ -44,7 +45,12 @@ public:
     void setTangentsOut(const std::vector<float>& values);
     void setInterpolations(const std::vector<unsigned int>& values);
 
+    unsigned int getTargetAttribute() const;
     const std::vector<float>& getKeyValues() const;
+    const std::vector<float>& getKeyTimes() const;
+    const std::vector<float>& getTangentsIn() const;
+    const std::vector<float>& getTangentsOut() const;
+    const std::vector<unsigned int>& getInterpolationTypes() const;
 
     /**
      * Returns the interpolation type value for the given string or zero if not valid.
@@ -56,7 +62,6 @@ public:
      */
     static unsigned int getInterpolationType(const char* str);
 
-
 private:
 
     std::string _targetId;
@@ -68,7 +73,6 @@ private:
     std::vector<unsigned int> _interpolations;
 };
 
-
 }
-#endif
 
+#endif

+ 11 - 0
gameplay-encoder/src/Animations.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Animations.h"
 
 namespace gameplay
@@ -51,4 +52,14 @@ void Animations::add(Animation* animation)
     _animations.push_back(animation);
 }
 
+unsigned int Animations::getAnimationCount() const
+{
+    return _animations.size();
+}
+
+Animation* Animations::getAnimation(unsigned int index) const
+{
+    return _animations[index];
+}
+
 }

+ 4 - 0
gameplay-encoder/src/Animations.h

@@ -30,10 +30,14 @@ public:
     virtual void writeText(FILE* file);
 
     void add(Animation* animation);
+    unsigned int getAnimationCount() const;
+    Animation* getAnimation(unsigned int index) const;
 
 private:
+
     std::vector<Animation*> _animations;
 };
 
 }
+
 #endif

+ 31 - 10
gameplay-encoder/src/Base.h

@@ -1,23 +1,35 @@
 #ifndef BASE_H_
 #define BASE_H_
 
+// C++ includes
 #include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstdarg>
+#include <cassert>
+#include <cmath>
+#include <cfloat>
+#include <ctime>
 #include <iostream>
+#include <fstream>
 #include <string>
 #include <vector>
 #include <list>
 #include <map>
-#include <stdio.h>
-#include <stdlib.h>
-#include <iostream>
-#include <string>
+#include <algorithm>
 #include <sys/stat.h>
-#include <vector>
-#include <assert.h>
-#include <math.h>
-#include <float.h>
 
+// Collada includes
+#include <dae.h>
+#include <dae/daeSIDResolver.h>
+#include <dae/domAny.h>
+#include <dom/domCOLLADA.h>
+#include <dom/domConstants.h>
+#include <dom/domElements.h>
+#include <dom/domCamera.h>
+#include <dom/domProfile_COMMON.h>
 
+// Defines
 #ifndef M_1_PI        
 #define M_1_PI                      0.31830988618379067154
 #endif
@@ -59,10 +71,19 @@ enum VertexUsage
     TEXCOORD7 = 15
 };
 
-
 void fillArray(float values[], float value, size_t length);
 void setIdentityMatrix(float values[]);
 
-}
+#define ISZERO(x) (fabs(x) < 0.000001f)
+
+#ifdef NDEBUG
+#define DEBUGPRINT(x)
+#define DEBUGPRINT_VARG(x, ...)
+#else
+#define DEBUGPRINT(x)  printf(x)
+#define DEBUGPRINT_VARG(x, ...) printf(x, __VA_ARGS__)
 #endif
 
+}
+
+#endif

+ 137 - 0
gameplay-encoder/src/BoundingVolume.cpp

@@ -0,0 +1,137 @@
+#include "Base.h"
+#include "BoundingVolume.h"
+
+namespace gameplay
+{
+
+BoundingVolume::BoundingVolume()
+    : radius(0.0f)
+{
+}
+
+void updateMinMax(Vector3* point, Vector3* min, Vector3* max)
+{
+    // Leftmost point.
+    if (point->x < min->x)
+    {
+        min->x = point->x;
+    }
+
+    // Rightmost point.
+    if (point->x > max->x)
+    {
+        max->x = point->x;
+    }
+
+    // Lowest point.
+    if (point->y < min->y)
+    {
+        min->y = point->y;
+    }
+
+    // Highest point.
+    if (point->y > max->y)
+    {
+        max->y = point->y;
+    }
+
+    // Farthest point.
+    if (point->z < min->z)
+    {
+        min->z = point->z;
+    }
+
+    // Nearest point.
+    if (point->z > max->z)
+    {
+        max->z = point->z;
+    }
+}
+
+void BoundingVolume::transform(const Matrix& m)
+{
+    // Transform the bounding sphere
+    m.transformPoint(center, &center);
+    Vector3 translate;
+    m.decompose(&translate, NULL, NULL);
+    float r = radius * translate.x;
+    r = std::max(radius, radius * translate.y);
+    r = std::max(radius, radius * translate.z);
+    radius = r;
+
+    // Transform the bounding box
+    Vector3 corners[8];
+    corners[0].set(min.x, max.y, max.z);
+    // Left-bottom-front.
+    corners[1].set(min.x, min.y, max.z);
+    // Right-bottom-front.
+    corners[2].set(max.x, min.y, max.z);
+    // Right-top-front.
+    corners[3].set(max.x, max.y, max.z);
+    // Right-top-back.
+    corners[4].set(max.x, max.y, min.z);
+    // Right-bottom-back.
+    corners[5].set(max.x, min.y, min.z);
+    // Left-bottom-back.
+    corners[6].set(min.x, min.y, min.z);
+    // Left-top-back.
+    corners[7].set(min.x, max.y, min.z);
+
+    // Transform the corners, recalculating the min and max points along the way.
+    m.transformPoint(corners[0], &corners[0]);
+    Vector3 newMin = corners[0];
+    Vector3 newMax = corners[0];
+    for (int i = 1; i < 8; i++)
+    {
+        m.transformPoint(corners[i], &corners[i]);
+        updateMinMax(&corners[i], &newMin, &newMax);
+    }
+    min = newMin;
+    max = newMax;
+}
+
+void BoundingVolume::merge(const BoundingVolume& v)
+{
+    // Calculate the distance between the two centers.
+    float vx = center.x - v.center.x;
+    float vy = center.y - v.center.y;
+    float vz = center.z - v.center.z;
+    float d = sqrt(vx * vx + vy * vy + vz * vz);
+
+    // If one sphere is contained inside the other, set to the larger sphere.
+    if (d <= (v.radius - radius))
+    {
+        // Use targert volume
+        radius = v.radius;
+        center = v.center;
+    }
+    else if (d <= (radius - v.radius))
+    {
+        // No change
+    }
+    else
+    {
+        // Calculate the unit vector between the two centers.
+        float dI = 1.0f / d;
+        vx *= dI;
+        vy *= dI;
+        vz *= dI;
+
+        // Calculate the new radius.
+        float r = (radius + v.radius + d) * 0.5f;
+
+        // Calculate the new center.
+        float scaleFactor = (r - v.radius);
+        vx = vx * scaleFactor + v.center.x;
+        vy = vy * scaleFactor + v.center.y;
+        vz = vz * scaleFactor + v.center.z;
+
+        // Set the new center and radius.
+        center.x = vx;
+        center.y = vy;
+        center.z = vz;
+        radius = r;
+    }
+}
+
+}

+ 57 - 0
gameplay-encoder/src/BoundingVolume.h

@@ -0,0 +1,57 @@
+#ifndef BOUNDINGVOLUME_H_
+#define BOUNDINGVOLUME_H_
+
+#include "Vector3.h"
+#include "Matrix.h"
+
+namespace gameplay
+{
+
+/**
+ * Represents a 3D bounding volumes, which defines both a
+ * bounding sphere and an axis-aligned bounding box (AABB).
+ */
+class BoundingVolume
+{
+public:
+
+    /**
+     * Radius of the bounding sphere.
+     */
+    float radius;
+
+    /**
+     * Center point of the bounding sphere.
+     */
+    Vector3 center;
+
+    /**
+     * Minimum point of the AABB.
+     */
+    Vector3 min;
+
+    /**
+     * Maximum point of the AABB.
+     */
+    Vector3 max;
+
+    /**
+     * Constructor.
+     */
+    BoundingVolume();
+
+    /**
+     * Transforms this bounding volume by the specified matrix.
+     */
+    void transform(const Matrix& m);
+
+    /**
+     * Merges this bounding volume with the specified one and
+     * stores the result in this BoundingVolume.
+     */
+    void merge(const BoundingVolume& v);
+};
+
+}
+
+#endif

+ 1 - 1
gameplay-encoder/src/Camera.cpp

@@ -1,4 +1,4 @@
-#include <assert.h>
+#include "Base.h"
 #include "Camera.h"
 
 namespace gameplay

+ 1 - 0
gameplay-encoder/src/Camera.h

@@ -54,4 +54,5 @@ private:
 };
 
 }
+
 #endif

+ 2 - 1
gameplay-encoder/src/CameraInstance.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "CameraInstance.h"
 
 namespace gameplay
@@ -50,4 +51,4 @@ void CameraInstance::setCamera(Camera* camera)
     _ref = camera;
 }
 
-}
+}

+ 3 - 0
gameplay-encoder/src/CameraInstance.h

@@ -28,9 +28,12 @@ public:
 
     Camera* getCamera();
     void setCamera(Camera* camera);
+
 private:
+
     Camera* _ref;
 };
 
 }
+
 #endif

+ 2 - 2
gameplay-encoder/src/DAEChannelTarget.cpp

@@ -1,4 +1,4 @@
-
+#include "Base.h"
 #include "DAEChannelTarget.h"
 
 
@@ -98,4 +98,4 @@ void DAEChannelTarget::getPropertyName(size_t index, std::string* str)
     str->clear();
 }
 
-}
+}

+ 0 - 12
gameplay-encoder/src/DAEChannelTarget.h

@@ -1,18 +1,6 @@
 #ifndef DAECHANNELTARGET_H_
 #define DAECHANNELTARGET_H_
 
-#include <dae.h>
-#include <dae/daeSIDResolver.h>
-#include <dae/domAny.h>
-#include <dom/domCOLLADA.h>
-#include <dom/domConstants.h>
-#include <dom/domElements.h>
-#include <dom/domProfile_COMMON.h>
-
-#include <vector>
-
-#include "Base.h"
-
 namespace gameplay
 {
 

+ 7 - 4
gameplay-encoder/src/DAEOptimizer.cpp

@@ -1,9 +1,10 @@
+#include "Base.h"
 #include "DAEOptimizer.h"
-
-#include <algorithm>
-
 #include "StringUtil.h"
 
+namespace gameplay
+{
+
 DAEOptimizer::DAEOptimizer(domCOLLADA* dom)
 {
     _dom = dom;
@@ -122,4 +123,6 @@ void DAEOptimizer::deleteEmptyAnimations()
     {
         daeElement::removeFromParent(*i);
     }
-}
+}
+
+}

+ 5 - 11
gameplay-encoder/src/DAEOptimizer.h

@@ -1,19 +1,11 @@
 #ifndef DAEOPTIMIZER_H_
 #define DAEOPTIMIZER_H_
 
-#include <dae.h>
-#include <dae/daeSIDResolver.h>
-#include <dae/domAny.h>
-#include <dom/domCOLLADA.h>
-#include <dom/domConstants.h>
-#include <dom/domElements.h>
-#include <dom/domProfile_COMMON.h>
-
-#include <vector>
-
-#include "Base.h"
 #include "DAEUtil.h"
 
+namespace gameplay
+{
+
 /**
  * The DAEOptimizer optimizes a COLLADA dom.
  */
@@ -60,4 +52,6 @@ private:
     std::string _inputPath;
 };
 
+}
+
 #endif

+ 16 - 19
gameplay-encoder/src/DAESceneEncoder.cpp

@@ -1,15 +1,11 @@
-/*
- * DAESceneEncoder.h
- */
-
-#include <algorithm>
-
+#include "Base.h"
 #include "DAESceneEncoder.h"
 #include "DAEOptimizer.h"
 
 //#define ENCODER_PRINT_TIME 1
 
-using namespace gameplay;
+namespace gameplay
+{
 
 DAESceneEncoder::DAESceneEncoder()
     : _collada(NULL), _dom(NULL), file(NULL), _vertexBlendWeights(NULL), _vertexBlendIndices(NULL)
@@ -243,7 +239,7 @@ void DAESceneEncoder::createTrianglesFromPolylist(domMesh* domMesh, domPolylist*
 
 void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments& arguments)
 {
-    _begin = std::clock();
+    _begin = clock();
     const char* nodeId = arguments.getNodeId();
     bool text = arguments.textOutputEnabled();
 
@@ -663,14 +659,14 @@ bool DAESceneEncoder::loadTarget(const domChannelRef& channelRef, AnimationChann
 void DAESceneEncoder::begin()
 {
     #ifdef ENCODER_PRINT_TIME
-    _begin = std::clock();
+    _begin = clock();
     #endif
 }
 
 void DAESceneEncoder::end(const char* str)
 {
     #ifdef ENCODER_PRINT_TIME
-    clock_t time = std::clock() - _begin;
+    clock_t time = clock() - _begin;
     fprintf(stderr,"%5d %s\n", time, str);
     #endif
 }
@@ -1266,9 +1262,9 @@ void DAESceneEncoder::loadSkeleton(domInstance_controller::domSkeleton* skeleton
     }
 
     // Resolve and set joints array for skin
-    std::list<Node*> _joints;
-    const std::list<std::string>& jointNames = skin->getJointNames();
-    for (std::list<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); i++)
+    std::vector<Node*> _joints;
+    const std::vector<std::string>& jointNames = skin->getJointNames();
+    for (std::vector<std::string>::const_iterator i = jointNames.begin(); i != jointNames.end(); i++)
     {
         Object* obj = _gamePlayFile.getFromRefTable(*i);
         if (obj)
@@ -1302,7 +1298,6 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
     domSkin::domJointsRef _joints = skinElement->getJoints();
     domInputLocal_Array& jointInputs = _joints->getInput_array();
 
-
     // Process "JOINT" input semantic first (we need to do this to set the joint count)
     unsigned int jointCount = 0;
     for (unsigned int i = 0; i < jointInputs.getCount(); i++)
@@ -1316,12 +1311,12 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
         if (equals(inputSemantic, "JOINT"))
         {
             // Get the joint Ids's
-            std::list<std::string> list;
+            std::vector<std::string> list;
             getJointNames(source, list);
 
             // Go through the joint list and conver them from sid to id because the sid information is
             // lost when converting to the gameplay binary format.
-            for (std::list<std::string>::iterator i = list.begin(); i != list.end(); i++)
+            for (std::vector<std::string>::iterator i = list.begin(); i != list.end(); i++)
             {
                 daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
                 daeElement* element = resolver.getElement();
@@ -1340,7 +1335,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
             jointCount = list.size();
             _jointInverseBindPoseMatrices.reserve(jointCount);
             unsigned int j = 0;
-            for (std::list<std::string>::const_iterator i = list.begin(); i != list.end(); i++)
+            for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); i++)
             {
                 _jointLookupTable[*i] = j++;
             }
@@ -1673,7 +1668,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
         domTriangles* triangles = daeSafeCast<domTriangles>(trianglesArray.get(i));
 
         // Parse the material for this subset
-        //std::string materialName = triangles->getMaterial() == NULL ? _T("") : triangles->getMaterial();
+        //string materialName = triangles->getMaterial() == NULL ? _T("") : triangles->getMaterial();
         //if (materialName.size() > 0)
         ///    subset->material = ParseMaterial(bindMaterial, materialName);
 
@@ -1925,4 +1920,6 @@ DAESceneEncoder::DAEPolygonInput::DAEPolygonInput(void) :
 
 DAESceneEncoder::DAEPolygonInput::~DAEPolygonInput(void)
 {
-}
+}
+
+}

+ 4 - 20
gameplay-encoder/src/DAESceneEncoder.h

@@ -1,25 +1,6 @@
-/*
- * DAESceneEncoder.h
- */
-
 #ifndef DAESCENEEENCODER_H_
 #define DAESCENEEENCODER_H_
 
-#include <iostream>
-#include <list>
-#include <vector>
-#include <ctime>
-
-#include <dae.h>
-#include <dae/daeSIDResolver.h>
-#include <dae/domAny.h>
-#include <dom/domCOLLADA.h>
-#include <dom/domConstants.h>
-#include <dom/domElements.h>
-#include <dom/domProfile_COMMON.h>
-#include <dom/domCamera.h>
-
-#include "Base.h"
 #include "StringUtil.h"
 #include "Object.h"
 #include "Node.h"
@@ -42,7 +23,8 @@
 #include "DAEUtil.h"
 #include "EncoderArguments.h"
 
-using namespace gameplay;
+namespace gameplay
+{
 
 /**
  * Class for binary encoding a Collada (DAE) file.
@@ -223,4 +205,6 @@ private:
     clock_t _begin;
 };
 
+}
+
 #endif

+ 8 - 3
gameplay-encoder/src/DAEUtil.cpp

@@ -1,6 +1,9 @@
-
+#include "Base.h"
 #include "DAEUtil.h"
 
+namespace gameplay
+{
+
 /**
  * Returns the index of the skeleton in skeletonArray that points to the given node.
  * 
@@ -11,7 +14,7 @@
  */
 int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, const domNodeRef& node);
 
-void getJointNames(const domSourceRef source, std::list<std::string>& list)
+void getJointNames(const domSourceRef source, std::vector<std::string>& list)
 {
     // BLENDER used name_array
     const domName_arrayRef& nameArray = source->getName_array();
@@ -40,7 +43,7 @@ void getJointNames(const domSourceRef source, std::list<std::string>& list)
     }
 }
 
-void getJointNames(const domSkin* skin, std::list<std::string>& list)
+void getJointNames(const domSkin* skin, std::vector<std::string>& list)
 {
     const domSkin::domJointsRef& joints = skin->getJoints();
     const domInputLocal_Array& inputArray = joints->getInput_array();
@@ -301,3 +304,5 @@ int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, con
     }
     return -1;
 }
+
+}

+ 6 - 21
gameplay-encoder/src/DAEUtil.h

@@ -1,25 +1,8 @@
-/*
- * DAEUtil.h
- */
-
 #ifndef DAEUTIL_H_
 #define DAEUTIL_H_
 
-#include <iostream>
-#include <list>
-#include <vector>
-
-#include <dae.h>
-#include <dae/daeSIDResolver.h>
-#include <dae/domAny.h>
-#include <dom/domCOLLADA.h>
-#include <dom/domConstants.h>
-#include <dom/domElements.h>
-#include <dom/domProfile_COMMON.h>
-
-#include "Base.h"
-
-using namespace gameplay;
+namespace gameplay
+{
 
 /**
  * Gets the joint names for the given source and appends them to the given list.
@@ -27,7 +10,7 @@ using namespace gameplay;
  * @param source The source element to search in.
  * @param list The list to append the joint names to.
  */
-void getJointNames(const domSourceRef source, std::list<std::string>& list);
+void getJointNames(const domSourceRef source, std::vector<std::string>& list);
 
 /**
  * Gets the joint names for the given skin and appends them to the given list.
@@ -35,7 +18,7 @@ void getJointNames(const domSourceRef source, std::list<std::string>& list);
  * @param skin The skin element to search in.
  * @param list The list to append the joint names to.
  */
-void getJointNames(const domSkin* skin, std::list<std::string>& list);
+void getJointNames(const domSkin* skin, std::vector<std::string>& list);
 
 /**
  * Gets the input source from the given channel.
@@ -123,4 +106,6 @@ void moveChannelAndSouresToAnimation(domChannelRef& channel, domAnimationRef& an
  */
 bool isEmptyAnimation(domAnimationRef& animation);
 
+}
+
 #endif

+ 4 - 1
gameplay-encoder/src/Effect.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Effect.h"
 
 namespace gameplay
@@ -15,6 +16,7 @@ unsigned int Effect::getTypeId(void) const
 {
     return EFFECT_ID;
 }
+
 const char* Effect::getElementName(void) const
 {
     return "Effect";
@@ -26,6 +28,7 @@ void Effect::writeBinary(FILE* file)
     write(_vertexShader, file);
     write(_fragmentShader, file);
 }
+
 void Effect::writeText(FILE* file)
 {
     fprintElementStart(file);
@@ -34,4 +37,4 @@ void Effect::writeText(FILE* file)
     fprintElementEnd(file);
 }
 
-}
+}

+ 1 - 2
gameplay-encoder/src/Effect.h

@@ -33,7 +33,6 @@ private:
     std::string _fragmentShader;
 };
 
-
 }
-#endif
 
+#endif

+ 6 - 1
gameplay-encoder/src/EncoderArguments.cpp

@@ -1,5 +1,5 @@
+#include "Base.h"
 #include "EncoderArguments.h"
-
 #include "StringUtil.h"
 
 #ifdef WIN32
@@ -7,6 +7,9 @@
     #define realpath(A,B)    _fullpath(B,A,PATH_MAX)
 #endif
 
+namespace gameplay
+{
+
 EncoderArguments::EncoderArguments(size_t argc, const char** argv) :
     _fontSize(0),
     _parseError(false),
@@ -273,3 +276,5 @@ void EncoderArguments::replace_char(char* str, char oldChar, char newChar)
         }
     }
 }
+
+}

+ 4 - 2
gameplay-encoder/src/EncoderArguments.h

@@ -1,8 +1,8 @@
 #ifndef ENCODERARGUMENTS_H_
 #define ENCODERARGUMENTS_H_
 
-
-#include "Base.h"
+namespace gameplay
+{
 
 /**
  * EncoderArguments handles parsing the command line arguments for the GamePlay Encoder.
@@ -111,4 +111,6 @@ private:
     std::vector<std::string> _groupAnimationAnimationId;
 };
 
+}
+
 #endif

+ 2 - 2
gameplay-encoder/src/FileIO.cpp

@@ -1,9 +1,9 @@
+#include "Base.h"
 #include "FileIO.h"
 
 namespace gameplay
 {
 
-
 // Writing out a binary file //
 
 void write(unsigned char value, FILE* file)
@@ -144,4 +144,4 @@ void skipUint(FILE* file)
     fseek(file, sizeof(unsigned int), SEEK_CUR);
 }
 
-}
+}

+ 1 - 3
gameplay-encoder/src/FileIO.h

@@ -1,8 +1,6 @@
 #ifndef FILEIO_H_
 #define FILEIO_H_
 
-#include "Base.h"
-
 namespace gameplay
 {
 
@@ -114,5 +112,5 @@ void skipString(FILE* file);
 void skipUint(FILE* file);
 
 }
-#endif
 
+#endif

+ 2 - 1
gameplay-encoder/src/Font.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Font.h"
 
 namespace gameplay
@@ -50,4 +51,4 @@ void Font::writeText(FILE* file)
     fprintElementEnd(file);
 }
 
-}
+}

+ 1 - 2
gameplay-encoder/src/Font.h

@@ -44,7 +44,6 @@ public:
     };
 };
 
-
 }
-#endif
 
+#endif

+ 2 - 1
gameplay-encoder/src/GPBDecoder.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "GPBDecoder.h"
 
 namespace gameplay
@@ -113,4 +114,4 @@ std::string GPBDecoder::readString(FILE* fp)
     return result;
 }
 
-};
+}

+ 1 - 8
gameplay-encoder/src/GPBDecoder.h

@@ -1,14 +1,6 @@
-/*
- * GamePlayFile.h
- */
-
 #ifndef GPBDECODER_H_
 #define GPBDECODER_H_
 
-#include <iostream>
-#include <list>
-#include <assert.h>
-
 #include "FileIO.h"
 
 namespace gameplay
@@ -40,6 +32,7 @@ public:
     std::string readString(FILE* fp);
 
 private:
+
     FILE* _file;
     FILE* _outFile;
 };

+ 15 - 2
gameplay-encoder/src/GPBFile.cpp

@@ -1,17 +1,26 @@
+#include "Base.h"
 #include "GPBFile.h"
 
 namespace gameplay
 {
 
+static GPBFile* __instance = NULL;
+
 GPBFile::GPBFile(void)
     : _file(NULL), _animationsAdded(false)
 {
+    __instance = this;
 }
 
 GPBFile::~GPBFile(void)
 {
 }
 
+GPBFile* GPBFile::getInstance()
+{
+    return __instance;
+}
+
 void GPBFile::saveBinary(const std::string& filepath)
 {
     _file = fopen(filepath.c_str(), "w+b");
@@ -200,6 +209,11 @@ Node* GPBFile::getNode(const char* id)
     return NULL;
 }
 
+Animations* GPBFile::getAnimations()
+{
+    return &_animations;
+}
+
 void GPBFile::adjust()
 {
     // calculate the ambient color for each scene
@@ -227,5 +241,4 @@ void GPBFile::adjust()
     //   This can be merged into one animation. Same for scale animations.
 }
 
-
-}
+}

+ 14 - 12
gameplay-encoder/src/GPBFile.h

@@ -1,13 +1,6 @@
-/*
- * GPBFile.h
- */
-
 #ifndef GPBFILE_H_
 #define GPBFILE_H_
 
-#include <iostream>
-#include <list>
-
 #include "FileIO.h"
 #include "Object.h"
 #include "Scene.h"
@@ -23,11 +16,12 @@
 
 namespace gameplay
 {
-    /**
-     * Increment the version number when making a change that break binary compatibility.
-     * [0] is major, [1] is minor.
-     */
-    const unsigned char VERSION[2] = {1, 0};
+
+/**
+ * Increment the version number when making a change that break binary compatibility.
+ * [0] is major, [1] is minor.
+ */
+const unsigned char VERSION[2] = {1, 1};
 
 /**
  * The GamePlay Binary file class handles writing the GamePlay Binary file.
@@ -46,6 +40,11 @@ public:
      */
     ~GPBFile(void);
 
+    /**
+     * Returns the GPBFile instance.
+     */
+    static GPBFile* getInstance();
+
     /**
      * Saves the GPBFile as a binary file at filepath.
      *
@@ -88,6 +87,8 @@ public:
     Mesh* getMesh(const char* id);
     Node* getNode(const char* id);
 
+    Animations* getAnimations();
+
     /**
      * Adjusts the game play binary file before it is written.
      */
@@ -108,4 +109,5 @@ private:
 };
 
 }
+
 #endif

+ 5 - 3
gameplay-encoder/src/Glyph.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Glyph.h"
 
 namespace gameplay
@@ -10,10 +11,10 @@ Glyph::Glyph(void) :
     fillArray(uvCoords, 0.0f, 4);
 }
 
-
-Glyph::~Glyph(void)
+    Glyph::~Glyph(void)
 {
 }
+
 const char* Glyph::getElementName(void) const
 {
     return "Glyph";
@@ -28,6 +29,7 @@ void Glyph::writeBinary(FILE* file)
     write(uvCoords, 4, file);
 
 }
+
 void Glyph::writeText(FILE* file)
 {
     fprintElementStart(file);
@@ -37,4 +39,4 @@ void Glyph::writeText(FILE* file)
     fprintElementEnd(file);
 }
 
-}
+}

+ 1 - 0
gameplay-encoder/src/Glyph.h

@@ -30,4 +30,5 @@ public:
 };
 
 }
+
 #endif

+ 2 - 1
gameplay-encoder/src/Light.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Light.h"
 #include "DAESceneEncoder.h"
 
@@ -227,4 +228,4 @@ void Light::setFalloffExponent(float value)
     }
 }
 
-}
+}

+ 1 - 3
gameplay-encoder/src/Light.h

@@ -77,8 +77,6 @@ private:
     float _outerAngle;
 };
 
-
-
 }
-#endif
 
+#endif

+ 2 - 2
gameplay-encoder/src/LightInstance.cpp

@@ -1,5 +1,5 @@
+#include "Base.h"
 #include "LightInstance.h"
-#include "assert.h"
 
 namespace gameplay
 {
@@ -52,4 +52,4 @@ bool LightInstance::isAmbient() const
     return _ref != NULL && _ref->isAmbient();
 }
 
-}
+}

+ 3 - 1
gameplay-encoder/src/LightInstance.h

@@ -32,9 +32,11 @@ public:
     bool isAmbient() const;
 
 private:
+
     Light* _ref;
+
 };
 
 }
-#endif
 
+#endif

+ 2 - 1
gameplay-encoder/src/Material.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Material.h"
 
 namespace gameplay
@@ -35,4 +36,4 @@ void Material::writeText(FILE* file)
     fprintElementEnd(file);
 }
 
-}
+}

+ 1 - 2
gameplay-encoder/src/Material.h

@@ -32,7 +32,6 @@ private:
     Effect* _effect;
 };
 
-
 }
-#endif
 
+#endif

+ 2 - 1
gameplay-encoder/src/MaterialParameter.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "MaterialParameter.h"
 
 namespace gameplay
@@ -35,4 +36,4 @@ void MaterialParameter::writeText(FILE* file)
     fprintElementEnd(file);
 }
 
-}
+}

+ 1 - 2
gameplay-encoder/src/MaterialParameter.h

@@ -30,7 +30,6 @@ private:
     unsigned int _type;
 };
 
-
 }
-#endif
 
+#endif

+ 57 - 3
gameplay-encoder/src/Matrix.cpp

@@ -1,9 +1,9 @@
+#include "Base.h"
 #include "Matrix.h"
 
 namespace gameplay
 {
 
-
 Matrix::Matrix(void)
 {
     setIdentity(m);
@@ -41,6 +41,45 @@ void Matrix::setIdentity(float* matrix)
     memcpy(matrix, MATRIX4F_IDENTITY, MATRIX4F_SIZE);
 }
 
+void Matrix::createRotation(const Quaternion& q, float* dst)
+{
+    assert(dst);
+
+    float x2 = q.x + q.x;
+    float y2 = q.y + q.y;
+    float z2 = q.z + q.z;
+
+    float xx2 = q.x * x2;
+    float yy2 = q.y * y2;
+    float zz2 = q.z * z2;
+    float xy2 = q.x * y2;
+    float xz2 = q.x * z2;
+    float yz2 = q.y * z2;
+    float wx2 = q.w * x2;
+    float wy2 = q.w * y2;
+    float wz2 = q.w * z2;
+
+    dst[0] = 1.0f - yy2 - zz2;
+    dst[1] = xy2 + wz2;
+    dst[2] = xz2 - wy2;
+    dst[3] = 0.0f;
+
+    dst[4] = xy2 - wz2;
+    dst[5] = 1.0f - xx2 - zz2;
+    dst[6] = yz2 + wx2;
+    dst[7] = 0.0f;
+
+    dst[8] = xz2 + wy2;
+    dst[9] = yz2 - wx2;
+    dst[10] = 1.0f - xx2 - yy2;
+    dst[11] = 0.0f;
+
+    dst[12] = 0.0f;
+    dst[13] = 0.0f;
+    dst[14] = 0.0f;
+    dst[15] = 1.0f;
+}
+
 void Matrix::createRotation(float x, float y, float z, float angle, float* dst)
 {
     // Make sure the input axis is normalized
@@ -48,7 +87,7 @@ void Matrix::createRotation(float x, float y, float z, float angle, float* dst)
     if (n != 1.0f)
     {
         // Not normalized
-        n = sqrtf(n);
+        n = sqrt(n);
         if (n > 0.000001f) // prevent divide too close to zero
         {
             n = 1.0f / n;
@@ -167,6 +206,13 @@ void Matrix::scale(float x, float y, float z)
     multiply(m, s, m);
 }
 
+void Matrix::rotate(const Quaternion& q)
+{
+    float r[16];
+    createRotation(q, r);
+    multiply(m, r, m);
+}
+
 void Matrix::rotate(float x, float y, float z, float angle)
 {
     float r[16];
@@ -350,4 +396,12 @@ float Matrix::determinant() const
     return (a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0);
 }
 
-}
+void Matrix::transformPoint(const Vector3& p, Vector3* dst) const
+{
+    dst->set(
+        p.x * m[0] + p.y * m[4] + p.z * m[8] +  m[12],
+        p.x * m[1] + p.y * m[5] + p.z * m[9] +  m[13],
+        p.x * m[2] + p.y * m[6] + p.z * m[10] + m[14] );
+}
+
+}

+ 23 - 2
gameplay-encoder/src/Matrix.h

@@ -12,7 +12,6 @@
 #define TORADIANS(degrees) (degrees * (PI / 180.0f))
 #define TODEGREES(radians) (radians * (180.0f / PI))
 
-
 namespace gameplay
 {
 
@@ -31,6 +30,11 @@ class Matrix
 {
 public:
 
+    /**
+     * Matrix colums.
+     */
+    float m[16];
+
     /**
      * Constructor.
      */
@@ -81,6 +85,11 @@ public:
      */
     static void createScale(float x, float y, float z, float* dst);
 
+    /**
+     * Creates a rotation matrix from the given quaternion.
+     */
+    static void createRotation(const Quaternion& q, float* dst);
+
     /**
      * Creates a rotation matrix from the given axis and angle in degrees.
      */
@@ -121,6 +130,11 @@ public:
      */
     void scale(float x, float y, float z);
 
+    /**
+     * Rotates the matrix by the given Quaternion.
+     */
+    void rotate(const Quaternion& q);
+
     /**
      * Rotates the matrix by the axies specified and angle.
      */
@@ -141,8 +155,15 @@ public:
      */
     void rotateZ(float angle);
 
-    float m[16];
+    /**
+     * Transforms the specified point by this matrix.
+     *
+     * Note that the input vector is treated as a point and NOT a vector.
+     */
+    void transformPoint(const Vector3& p, Vector3* dst) const;
+
 };
 
 }
+
 #endif

+ 35 - 16
gameplay-encoder/src/Mesh.cpp

@@ -1,9 +1,11 @@
+#include "Base.h"
 #include "Mesh.h"
+#include "Model.h"
 
 namespace gameplay
 {
 
-Mesh::Mesh(void)
+Mesh::Mesh(void) : model(NULL)
 {
 }
 
@@ -25,8 +27,8 @@ void Mesh::writeBinary(FILE* file)
 {
     Object::writeBinary(file);
     // vertex formats
-    write(_vertexFormats.size(), file);
-    for (std::vector<VertexElement>::iterator i = _vertexFormats.begin(); i != _vertexFormats.end(); i++)
+    write(_vertexFormat.size(), file);
+    for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); i++)
     {
         i->writeBinary(file);
     }
@@ -73,7 +75,7 @@ void Mesh::writeText(FILE* file)
     // for each VertexFormat
     if (vertices.size() > 0 )
     {
-        for (std::vector<VertexElement>::iterator i = _vertexFormats.begin(); i != _vertexFormats.end(); i++)
+        for (std::vector<VertexElement>::iterator i = _vertexFormat.begin(); i != _vertexFormat.end(); i++)
         {
             i->writeText(file);
         }
@@ -123,7 +125,7 @@ void Mesh::addMeshPart(Vertex* vertex)
 
 void Mesh::addVetexAttribute(unsigned int usage, unsigned int count)
 {
-    _vertexFormats.push_back(VertexElement(usage, count));
+    _vertexFormat.push_back(VertexElement(usage, count));
 }
 
 size_t Mesh::getVertexCount() const
@@ -131,6 +133,21 @@ size_t Mesh::getVertexCount() const
     return vertices.size();
 }
 
+const Vertex& Mesh::getVertex(unsigned int index) const
+{
+    return vertices[index];
+}
+
+size_t Mesh::getVertexElementCount() const
+{
+    return _vertexFormat.size();
+}
+
+const VertexElement& Mesh::getVertexElement(unsigned int index) const
+{
+    return _vertexFormat[index];
+}
+
 bool Mesh::contains(const Vertex& vertex) const
 {
     return vertexLookupTable.count(vertex) > 0;
@@ -154,13 +171,20 @@ unsigned int Mesh::getVertexIndex(const Vertex& vertex)
 
 void Mesh::computeBounds()
 {
+    // If we have a Model with a MeshSkin associated with it,
+    // compute the bounds from the skin - otherwise compute
+    // it from the local mesh data.
+    if (model && model->getSkin())
+    {
+        model->getSkin()->computeBounds();
+        return;
+    }
+
     bounds.min.x = bounds.min.y = bounds.min.z = FLT_MAX;
     bounds.max.x = bounds.max.y = bounds.max.z = FLT_MIN;
     bounds.center.x = bounds.center.y = bounds.center.z = 0.0f;
     bounds.radius = 0.0f;
-    
-    // for each vertex
-    Vector3 avgPos;
+
     for (std::vector<Vertex>::const_iterator i = vertices.begin(); i != vertices.end(); i++)
     {
         // Update min/max for this vertex
@@ -176,16 +200,11 @@ void Mesh::computeBounds()
             bounds.max.y = i->position.y;
         if (i->position.z > bounds.max.z)
             bounds.max.z = i->position.z;
-
-        avgPos.x += i->position.x;
-        avgPos.y += i->position.y;
-        avgPos.z += i->position.z;
     }
 
     // Compute center point
-    bounds.center.x = avgPos.x / (float)vertices.size();
-    bounds.center.y = avgPos.y / (float)vertices.size();
-    bounds.center.z = avgPos.z / (float)vertices.size();
+    Vector3::add(bounds.min, bounds.max, &bounds.center);
+    bounds.center.scale(0.5f);
 
     // Compute radius by looping through all points again and finding the max
     // distance between the center point and each vertex position
@@ -199,7 +218,7 @@ void Mesh::computeBounds()
     }
 
     // Convert squared distance to distance for radius
-    bounds.radius = sqrtf(bounds.radius);
+    bounds.radius = sqrt(bounds.radius);
 }
 
 }

+ 13 - 8
gameplay-encoder/src/Mesh.h

@@ -5,12 +5,17 @@
 #include "Object.h"
 #include "MeshPart.h"
 #include "VertexElement.h"
+#include "BoundingVolume.h"
 
 namespace gameplay
 {
 
+class Model;
+
 class Mesh : public Object
 {
+    friend class Model;
+
 public:
 
     /**
@@ -38,6 +43,10 @@ public:
     void addVetexAttribute(unsigned int usage, unsigned int count);
 
     size_t getVertexCount() const;
+    const Vertex& getVertex(unsigned int index) const;
+
+    size_t getVertexElementCount() const;
+    const VertexElement& getVertexElement(unsigned int index) const;
 
     /**
      * Returns true if this MeshPart contains the given Vertex.
@@ -51,15 +60,10 @@ public:
 
     unsigned int getVertexIndex(const Vertex& vertex);
 
+    Model* model;
     std::vector<Vertex> vertices;
     std::vector<MeshPart*> parts;
-    struct
-    {
-        Vector3 min;
-        Vector3 max;
-        Vector3 center;
-        float radius;
-    } bounds;
+    BoundingVolume bounds;
     std::map<Vertex, unsigned int> vertexLookupTable;
 
 private:
@@ -67,9 +71,10 @@ private:
     void computeBounds();
 
 private:
-    std::vector<VertexElement> _vertexFormats;
+    std::vector<VertexElement> _vertexFormat;
 
 };
 
 }
+
 #endif

+ 2 - 1
gameplay-encoder/src/MeshPart.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "MeshPart.h"
 
 namespace gameplay
@@ -104,4 +105,4 @@ void MeshPart::updateIndexFormat(unsigned int newIndex)
     }
 }
 
-}
+}

+ 1 - 5
gameplay-encoder/src/MeshPart.h

@@ -1,8 +1,6 @@
 #ifndef MESHPART_H_
 #define MESHPART_H_
 
-#include <vector>
-
 #include "Base.h"
 #include "Object.h"
 #include "Vertex.h"
@@ -85,8 +83,6 @@ private:
     std::vector<unsigned int> _indices;
 };
 
-
-
 }
-#endif
 
+#endif

+ 342 - 16
gameplay-encoder/src/MeshSkin.cpp

@@ -1,6 +1,12 @@
+#include "Base.h"
 #include "MeshSkin.h"
 #include "Node.h"
 #include "StringUtil.h"
+#include "Mesh.h"
+#include "GPBFile.h"
+#include "Animations.h"
+#include "Transform.h"
+#include "../../gameplay/src/Curve.h"
 
 namespace gameplay
 {
@@ -30,11 +36,28 @@ void MeshSkin::writeBinary(FILE* file)
     Object::writeBinary(file);
     write(_bindShape, 16, file);
     write(_joints.size(), file);
-    for (std::list<Node*>::const_iterator i = _joints.begin(); i != _joints.end(); i++)
+    for (std::vector<Node*>::const_iterator i = _joints.begin(); i != _joints.end(); i++)
     {
         (*i)->writeBinaryXref(file);
     }
-    write(_bindPoses, file);
+    write(_bindPoses.size() * 16, file);
+    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
+    {
+        write(i->m, 16, file);
+    }
+
+    /*
+    // Write joint bounding spheres
+    write((unsigned int)_jointBounds.size(), file);
+    for (unsigned int i = 0; i < _jointBounds.size(); ++i)
+    {
+        BoundingVolume& v = _jointBounds[i];
+        write(v.center.x, file);
+        write(v.center.y, file);
+        write(v.center.z, file);
+        write(v.radius, file);
+    }
+    */
 }
 
 void MeshSkin::writeText(FILE* file)
@@ -44,17 +67,21 @@ void MeshSkin::writeText(FILE* file)
     fprintfMatrix4f(file, _bindShape);
     fprintf(file, "</bindShape>");
     fprintf(file, "<joints>");
-    for (std::list<std::string>::const_iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
+    for (std::vector<std::string>::const_iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
     {
         fprintf(file, "%s ", i->c_str());
     }
     fprintf(file, "</joints>\n");
-    fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size());
-    for (std::list<float>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
+    fprintf(file, "<bindPoses count=\"%lu\">", _bindPoses.size() * 16);
+    for (std::vector<Matrix>::const_iterator i = _bindPoses.begin(); i != _bindPoses.end(); i++)
     {
-        fprintf(file, "%f ", *i);
+        for (unsigned int j = 0; j < 16; ++j)
+        {
+            fprintf(file, "%f ", i->m[j]);
+        }
     }
     fprintf(file, "</bindPoses>\n");
+
     fprintElementEnd(file);
 }
 
@@ -71,17 +98,17 @@ void MeshSkin::setVertexInfluenceCount(unsigned int count)
     _vertexInfluenceCount = count;
 }
 
-void MeshSkin::setJointNames(const std::list<std::string>& list)
+void MeshSkin::setJointNames(const std::vector<std::string>& list)
 {
     _jointNames = list;
 }
 
-const std::list<std::string>& MeshSkin::getJointNames()
+const std::vector<std::string>& MeshSkin::getJointNames()
 {
     return _jointNames;
 }
 
-void MeshSkin::setJoints(const std::list<Node*>& list)
+void MeshSkin::setJoints(const std::vector<Node*>& list)
 {
     _joints = list;
 }
@@ -90,17 +117,13 @@ void MeshSkin::setBindPoses(std::vector<Matrix>& list)
 {
     for (std::vector<Matrix>::iterator i = list.begin(); i != list.end(); i++)
     {
-        float* a = i->m;
-        for (int j = 0; j < 16; j++)
-        {
-            _bindPoses.push_back(a[j]);
-        }
+        _bindPoses.push_back(*i);
     }
 }
 
 bool MeshSkin::hasJoint(const char* id)
 {
-    for (std::list<std::string>::iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
+    for (std::vector<std::string>::iterator i = _jointNames.begin(); i != _jointNames.end(); i++)
     {
         if (equals(*i, id))
         {
@@ -110,4 +133,307 @@ bool MeshSkin::hasJoint(const char* id)
     return false;
 }
 
-}
+void MeshSkin::computeBounds()
+{
+    // Find the offset of the blend indices and blend weights within the mesh vertices
+    int blendIndexOffset = -1;
+    int blendWeightOffset = -1;
+    for (unsigned int i = 0, count = _mesh->getVertexElementCount(); i < count; ++i)
+    {
+        const VertexElement& e = _mesh->getVertexElement(i);
+        switch (e.usage)
+        {
+        case BLENDINDICES:
+            blendIndexOffset = i;
+            break;
+        case BLENDWEIGHTS:
+            blendWeightOffset = i;
+            break;
+        }
+    }
+    if (blendIndexOffset == -1 || blendWeightOffset == -1)
+    {
+        // Need blend indices and blend weights to calculate skinned bounding volume
+        return;
+    }
+
+    DEBUGPRINT_VARG("\nComputing bounds for skin of mesh: %s\n", _mesh->getId().c_str());
+
+    Node* joint;
+
+    // Get the root joint
+    Node* rootJoint = _joints[0];
+    Node* parent = rootJoint->getParent();
+    while (parent)
+    {
+        // Is this parent in the list of joints that form the skeleton?
+        // If not, then it's simply a parent node to the root joint
+        if (find(_joints.begin(), _joints.end(), parent) != _joints.end())
+        {
+            rootJoint = parent;
+        }
+        parent = parent->getParent();
+    }
+
+    // If the root joint has a parent node, temporarily detach it so that its transform is
+    // not included in the bounding volume calculation below
+    Node* rootJointParent = rootJoint->getParent();
+    if (rootJointParent)
+    {
+        rootJointParent->removeChild(rootJoint);
+    }
+
+    unsigned int jointCount = _joints.size();
+    unsigned int vertexCount = _mesh->getVertexCount();
+
+    DEBUGPRINT_VARG("> %d joints found.\n", jointCount);
+
+    std::vector<AnimationChannel*> channels;
+    std::vector<Node*> channelTargets;
+    std::vector<Curve*> curves;
+    std::vector<Vector3> vertices;
+    _jointBounds.resize(jointCount);
+
+    // Construct a list of all animation channels that target the joints affecting this mesh skin
+    DEBUGPRINT("> Collecting animations...\n");
+    DEBUGPRINT("> 0%%\r");
+    for (unsigned int i = 0; i < jointCount; ++i)
+    {
+        joint = _joints[i];
+
+        // Find all animations that target this joint
+        Animations* animations = GPBFile::getInstance()->getAnimations();
+        for (unsigned int j = 0, animationCount = animations->getAnimationCount(); j < animationCount; ++j)
+        {
+            Animation* animation = animations->getAnimation(j);
+            for (unsigned int k = 0, channelCount = animation->getAnimationChannelCount(); k < channelCount; ++k)
+            {
+                AnimationChannel* channel = animation->getAnimationChannel(k);
+                if (channel->getTargetId() == joint->getId())
+                {
+                    if (find(channels.begin(), channels.end(), channel) == channels.end())
+                    {
+                        channels.push_back(channel);
+                        channelTargets.push_back(joint);
+                    }
+                }
+            }
+        }
+
+        // Calculate the local bounding volume for this joint
+        vertices.clear();
+        BoundingVolume jointBounds;
+        jointBounds.min.set(FLT_MAX, FLT_MAX, FLT_MAX);
+        jointBounds.max.set(FLT_MIN, FLT_MIN, FLT_MIN);
+        for (unsigned int j = 0; j < vertexCount; ++j)
+        {
+            const Vertex& v = _mesh->getVertex(j);
+
+            if ((v.blendIndices.x == i && !ISZERO(v.blendWeights.x)) ||
+                (v.blendIndices.y == i && !ISZERO(v.blendWeights.y)) ||
+                (v.blendIndices.z == i && !ISZERO(v.blendWeights.z)) ||
+                (v.blendIndices.w == i && !ISZERO(v.blendWeights.w)))
+            {
+                vertices.push_back(v.position);
+                // Update box min/max
+                if (v.position.x < jointBounds.min.x)
+                    jointBounds.min.x = v.position.x;
+                if (v.position.y < jointBounds.min.y)
+                    jointBounds.min.y = v.position.y;
+                if (v.position.z < jointBounds.min.z)
+                    jointBounds.min.z = v.position.z;
+                if (v.position.x > jointBounds.max.x)
+                    jointBounds.max.x = v.position.x;
+                if (v.position.y > jointBounds.max.y)
+                    jointBounds.max.y = v.position.y;
+                if (v.position.z > jointBounds.max.z)
+                    jointBounds.max.z = v.position.z;
+            }
+        }
+        if (vertices.size() > 0)
+        {
+            // Compute center point
+            Vector3::add(jointBounds.min, jointBounds.max, &jointBounds.center);
+            jointBounds.center.scale(0.5f);
+            // Compute radius
+            for (unsigned int j = 0, jointVertexCount = vertices.size(); j < jointVertexCount; ++j)
+            {
+                float d = jointBounds.center.distanceSquared(vertices[j]);
+                if (d > jointBounds.radius)
+                    jointBounds.radius = d;
+            }
+            jointBounds.radius = sqrt(jointBounds.radius);
+        }
+        _jointBounds[i] = jointBounds;
+
+        DEBUGPRINT_VARG("> %d%%\r", (int)((float)(i+1) / (float)jointCount * 100.0f));
+    }
+    DEBUGPRINT("\n");
+
+    unsigned int channelCount = channels.size();
+
+    // Create a Curve for each animation channel
+    float maxDuration = 0.0f;
+    DEBUGPRINT("> Building animation curves...\n");
+    DEBUGPRINT("> 0%%\r");
+    for (unsigned int i = 0; i < channelCount; ++i)
+    {
+        AnimationChannel* channel = channels[i];
+
+        const std::vector<float>& keyTimes = channel->getKeyTimes();
+        unsigned int keyCount = keyTimes.size();
+        if (keyCount == 0)
+            continue;
+
+        // Create a curve for this animation channel
+        Curve* curve = NULL;
+        switch (channel->getTargetAttribute())
+        {
+        case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
+            curve = new Curve(keyCount, 10);
+            curve->addQuaternionOffset(3);
+            break;
+        }
+        if (curve == NULL)
+        {
+            // Unsupported/not implemented curve type 
+            continue;
+        }
+
+        // Copy key values into a temporary array
+        unsigned int keyValuesCount = channel->getKeyValues().size();
+        float* keyValues = new float[keyValuesCount];
+        for (unsigned int j = 0; j < keyValuesCount; ++j)
+            keyValues[j] = channel->getKeyValues()[j];
+
+        // Determine animation duration
+        float startTime = keyTimes[0];
+        float duration = keyTimes[keyCount-1] - startTime;
+        if (duration > maxDuration)
+            maxDuration = duration;
+
+        // Set curve points
+        float* keyValuesPtr = keyValues;
+        for (unsigned int j = 0; j < keyCount; ++j)
+        {
+            // Store time normalized, between 0-1
+            float t = (keyTimes[j] - startTime) / duration;
+
+            // Set the curve point
+            // TODO: Handle other interpolation types
+            curve->setPoint(j, t, keyValuesPtr, gameplay::Curve::LINEAR);
+
+            // Move to the next point on the curve
+            keyValuesPtr += curve->getComponentCount();
+        }
+
+        delete[] keyValues;
+        keyValues = NULL;
+
+        curves.push_back(curve);
+
+        DEBUGPRINT_VARG("> %d%%\r", (int)((float)(i+1) / (float)channelCount * 100.0f));
+    }
+    DEBUGPRINT("\n");
+
+    // Compute a total combined bounding volume for the MeshSkin that contains all possible
+    // vertex positions for all animations targetting the skin. This rough approximation allows
+    // us to store a volume that can be used for rough intersection tests (such as for visibility
+    // determination) efficiently at runtime.
+
+    // Backup existing node transforms so we can restore them when we are finished
+    Matrix* oldTransforms = new Matrix[jointCount];
+    for (unsigned int i = 0; i < jointCount; ++i)
+    {
+        memcpy(oldTransforms[i].m, _joints[i]->getTransformMatrix().m, 16 * sizeof(float));
+    }
+
+    float time = 0.0f;
+    float srt[10];
+    Matrix temp;
+    Matrix* jointTransforms = new Matrix[jointCount];
+    _mesh->bounds.min.set(FLT_MAX, FLT_MAX, FLT_MAX);
+    _mesh->bounds.max.set(FLT_MIN, FLT_MIN, FLT_MIN);
+    _mesh->bounds.center.set(0, 0, 0);
+    _mesh->bounds.radius = 0;
+    Vector3 skinnedPos;
+    Vector3 tempPos;
+    DEBUGPRINT("> Evaluating joints...\n");
+    DEBUGPRINT("> 0%%\r");
+    BoundingVolume finalBounds;
+    while (time <= maxDuration)
+    {
+        // Evaluate joint transforms at this time interval
+        for (unsigned int i = 0, curveCount = curves.size(); i < curveCount; ++i)
+        {
+            Node* joint = channelTargets[i];
+            Curve* curve = curves[i];
+
+            // Evalulate the curve at this time to get the new value
+            float tn = time / maxDuration;
+            if (tn > 1.0f)
+                tn = 1.0f;
+            curve->evaluate(tn, srt);
+
+            // Update the joint's local transform
+            Matrix::createTranslation(srt[7], srt[8], srt[9], temp.m);
+            temp.rotate(*((Quaternion*)&srt[3]));
+            temp.scale(srt[0], srt[1], srt[2]);
+            joint->setTransformMatrix(temp.m);
+        }
+
+        // Store the final matrix pallette of resovled world space joint matrices
+        std::vector<Matrix>::const_iterator bindPoseItr = _bindPoses.begin();
+        for (unsigned int i = 0; i < jointCount; ++i, bindPoseItr++)
+        {
+            BoundingVolume bounds = _jointBounds[i];
+            if (ISZERO(bounds.radius))
+                continue;
+
+            Matrix& m = jointTransforms[i];
+            Matrix::multiply(_joints[i]->getWorldMatrix().m, bindPoseItr->m, m.m);
+            Matrix::multiply(m.m, _bindShape, m.m);
+
+            // Get a world-space bounding volume for this joint
+            bounds.transform(m);
+            if (ISZERO(finalBounds.radius))
+                finalBounds = bounds;
+            else
+                finalBounds.merge(bounds);
+        }
+
+        // Increment time by 1/30th of second (~ 33 ms)
+        if (time < maxDuration && (time + 33.0f) > maxDuration)
+            time = maxDuration;
+        else
+            time += 33.0f;
+
+        DEBUGPRINT_VARG("> %d%%\r", (int)(time / maxDuration * 100.0f));
+    }
+    DEBUGPRINT("\n");
+
+    // Update the bounding sphere for the mesh
+    _mesh->bounds = finalBounds;
+
+    // Restore original joint transforms
+    for (unsigned int i = 0; i < jointCount; ++i)
+    {
+        _joints[i]->setTransformMatrix(oldTransforms[i].m);
+    }
+
+    // Cleanup
+    for (unsigned int i = 0, curveCount = curves.size(); i < curveCount; ++i)
+    {
+        delete curves[i];
+    }
+    delete[] oldTransforms;
+    delete[] jointTransforms;
+
+    // Restore removed joints
+    if (rootJointParent)
+    {
+        rootJointParent->addChild(rootJoint);
+    }
+}
+
+}

+ 15 - 10
gameplay-encoder/src/MeshSkin.h

@@ -1,20 +1,22 @@
 #ifndef MESHSKIN_H_
 #define MESHSKIN_H_
 
-#include <vector>
-
 #include "Base.h"
 #include "Object.h"
 #include "Matrix.h"
 #include "Animation.h"
+#include "BoundingVolume.h"
 
 namespace gameplay
 {
 
 class Node;
+class Mesh;
 
 class MeshSkin : public Object
 {
+    friend class Model;
+
 public:
 
     /**
@@ -36,11 +38,11 @@ public:
 
     void setVertexInfluenceCount(unsigned int count);
 
-    void setJointNames(const std::list<std::string>& list);
+    void setJointNames(const std::vector<std::string>& list);
 
-    const std::list<std::string>& getJointNames();
+    const std::vector<std::string>& getJointNames();
 
-    void setJoints(const std::list<Node*>& list);
+    void setJoints(const std::vector<Node*>& list);
 
     void setBindPoses(std::vector<Matrix>& list);
 
@@ -53,16 +55,19 @@ public:
      */
     bool hasJoint(const char* id);
 
+    void computeBounds();
+
 private:
 
+    Mesh* _mesh;
     float _bindShape[16];
-    std::list<Node*> _joints;
-    std::list<float> _bindPoses;
-
-    std::list<std::string> _jointNames;
-
+    std::vector<Node*> _joints;
+    std::vector<Matrix> _bindPoses;
+    std::vector<std::string> _jointNames;
     unsigned int _vertexInfluenceCount;
+    std::vector<BoundingVolume> _jointBounds;
 };
 
 }
+
 #endif

+ 20 - 1
gameplay-encoder/src/Model.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Model.h"
 
 namespace gameplay
@@ -49,8 +50,11 @@ void Model::writeBinary(FILE* file)
     writeBinaryObjects(_materials, file);
 
 }
+
 void Model::writeText(FILE* file)
 {
+    // Compute mesh bounds before writing
+
     fprintElementStart(file);
     if (_ref != NULL)
     {
@@ -71,11 +75,26 @@ MeshSkin* Model::getSkin()
 void Model::setMesh(Mesh* mesh)
 {
     _ref = mesh;
+
+    if (mesh)
+    {
+        mesh->model = this;
+    }
+
+    if (_ref && _meshSkin)
+    {
+        _meshSkin->_mesh = _ref;
+    }
 }
 
 void Model::setSkin(MeshSkin* skin)
 {
     _meshSkin = skin;
+
+    if (_meshSkin)
+    {
+        _meshSkin->_mesh = _ref;
+    }
 }
 
-}
+}

+ 2 - 3
gameplay-encoder/src/Model.h

@@ -1,8 +1,6 @@
 #ifndef MODEL_H_
 #define MODEL_H_
 
-#include <list>
-
 #include "Object.h"
 #include "Mesh.h"
 #include "MeshSkin.h"
@@ -35,11 +33,12 @@ public:
     void setSkin(MeshSkin* skin);
 
 private:
+
     Mesh* _ref;
     MeshSkin* _meshSkin;
     std::list<Material*> _materials;
 };
 
 }
-#endif
 
+#endif

+ 23 - 6
gameplay-encoder/src/Node.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Node.h"
 
 #define NODE 1
@@ -12,7 +13,7 @@ Node::Node(void) :
     _firstChild(NULL), _lastChild(NULL), _parent(NULL),
     _camera(NULL), _light(NULL), _model(NULL), _joint(false)
 {
-    setIdentityMatrix(_transform);
+    setIdentityMatrix(_transform.m);
 }
 
 Node::~Node(void)
@@ -37,7 +38,7 @@ void Node::writeBinary(FILE* file)
     unsigned int type = _joint ? JOINT : NODE;
     write(type, file);
 
-    write(_transform, 16, file);
+    write(_transform.m, 16, file);
     // children
     write(getChildCount(), file); // write number of children
     for (Node* node = getFirstChild(); node != NULL; node = node->getNextSibling())
@@ -84,7 +85,7 @@ void Node::writeText(FILE* file)
         fprintElementStart(file);
     }
     fprintf(file, "<transform>");
-    fprintfMatrix4f(file, _transform);
+    fprintfMatrix4f(file, _transform.m);
     fprintf(file, "</transform>\n");
 
     // children
@@ -232,12 +233,28 @@ void Node::setModel(Model* model)
     _model = model;
 }
 
+const Matrix& Node::getTransformMatrix() const
+{
+    return _transform;
+}
+
 void Node::setTransformMatrix(float matrix[])
 {
-    for (int i = 0; i < 16; i++)
+    memcpy(_transform.m, matrix, 16 * sizeof(float));
+}
+
+const Matrix& Node::getWorldMatrix() const
+{
+    if (_parent)
     {
-        _transform[i] = matrix[i];
+        Matrix::multiply(_parent->getWorldMatrix().m, _transform.m, _worldTransform.m);
     }
+    else
+    {
+        memcpy(_worldTransform.m, _transform.m, 16 * sizeof(float));
+    }
+
+    return _worldTransform;
 }
 
 void Node::setIsJoint(bool value)
@@ -304,4 +321,4 @@ bool Node::hasLight() const
     return _light != NULL;
 }
 
-}
+}

+ 14 - 5
gameplay-encoder/src/Node.h

@@ -1,8 +1,6 @@
 #ifndef NODE_H_
 #define NODE_H_
 
-#include <list>
-
 #include "Object.h"
 #include "CameraInstance.h"
 #include "LightInstance.h"
@@ -125,11 +123,21 @@ public:
      */
     Model* getModel() const;
 
+    /**
+     * Returns the transform matrix for the node.
+     */
+    const Matrix& getTransformMatrix() const;
+
     /**
      * Sets the transform for this node.
      */
     void setTransformMatrix(float matrix[]);
 
+    /**
+     * Returns the resolved world matrix for the node.
+     */
+    const Matrix& getWorldMatrix() const;
+
     void setCameraInstance(CameraInstance* cameraInstance);
     void setLightInstance(LightInstance* lightInstance);
     void setModel(Model* model);
@@ -157,7 +165,9 @@ public:
     bool hasLight() const;
     
 private:
-    float _transform[16];
+
+    Matrix _transform;
+    mutable Matrix _worldTransform;
 
     int _childCount;
     Node* _nextSibling;
@@ -173,7 +183,6 @@ private:
     bool _joint;
 };
 
-
 }
-#endif
 
+#endif

+ 2 - 1
gameplay-encoder/src/Object.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Object.h"
 
 namespace gameplay
@@ -76,4 +77,4 @@ void Object::writeBinaryXref(FILE* file)
     write(xref, file);
 }
 
-}
+}

+ 2 - 2
gameplay-encoder/src/Object.h

@@ -1,11 +1,11 @@
 #ifndef OBJ_H_
 #define OBJ_H_
 
-#include "Base.h"
 #include "FileIO.h"
 
 namespace gameplay
 {
+
 /**
  * Object is the abstract base class of all the objects that can be written in the GamePlay Binary file.
  */
@@ -35,7 +35,6 @@ public:
         FONT_ID = 128,
     };
 
-
     /**
      * Constructor.
      */
@@ -137,6 +136,7 @@ public:
     }
 
 private:
+
     /**
      * Saves where this object was written to in the binary file.
      */

+ 1 - 5
gameplay-encoder/src/Quaternion.cpp

@@ -1,7 +1,3 @@
-/*
- * Quaternion.cpp
- */
-
 #include "Base.h"
 #include "Quaternion.h"
 
@@ -162,7 +158,7 @@ void Quaternion::normalize(Quaternion* dst) const
     if (n == 1.0f)
         return;
 
-    n = sqrtf(n);
+    n = sqrt(n);
     // too close to zero
     if (n < 0.000001f)
         return;

+ 2 - 5
gameplay-encoder/src/Quaternion.h

@@ -1,7 +1,3 @@
-/*
- * Quaternion.h
- */
-
 #ifndef QUATERNION_H_
 #define QUATERNION_H_
 
@@ -308,4 +304,5 @@ private:
 };
 
 }
-#endif /* QUATERNION_H_ */
+
+#endif

+ 2 - 1
gameplay-encoder/src/Reference.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Reference.h"
 
 namespace gameplay
@@ -83,4 +84,4 @@ Object* Reference::getObj()
     return _ref;
 }
 
-}
+}

+ 1 - 0
gameplay-encoder/src/Reference.h

@@ -53,4 +53,5 @@ private:
 };
 
 }
+
 #endif

+ 2 - 1
gameplay-encoder/src/ReferenceTable.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "ReferenceTable.h"
 
 namespace gameplay
@@ -65,4 +66,4 @@ std::map<std::string, Reference>::iterator ReferenceTable::end()
     return _table.end();
 }
 
-}
+}

+ 1 - 3
gameplay-encoder/src/ReferenceTable.h

@@ -1,8 +1,6 @@
 #ifndef REFTABLE_H_
 #define REFTABLE_H_
 
-#include <map>
-
 #include "FileIO.h"
 #include "Reference.h"
 #include "Object.h"
@@ -56,5 +54,5 @@ private:
 };
 
 }
-#endif
 
+#endif

+ 3 - 3
gameplay-encoder/src/Scene.cpp

@@ -1,5 +1,4 @@
-#include <algorithm>
-
+#include "Base.h"
 #include "Scene.h"
 
 namespace gameplay
@@ -40,6 +39,7 @@ void Scene::writeBinary(FILE* file)
     }
     write(_ambientColor, Light::COLOR_SIZE, file);
 }
+
 void Scene::writeText(FILE* file)
 {
     fprintElementStart(file);
@@ -113,4 +113,4 @@ void Scene::calcAmbientColor(const Node* node, float* values) const
     }
 }
 
-}
+}

+ 1 - 0
gameplay-encoder/src/Scene.h

@@ -68,4 +68,5 @@ private:
 };
 
 }
+
 #endif

+ 2 - 3
gameplay-encoder/src/StringUtil.cpp

@@ -1,7 +1,6 @@
+#include "Base.h"
 #include "StringUtil.h"
 
-#include <string>
-
 namespace gameplay
 {
 
@@ -100,4 +99,4 @@ bool equalsIgnoreCase(const std::string& a, const char* b)
     return true;
 }
 
-}
+}

+ 1 - 2
gameplay-encoder/src/StringUtil.h

@@ -1,8 +1,6 @@
 #ifndef STRINGUTIL_H_
 #define STRINGUTIL_H_
 
-#include <string>
-
 namespace gameplay
 {
 
@@ -20,4 +18,5 @@ bool equals(const std::string& a, const char* b);
 bool equalsIgnoreCase(const std::string& a, const char* b);
 
 }
+
 #endif

+ 8 - 3
gameplay-encoder/src/TTFFontEncoder.cpp

@@ -1,5 +1,9 @@
+#include "Base.h"
 #include "TTFFontEncoder.h"
+#include "GPBFile.h"
 
+namespace gameplay
+{
 
 void drawBitmap(unsigned char* dstBitmap, int x, int y, int dstWidth, unsigned char* srcBitmap, int srcWidth, int srcHeight)
 {
@@ -263,9 +267,8 @@ int writeFont(const char* filename, unsigned int fontSize, const char* id, bool
     
     // File header and version.
     char fileHeader[9]     = {'«', 'G', 'P', 'B', '»', '\r', '\n', '\x1A', '\n'};
-    char fileVersion[2]    = {1, 0};
     fwrite(fileHeader, sizeof(char), 9, gpbFp);
-    fwrite(fileVersion, sizeof(char), 2, gpbFp);
+    fwrite(gameplay::VERSION, sizeof(char), 2, gpbFp);
 
     // Write Ref table (for a single font)
     writeUint(gpbFp, 1);                // Ref[] count
@@ -326,4 +329,6 @@ int writeFont(const char* filename, unsigned int fontSize, const char* id, bool
     FT_Done_Face(face);
     FT_Done_FreeType(library);
     return 0;
-}
+}
+
+}

+ 5 - 7
gameplay-encoder/src/TTFFontEncoder.h

@@ -1,9 +1,4 @@
-#include <stdio.h>
 #include <ft2build.h>
-#include "string.h"
-#include <fstream>
-#include <math.h>
-
 #include FT_FREETYPE_H
 
 #define START_INDEX     32
@@ -11,6 +6,8 @@
 
 #define GLYPH_PADDING   4
 
+namespace gameplay
+{
 
 // Structure of Glyph.
 class Glyph
@@ -21,7 +18,6 @@ public:
     float uvCoords[4];
 };
 
-
 void drawBitmap(unsigned char* dstBitmap, int x, int y, int dstWidth, unsigned char* srcBitmap, int srcWidth, int srcHeight);
 
 void writeUint(FILE* fp, unsigned int i);
@@ -30,4 +26,6 @@ void writeFloat(FILE* fp, float f);
 
 void writeString(FILE* fp, const char* str);
 
-int writeFont(const char* filename, unsigned int fontSize, const char* id, bool fontpreview);
+int writeFont(const char* filename, unsigned int fontSize, const char* id, bool fontpreview);
+
+}

+ 2 - 0
gameplay-encoder/src/Transform.cpp

@@ -0,0 +1,2 @@
+#include "Base.h"
+#include "Transform.h"

+ 3 - 9
gameplay-encoder/src/Vector2.cpp

@@ -1,7 +1,3 @@
-/*
- * Vector2.cpp
- */
-
 #include "Base.h"
 #include "Vector2.h"
 #include "FileIO.h"
@@ -151,7 +147,7 @@ float Vector2::distance(const Vector2& v)
     float dx = v.x - x;
     float dy = v.y - y;
 
-    return sqrtf(dx * dx + dy * dy);
+    return sqrt(dx * dx + dy * dy);
 }
 
 
@@ -177,7 +173,7 @@ float Vector2::dot(const Vector2& v1, const Vector2& v2)
 
 float Vector2::length()
 {
-    return sqrtf(x * x + y * y);
+    return sqrt(x * x + y * y);
 }
 
 
@@ -215,7 +211,7 @@ void Vector2::normalize(Vector2* dst)
     if (n == 1.0f)
         return;
 
-    n = sqrtf(n);
+    n = sqrt(n);
     // too close to zero
     if (n < MATH_TOLERANCE)
         return;
@@ -319,5 +315,3 @@ void Vector2::writeText(FILE* file) const
 }
 
 }
-
-

+ 1 - 5
gameplay-encoder/src/Vector2.h

@@ -1,13 +1,9 @@
-/*
- * Vector2.h
- */
-
 #ifndef VECTOR2_H_
 #define VECTOR2_H_
 
-
 namespace gameplay
 {
+
 // Forward declare
 class Matrix;
 

+ 3 - 7
gameplay-encoder/src/Vector3.cpp

@@ -1,7 +1,3 @@
-/*
- * Vector3.cpp
- */
-
 #include "Base.h"
 #include "Vector3.h"
 #include "FileIO.h"
@@ -96,7 +92,7 @@ float Vector3::angle(const Vector3& v1, const Vector3& v2)
     float dy = v1.z * v2.x - v1.x * v2.z;
     float dz = v1.x * v2.y - v1.y * v2.x;
 
-    return atan2f(sqrtf(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dot(v1, v2));
+    return atan2f(sqrt(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dot(v1, v2));
 }
 
 
@@ -200,7 +196,7 @@ float Vector3::distance(const Vector3& v)
     float dy = v.y - y;
     float dz = v.z - z;
 
-    return sqrtf(dx * dx + dy * dy + dz * dz);
+    return sqrt(dx * dx + dy * dy + dz * dz);
 }
 
 
@@ -228,7 +224,7 @@ float Vector3::dot(const Vector3& v1, const Vector3& v2)
 
 float Vector3::length()
 {
-    return sqrtf(x * x + y * y + z * z);
+    return sqrt(x * x + y * y + z * z);
 }
 
 

+ 0 - 7
gameplay-encoder/src/Vector3.h

@@ -1,11 +1,6 @@
-/*
- * Vector3.h
- */
-
 #ifndef VECTOR3_H_
 #define VECTOR3_H_
 
-
 namespace gameplay
 {
 
@@ -337,8 +332,6 @@ public:
      */
     static void subtract(const Vector3& v1, const Vector3& v2, Vector3* dst);
 
-
-
     inline bool operator<(const Vector3& v) const
     {
         if (x == v.x)

+ 3 - 7
gameplay-encoder/src/Vector4.cpp

@@ -1,7 +1,3 @@
-/*
- * Vector4.cpp
- */
-
 #include "Base.h"
 #include "Vector4.h"
 #include "FileIO.h"
@@ -104,7 +100,7 @@ float Vector4::angle(const Vector4& v1, const Vector4& v2)
     float dy = v1.w * v2.y - v1.y * v2.w - v1.z * v2.x + v1.x * v2.z;
     float dz = v1.w * v2.z - v1.z * v2.w - v1.x * v2.y + v1.y * v2.x;
 
-    return atan2f(sqrtf(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dot(v1, v2));
+    return atan2f(sqrt(dx * dx + dy * dy + dz * dz) + MATH_FLOAT_SMALL, dot(v1, v2));
 }
 
 
@@ -200,7 +196,7 @@ float Vector4::distance(const Vector4& v)
     float dz = v.z - z;
     float dw = v.w - w;
 
-    return sqrtf(dx * dx + dy * dy + dz * dz + dw * dw);
+    return sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
 }
 
 
@@ -229,7 +225,7 @@ float Vector4::dot(const Vector4& v1, const Vector4& v2)
 
 float Vector4::length()
 {
-    return sqrtf(x * x + y * y + z * z + w * w);
+    return sqrt(x * x + y * y + z * z + w * w);
 }
 
 

+ 1 - 5
gameplay-encoder/src/Vector4.h

@@ -1,7 +1,3 @@
-/*
- * Vector4.h
- */
-
 #ifndef VECTOR4_H_
 #define VECTOR4_H_
 
@@ -367,4 +363,4 @@ public:
 
 }
 
-#endif
+#endif

+ 2 - 1
gameplay-encoder/src/Vertex.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Vertex.h"
 
 namespace gameplay
@@ -102,4 +103,4 @@ void Vertex::writeText(FILE* file) const
     }
 }
 
-}
+}

+ 1 - 0
gameplay-encoder/src/Vertex.h

@@ -92,4 +92,5 @@ public:
 };
 
 }
+
 #endif

+ 2 - 1
gameplay-encoder/src/VertexElement.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "VertexElement.h"
 
 namespace gameplay
@@ -72,4 +73,4 @@ const char* VertexElement::usageStr(unsigned int usage)
     }
 }
 
-}
+}

+ 1 - 0
gameplay-encoder/src/VertexElement.h

@@ -31,4 +31,5 @@ public:
 };
 
 }
+
 #endif

+ 1 - 3
gameplay-encoder/src/main.cpp

@@ -1,5 +1,4 @@
-#include <string>
-
+#include "Base.h"
 #include "DAESceneEncoder.h"
 #include "TTFFontEncoder.h"
 #include "GPBDecoder.h"
@@ -83,4 +82,3 @@ int main(int argc, const char** argv)
 
     return 0;
 }
-

BIN
gameplay-tutorials/sample01-longboard.pdf


BIN
gameplay-tutorials/sample02-spaceship.pdf


+ 0 - 13
gameplay.sln

@@ -25,13 +25,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample03-character", "gamep
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-encoder", "gameplay-encoder\gameplay-encoder.vcxproj", "{9D69B743-4872-4DD1-8E30-0087C64298D7}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D3CA8AE2-3ED6-458B-963A-EDA671E6F51C}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample04-sandbox", "gameplay-samples\sample04-sandbox\sample04-sandbox.vcxproj", "{FA260001-5B2E-41B7-86DD-C7F26DF3A485}"
-	ProjectSection(ProjectDependencies) = postProject
-		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -75,12 +68,6 @@ Global
 		{9D69B743-4872-4DD1-8E30-0087C64298D7}.DebugMem|Win32.Build.0 = Debug|Win32
 		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Release|Win32.ActiveCfg = Release|Win32
 		{9D69B743-4872-4DD1-8E30-0087C64298D7}.Release|Win32.Build.0 = Release|Win32
-		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Debug|Win32.ActiveCfg = Debug|Win32
-		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Debug|Win32.Build.0 = Debug|Win32
-		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Release|Win32.ActiveCfg = Release|Win32
-		{FA260001-5B2E-41B7-86DD-C7F26DF3A485}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 14 - 7
gameplay/.cproject

@@ -27,7 +27,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.2133604142" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.997142816" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -79,7 +80,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1670164593" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1380846613" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -130,7 +132,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1503059677" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.81809638" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -184,7 +187,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1769677874" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.2007171407" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -236,7 +240,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.847642559" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1038720310" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -288,7 +293,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.513622172" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1961855927" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -341,7 +347,8 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1685994750" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}\..\external-deps\bullet\include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/bullet/include&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../external-deps/oggvorbis/include&quot;"/>
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1658185881" superClass="com.qnx.qcc.inputType.compiler"/>

+ 12 - 7
gameplay/gameplay.vcxproj

@@ -69,6 +69,7 @@
     <ClCompile Include="src\Ref.cpp" />
     <ClCompile Include="src\RenderState.cpp" />
     <ClCompile Include="src\Scene.cpp" />
+    <ClCompile Include="src\SceneLoader.cpp" />
     <ClCompile Include="src\SpriteBatch.cpp" />
     <ClCompile Include="src\Technique.cpp" />
     <ClCompile Include="src\Texture.cpp" />
@@ -134,6 +135,7 @@
     <ClInclude Include="src\Ref.h" />
     <ClInclude Include="src\RenderState.h" />
     <ClInclude Include="src\Scene.h" />
+    <ClInclude Include="src\SceneLoader.h" />
     <ClInclude Include="src\SpriteBatch.h" />
     <ClInclude Include="src\Technique.h" />
     <ClInclude Include="src\Texture.h" />
@@ -166,11 +168,12 @@
     <None Include="res\shaders\solid.vsh" />
     <None Include="res\shaders\textured.fsh" />
     <None Include="res\shaders\textured.vsh" />
-    <None Include="src\gameplay-main-macosx.mm" />
     <None Include="src\BoundingBox.inl" />
     <None Include="src\BoundingSphere.inl" />
+    <None Include="src\gameplay-main-macos.mm" />
     <None Include="src\Matrix.inl" />
     <None Include="src\Plane.inl" />
+    <None Include="src\PlatformMacOS.mm" />
     <None Include="src\Quaternion.inl" />
     <None Include="src\Ray.inl" />
     <None Include="src\Vector2.inl" />
@@ -243,10 +246,11 @@
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>
       </RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -259,9 +263,10 @@
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -281,7 +286,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -293,4 +298,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 15 - 6
gameplay/gameplay.vcxproj.filters

@@ -172,10 +172,10 @@
       <Filter>src</Filter>
     </ClCompile>
     <ClCompile Include="src\gameplay-main-win32.cpp">
-		<Filter>src</Filter>
+      <Filter>src</Filter>
     </ClCompile>
     <ClCompile Include="src\DebugNew.cpp">
-		<Filter>src</Filter>
+      <Filter>src</Filter>
     </ClCompile>
     <ClCompile Include="src\PhysicsController.cpp">
       <Filter>src</Filter>
@@ -204,6 +204,9 @@
     <ClCompile Include="src\PhysicsMotionState.cpp">
       <Filter>src</Filter>
     </ClCompile>
+    <ClCompile Include="src\SceneLoader.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
@@ -395,6 +398,9 @@
     <ClInclude Include="src\PhysicsSocketConstraint.h">
       <Filter>src</Filter>
     </ClInclude>
+    <ClInclude Include="src\SceneLoader.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\shaders\bumped-specular.vsh">
@@ -457,11 +463,14 @@
     <None Include="res\shaders\bumped-specular.fsh">
       <Filter>res\shaders</Filter>
     </None>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="src\gameplay-main-macosx.mm">
+    <None Include="src\gameplay-main-macos.mm">
+      <Filter>src</Filter>
+    </None>
+    <None Include="src\PlatformMacOS.mm">
       <Filter>src</Filter>
     </None>
+  </ItemGroup>
+  <ItemGroup>
     <None Include="src\PhysicsFixedConstraint.inl">
       <Filter>src</Filter>
     </None>
@@ -505,4 +514,4 @@
       <Filter>src</Filter>
     </None>
   </ItemGroup>
-</Project>
+</Project>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 610 - 465
gameplay/gameplay.xcodeproj/project.pbxproj


+ 83 - 46
gameplay/src/Animation.cpp

@@ -1,7 +1,3 @@
-/*
- * Animation.cpp
- */
-
 #include "Base.h"
 #include "Animation.h"
 #include "AnimationController.h"
@@ -9,7 +5,6 @@
 #include "AnimationTarget.h"
 #include "Game.h"
 #include "Transform.h"
-#include <string.h>
 #include "Properties.h"
 
 #define ANIMATION_DEFAULT_CLIP_SUFFIX "__default__clip"
@@ -22,55 +17,62 @@ namespace gameplay
 {
 
 Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type)
-    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0)
+    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
 {
     createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);
-    createDefaultClip();
 }
 
 Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
-    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0)
+    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
 {
     createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
-    createDefaultClip();
 }
 
 Animation::~Animation()
 {
-    std::vector<Channel*>::iterator channelIter = _channels.begin();
+    if (_clips != NULL)
+    {
+        std::vector<AnimationClip*>::iterator clipIter = _clips->begin();
     
+        while (clipIter != _clips->end())
+        {   
+            AnimationClip* clip = *clipIter;
+            clip->stop();
+            SAFE_RELEASE(clip);
+            clipIter++;
+        }
+        _clips->clear();
+    }
+    SAFE_DELETE(_clips);
+
+    SAFE_DELETE(_defaultClip);
+
+    /*vector<Channel*>::iterator channelIter = _channels.begin();
     while (channelIter != _channels.end())
     {
-        SAFE_DELETE(*channelIter);
+        Animation::Channel* channel = *channelIter;
+        channel->_target->removeChannel(channel);
+        SAFE_RELEASE(channel);
         channelIter++;
-    }
+    }*/
     _channels.clear();
-    
-    std::vector<AnimationClip*>::iterator clipIter = _clips.begin();
-    
-    while (clipIter != _clips.end())
-    {
-        AnimationClip* clip = *clipIter;
-        SAFE_RELEASE(clip);
-        clipIter++;
-    }
-    _clips.clear();
 }
 
-Animation::Channel::Channel(AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
-    : _isRelative(false)
+Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
+    : _animation(animation), _target(target), _propertyId(propertyId), _curve(curve), _duration(duration)
 {
     // get property component count, and ensure the property exists on the AnimationTarget by getting the property component count.
-    assert(target->getAnimationPropertyComponentCount(propertyId));
+    assert(_target->getAnimationPropertyComponentCount(propertyId));
+
+    _animation->addRef();
 
-    _target = target;
-    _propertyId = propertyId;
-    _curve = curve;
-    _duration = duration;
+    _target->addChannel(this);
 }
 
 Animation::Channel::~Channel()
 {
+    _animation->removeChannel(this);
+    SAFE_RELEASE(_animation);
     SAFE_DELETE(_curve);
 }
 
@@ -105,7 +107,7 @@ void Animation::createClips(const char* animationFile)
         const char* repeat = pClip->getString("repeatCount");
         if (repeat)
         {
-            if (((std::string)repeat).compare(ANIMATION_INDEFINITE_STR) == 0)
+            if (strcmp(repeat, ANIMATION_INDEFINITE_STR) == 0)
             {
                 clip->setRepeatCount(AnimationClip::REPEAT_INDEFINITE);
             }
@@ -133,7 +135,7 @@ void Animation::createClips(const char* animationFile)
 
 AnimationClip* Animation::createClip(const char* id, unsigned long start, unsigned long end)
 {
-    if (findClip(id) != NULL)
+    if (_clips != NULL && findClip(id) != NULL)
     {
         return NULL;
     }
@@ -150,7 +152,10 @@ AnimationClip* Animation::getClip(const char* id)
     // If id is NULL return the default clip.
     if (id == NULL)
     {
-        return _clips[ANIMATION_DEFAULT_CLIP];
+        if (_defaultClip == NULL)
+            createDefaultClip();
+
+        return _defaultClip;
     }
     else
     {
@@ -163,7 +168,10 @@ void Animation::play(const char* id)
     // If id is NULL, play the default clip.
     if (id == NULL)
     {
-        _clips[ANIMATION_DEFAULT_CLIP]->play();
+        if (_defaultClip == NULL)
+            createDefaultClip();
+        
+        _defaultClip->play();
     }
     else
     {
@@ -181,7 +189,10 @@ void Animation::stop(const char* id)
     // If id is NULL, play the default clip.
     if (id == NULL)
     {
-        _clips[ANIMATION_DEFAULT_CLIP]->stop();
+        if (_defaultClip == NULL)
+            createDefaultClip();
+
+        _defaultClip->stop();
     }
     else
     {
@@ -236,10 +247,8 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
 
     SAFE_DELETE(normalizedKeyTimes);
 
-    Channel* channel = new Channel(target, propertyId, curve, duration);
-
+    Channel* channel = new Channel(this, target, propertyId, curve, duration);
     addChannel(channel);
-
     return channel;
 }
 
@@ -285,10 +294,8 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
 
     SAFE_DELETE(normalizedKeyTimes);
 
-    Channel* channel = new Channel(target, propertyId, curve, duration);
-
+    Channel* channel = new Channel(this, target, propertyId, curve, duration);
     addChannel(channel);
-
     return channel;
 }
 
@@ -300,25 +307,55 @@ void Animation::addChannel(Channel* channel)
         _duration = channel->_duration;
 }
 
+void Animation::removeChannel(Channel* channel)
+{
+    std::vector<Animation::Channel*>::iterator itr = _channels.begin();
+    while (itr != _channels.end())
+    {
+        Animation::Channel* chan = *itr;
+        if (channel == chan) 
+        {
+            _channels.erase(itr);
+            itr = _channels.end();
+        }
+        else
+        {
+            itr++;
+        }
+    }
+
+    if (_channels.empty())
+        _controller->destroyAnimation(this);
+}
+
 void Animation::createDefaultClip()
 {
     std::string clipId = _id + ANIMATION_DEFAULT_CLIP_SUFFIX;
-    _clips.push_back(new AnimationClip(clipId.c_str(), this, 0.0f, _duration));
+
+    _defaultClip = new AnimationClip(clipId.c_str(), this, 0.0f, _duration);
 }
 
 void Animation::addClip(AnimationClip* clip)
 {
-    _clips.push_back(clip);
+    if (_clips == NULL)
+        _clips = new std::vector<AnimationClip*>;
+
+    _clips->push_back(clip);
 }
 
 AnimationClip* Animation::findClip(const char* id) const
 {
-    unsigned int clipCount = _clips.size();
-    for (unsigned int i = 0; i < clipCount; i++)
+    if (_clips)
     {
-        if (_clips.at(i)->_id.compare(id) == 0)
+        AnimationClip* clip = NULL;
+        unsigned int clipCount = _clips->size();
+        for (unsigned int i = 0; i < clipCount; i++)
         {
-            return _clips.at(i);
+            clip = _clips->at(i);
+            if (clip->_id.compare(id) == 0)
+            {
+                return _clips->at(i);
+            }
         }
     }
     return NULL;

+ 11 - 7
gameplay/src/Animation.h

@@ -1,7 +1,3 @@
-/*
- * Animation.h
- */
-
 #ifndef ANIMATION_H_
 #define ANIMATION_H_
 
@@ -97,18 +93,19 @@ private:
     {
         friend class AnimationClip;
         friend class Animation;
+        friend class AnimationTarget;
 
     private:
 
-        Channel(AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration);
+        Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration);
         Channel(const Channel& copy);
         ~Channel();
 
+        Animation* _animation;                // Reference to the animation this channel belongs to.
         AnimationTarget* _target;             // The target of this channel.
         int _propertyId;                      // The target property this channel targets.
         Curve* _curve;                        // The curve used to represent the animation data.
         unsigned long _duration;              // The length of the animation (in milliseconds).
-        bool _isRelative;                     // Whether the data should be treated relatively or not. 
     };
 
     /**
@@ -165,12 +162,19 @@ private:
      * Adds a channel to the animation.
      */
     void addChannel(Channel* channel);
+
+    /**
+     * Removes a channel from the animation.
+     */
+    void removeChannel(Channel* channel);
     
     AnimationController* _controller;       // The AnimationController that this Animation will run on.
     std::string _id;                        // The Animation's ID.
     unsigned long _duration;                // the length of the animation (in milliseconds).
     std::vector<Channel*> _channels;        // The channels within this Animation.
-    std::vector<AnimationClip*> _clips;     // All the clips created from this Animation.
+    AnimationClip* _defaultClip;            // The Animation's default clip.
+    std::vector<AnimationClip*>* _clips;    // All the clips created from this Animation.
+
 };
 
 }

+ 324 - 26
gameplay/src/AnimationClip.cpp

@@ -1,46 +1,43 @@
-/*
- * AnimationClip.cpp
- */
-
 #include "Base.h"
 #include "AnimationClip.h"
 #include "Animation.h"
 #include "AnimationTarget.h"
 #include "Game.h"
+#include "Quaternion.h"
 
 namespace gameplay
 {
 
 AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long startTime, unsigned long endTime)
-    : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _elapsedTime(0), _runningTime(0), 
-       _channelCount(animation->_channels.size()), _repeatCount(1.0f), _speed(1.0f), _isPlaying(false), _beginListeners(NULL), _endListeners(NULL)
+    : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _duration(_endTime - _startTime), _repeatCount(1.0f), 
+      _activeDuration(_duration * _repeatCount), _speed(1.0f), _isPlaying(false), _timeStarted(0), _elapsedTime(0), _runningTime(0), 
+      _channelPriority(NULL), _crossFadeToClip(NULL), _crossFadeStart(0), _crossFadeOutElapsed(0), _crossFadeOutDuration(0), _blendWeight(1.0f), 
+      _isFadingOutStarted(false), _isFadingOut(false), _isFadingIn(false), _beginListeners(NULL), _endListeners(NULL)
 {
     assert(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
-
-    _duration = (_endTime - _startTime);
-    _activeDuration = _duration * _repeatCount;
     
-    for (unsigned int i = 0; i < _channelCount; i++)
+    unsigned int channelCount = _animation->_channels.size();
+    _channelPriority = new unsigned int[channelCount];
+    
+    for (unsigned int i = 0; i < channelCount; i++)
     {
         _values.push_back(new AnimationValue(_animation->_channels[i]->_curve->getComponentCount()));
+        _channelPriority[i] = 0;
     }
 }
 
 AnimationClip::~AnimationClip()
 {
-    // Explicitly stop this clip if it's currently playing so it gets removed from the controller
-    if (_isPlaying)
-    {
-        stop();
-    }
-
     std::vector<AnimationValue*>::iterator valueIter = _values.begin();
     while (valueIter != _values.end())
     {
         SAFE_DELETE(*valueIter);
         valueIter++;
     }
+    _values.clear();
 
+    SAFE_RELEASE(_crossFadeToClip);
+    SAFE_DELETE(_channelPriority);
     SAFE_DELETE(_beginListeners);
     SAFE_DELETE(_endListeners);
 }
@@ -123,6 +120,16 @@ float AnimationClip::getSpeed() const
     return _speed;
 }
 
+void AnimationClip::setBlendWeight(float blendWeight)
+{
+    _blendWeight = blendWeight;
+}
+
+float AnimationClip::getBlendWeight() const
+{
+    return _blendWeight;
+}
+
 bool AnimationClip::isPlaying() const
 {
     return _isPlaying;
@@ -131,12 +138,52 @@ bool AnimationClip::isPlaying() const
 void AnimationClip::play()
 {
     _animation->_controller->schedule(this);
+    _timeStarted = Game::getGameTime();
 }
 
 void AnimationClip::stop()
 {
     _animation->_controller->unschedule(this);
-    _isPlaying = false;
+    if (_isPlaying)
+    {
+        _isPlaying = false;
+        onEnd();
+    }
+}
+
+void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
+{
+    assert(clip);
+
+    if (clip->_isPlaying && clip->_isFadingOut)
+    {
+        clip->_isFadingOut = false;
+        clip->_crossFadeToClip->_isFadingIn = false;
+        SAFE_RELEASE(clip->_crossFadeToClip);
+    }
+
+    // If I already have a clip I'm fading too.. release it.
+    if (_crossFadeToClip)
+        SAFE_RELEASE(_crossFadeToClip);
+
+    // Assign the clip we're fading to, and increase its ref count.
+    _crossFadeToClip = clip;
+    _crossFadeToClip->addRef();
+        
+    // Set the fade in clip to fading in, and set the duration of the fade in.
+    _crossFadeToClip->_isFadingIn = true;
+    
+    // Set this clip to fade out, and reset the elapsed time for the fade out.
+    _isFadingOut = true;
+    _crossFadeOutElapsed = 0;
+    _crossFadeOutDuration = duration;
+    _crossFadeStart = (Game::getGameTime() - _timeStarted);
+    _isFadingOutStarted = true;
+    
+    if (!_isPlaying)
+        play();
+
+    _crossFadeToClip->play(); 
 }
 
 void AnimationClip::addBeginListener(AnimationClip::Listener* listener)
@@ -157,12 +204,19 @@ void AnimationClip::addEndListener(AnimationClip::Listener* listener)
 
 bool AnimationClip::update(unsigned long elapsedTime)
 {
+    float speed = _speed;
     if (!_isPlaying)
+    {
         onBegin();
-
-    // Update elapsed time.
-    _elapsedTime += elapsedTime;
-    _runningTime += elapsedTime * _speed;
+        _elapsedTime = Game::getGameTime() - _timeStarted;
+        _runningTime = _elapsedTime * speed;
+    }
+    else
+    {
+        // Update elapsed time.
+        _elapsedTime += elapsedTime;
+        _runningTime += elapsedTime * speed;
+    }
 
     float percentComplete = 0.0f;
 
@@ -171,9 +225,15 @@ bool AnimationClip::update(unsigned long elapsedTime)
     {
         _isPlaying = false;
         if (_speed >= 0)
+        {
             percentComplete = _activeDuration % _duration; // Get's the fractional part of the final repeat.
+            if (percentComplete == 0.0f)
+                percentComplete = _duration;
+        }
         else
+        {
             percentComplete = 0.0f; // If we are negative speed, the end value should be 0.
+        }
     }
     else
     {
@@ -183,20 +243,236 @@ bool AnimationClip::update(unsigned long elapsedTime)
 
     // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
     percentComplete = (float)(_startTime + percentComplete) / (float) _animation->_duration;
+    
+    if (_isFadingOut)
+    {
+        if (_isFadingOutStarted) // Calculate elapsed time since the fade out begin.
+        {
+            _crossFadeOutElapsed = (_elapsedTime - _crossFadeStart) * speed;
+            _isFadingOutStarted = false;
+        }
+        else
+        {
+            // continue tracking elapsed time.
+            _crossFadeOutElapsed += elapsedTime * speed;
+        }
 
+        if (_crossFadeOutElapsed < _crossFadeOutDuration)
+        {
+            float tempBlendWeight = (float) (_crossFadeOutDuration - _crossFadeOutElapsed) / (float) _crossFadeOutDuration;
+            _crossFadeToClip->_blendWeight = (1.0f - tempBlendWeight);
+            
+            // adjust the clip your blending to's weight to be a percentage of your current blend weight
+            if (_isFadingIn)
+            {
+                _crossFadeToClip->_blendWeight *= _blendWeight;
+                _blendWeight -= _crossFadeToClip->_blendWeight;
+            }
+            else
+            {
+                _blendWeight = tempBlendWeight;
+            }
+        }
+        else
+        {   // Fade done.
+            _crossFadeToClip->_blendWeight = 1.0f;
+                
+            if (_isFadingIn)
+                _crossFadeToClip->_blendWeight *= _blendWeight;
+
+            _crossFadeToClip->_isFadingIn = false;
+            SAFE_RELEASE(_crossFadeToClip);
+            _blendWeight = 0.0f; 
+            _isFadingOut = false;
+            _isPlaying = false;
+        }
+    }
+    
     // Evaluate this clip.
     Animation::Channel* channel = NULL;
     AnimationValue* value = NULL;
-    for (unsigned int i = 0; i < _channelCount; i++)
+    AnimationTarget* target = NULL;
+    unsigned int channelCount = _animation->_channels.size();
+    for (unsigned int i = 0; i < channelCount; i++)
     {
         channel = _animation->_channels[i];
-        value = _values.at(i);
+        target = channel->_target;
+        value = _values[i];
+
+        // Get the current value.
+        target->getAnimationPropertyValue(channel->_propertyId, value);
+
+        bool isHighest = false;
+        // My channel priority has changed if my priority is greater than the active animation count.
+        if (!target->_highestPriority)
+        {
+            target->_highestPriority = channel;
+            value->_isFirstActing = true;
+        }
 
-        // Evaluate point on curve.
-        channel->_curve->evaluate(percentComplete, value->_currentValue);
+        if (_blendWeight != 0.0f)
+        {
+            // Evaluate point on Curve.
+            channel->_curve->evaluate(percentComplete, value->_interpolatedValue);
+
+            if (channel->_curve->_quaternionOffsetsCount == 0)
+            {
+                if (value->_isFirstActing)
+                {
+                    unsigned int componentCount = value->_componentCount;
+                    for (unsigned int j = 0; j < componentCount; j++)
+                    {
+                        if (_blendWeight != 1.0f)
+                            value->_interpolatedValue[j] *= _blendWeight;
+
+                        value->_currentValue[j] = value->_interpolatedValue[j];
+                    }
+                }
+                else
+                {
+                    unsigned int componentCount = value->_componentCount;
+                    for (unsigned int j = 0; j < componentCount; j++)
+                    {
+                        if (_blendWeight != 1.0f)
+                            value->_interpolatedValue[j] *= _blendWeight;
+
+                        value->_currentValue[j] += value->_interpolatedValue[j];
+                    }
+                }
+            }
+            else
+            {   //We have Quaternions!!!
+                unsigned int j = 0;
+                unsigned int quaternionOffsetIndex = 0;
+                unsigned int quaternionOffset = 0;
+
+                if (value->_isFirstActing)
+                {
+                    do {
+                        quaternionOffset = channel->_curve->_quaternionOffsets[quaternionOffsetIndex];
+                        while (j < quaternionOffset)
+                        {
+                            if (_blendWeight != 1.0f)
+                                value->_interpolatedValue[j] *= _blendWeight;
+
+                            value->_currentValue[j] = value->_interpolatedValue[j];
+                            j++;
+                        }
+
+                        // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
+
+                        Quaternion* interpolatedQuaternion = (Quaternion*) (value->_interpolatedValue + j);
+                        Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
+
+                        // If we have a blend weight, we apply it by slerping from the identity to our interpolated value at the given weight.
+                        if (_blendWeight != 1.0f)
+                            Quaternion::slerp(Quaternion::identity(), *interpolatedQuaternion, _blendWeight, interpolatedQuaternion);
+                    
+                        // Add in contribution.
+                        currentQuaternion->set(*interpolatedQuaternion);
+                    
+                        // Increase by 4.
+                        j += 4;
+                        quaternionOffsetIndex++;
+                    } while (quaternionOffsetIndex < channel->_curve->_quaternionOffsetsCount);
+
+                    unsigned int componentCount = value->_componentCount;
+                    // Handle remaining scalar values.
+                    while (j < componentCount)
+                    {
+                        if (_blendWeight != 1.0f)
+                            value->_interpolatedValue[j] *= _blendWeight;
+
+                        value->_currentValue[j] = value->_interpolatedValue[j];
+                        j++;
+                    }
+                }
+                else
+                {
+                    do {
+                        quaternionOffset = channel->_curve->_quaternionOffsets[quaternionOffsetIndex];
+                        while (j < quaternionOffset)
+                        {
+                            if (_blendWeight != 1.0f)
+                                value->_interpolatedValue[j] *= _blendWeight;
+
+                            value->_currentValue[j] += value->_interpolatedValue[j];
+                            j++;
+                        }
+
+                        // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
+
+                        Quaternion* interpolatedQuaternion = (Quaternion*) (value->_interpolatedValue + j);
+                        Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
+
+                        // If we have a blend weight, we apply it by slerping from the identity to our interpolated value at the given weight.
+                        if (_blendWeight != 1.0f)
+                            Quaternion::slerp(Quaternion::identity(), *interpolatedQuaternion, _blendWeight, interpolatedQuaternion);
+                    
+                        // Add in contribution.
+                        currentQuaternion->multiply(*interpolatedQuaternion);
+                    
+                        // Increase by 4.
+                        j += 4;
+                        quaternionOffsetIndex++;
+                    } while (quaternionOffsetIndex < channel->_curve->_quaternionOffsetsCount);
+
+                    unsigned int componentCount = value->_componentCount;
+                    // Handle remaining scalar values.
+                    while (j < componentCount)
+                    {
+                        if (_blendWeight != 1.0f)
+                            value->_interpolatedValue[j] *= _blendWeight;
+
+                        value->_currentValue[j] += value->_interpolatedValue[j];
+                        j++;
+                    }
+                }
+            }
+        }
+        else if (value->_isFirstActing)
+        {
+            if (channel->_curve->_quaternionOffsetsCount == 0)
+            {
+                memset(value->_currentValue, 0.0f, value->_componentCount);
+            }
+            else
+            {
+                unsigned int j = 0;
+                unsigned int quaternionOffset = 0;
+                unsigned int quaternionOffsetIndex = 0;
+                
+                do {
+                    quaternionOffset = channel->_curve->_quaternionOffsets[quaternionOffsetIndex];
+                    while (j < quaternionOffset)
+                    {
+                        value->_currentValue[j] = 0.0f;
+                        j++;
+                    }
+
+                    // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
+                    Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
+
+                    // Set it to identity.
+                    currentQuaternion->setIdentity();
+                    
+                    // Increase by 4.
+                    j += 4;
+                    quaternionOffsetIndex++;
+                } while (quaternionOffsetIndex < channel->_curve->_quaternionOffsetsCount);
+
+                unsigned int componentCount = value->_componentCount;
+                // Handle remaining scalar values.
+                while (j < componentCount)
+                {
+                    value->_currentValue[j] = 0.0f;
+                    j++;
+                }
+            }
+        }
         
         // Set the animation value on the target property.
-        channel->_target->setAnimationPropertyValue(channel->_propertyId, value);
+        target->setAnimationPropertyValue(channel->_propertyId, value);
     }
 
     // When ended. Probably should move to it's own method so we can call it when the clip is ended early.
@@ -223,6 +499,7 @@ void AnimationClip::onBegin()
         _runningTime = _activeDuration;
     }
 
+    // Notify begin listeners.. if any.
     if (_beginListeners)
     {
         std::vector<Listener*>::iterator listener = _beginListeners->begin();
@@ -236,6 +513,27 @@ void AnimationClip::onBegin()
 
 void AnimationClip::onEnd()
 {
+    AnimationValue* value;
+    Animation::Channel* channel = NULL;
+    AnimationTarget* target = NULL;
+    unsigned int channelCount = _animation->_channels.size();
+    for (unsigned int i = 0; i < channelCount; i++)
+    {
+        value = _values[i];
+
+        if (value->_isFirstActing)
+        {
+            channel = _animation->_channels[i];
+            target = channel->_target;
+            target->_highestPriority = NULL;
+            value->_isFirstActing = false;
+        }
+    }
+
+    _blendWeight = 1.0f;
+    _timeStarted = 0;
+
+    // Notify end listeners if any.
     if (_endListeners)
     {
         std::vector<Listener*>::iterator listener = _endListeners->begin();

+ 42 - 14
gameplay/src/AnimationClip.h

@@ -1,7 +1,3 @@
-/*
- * AnimationClip.h
- */
-
 #ifndef ANIMATIONCLIP_H_
 #define ANIMATIONCLIP_H_
 
@@ -55,7 +51,7 @@ public:
         };
 
         /**
-         * Handles when a transform has changed.
+         * Handles when animation event occurs.
          */
         virtual void animationEvent(AnimationClip* clip, EventType type) = 0;
     };
@@ -141,6 +137,20 @@ public:
      */
     float getSpeed() const;
 
+    /**
+     * Sets the blend weight of the AnimationClip.
+     *
+     * @param blendWeight The blend weight to apply to the clip.
+     */
+    void setBlendWeight(float blendWeight);
+
+    /** 
+     * Gets the blend weight of the AnimationClip.
+     *
+     * @return The blendweight of the AnimationClip.
+     */
+    float getBlendWeight() const;
+
     /**
      * Checks if the AnimationClip is playing.
      *
@@ -158,6 +168,14 @@ public:
      */
     void stop();
 
+    /**
+     * Fades this clip out, and the specified clip in over the given duration.
+     *
+     * @param clip The clip to fade into.
+     * @param duration The duration of the fade.
+     */
+    void crossFade(AnimationClip* clip, unsigned long duration);
+
     /**
      * Adds a animation begin listener.
      *
@@ -210,20 +228,30 @@ private:
     void onEnd();
 
     std::string _id;                          // AnimationClip ID.
-    Animation* _animation;                    // Animations that this clip plays in parallel.
+    Animation* _animation;                    // The Animation this clip is created from.
     unsigned long _startTime;                 // Start time of the clip.
     unsigned long _endTime;                   // End time of the clip.
-    unsigned long _elapsedTime;               // Time elapsed while the clip is running.
-    long _runningTime;                        // Keeps track of the Animation's relative time in respect to the active duration.
-    unsigned int _channelCount;               // The number of channels in the clip.
-    std::vector<AnimationValue*> _values;     // AnimationValue holder.
-    float _repeatCount;                       // The clip's repeat count.
-    float _speed;                             // The speed that the clip is playing. Default is 1.0. Negative goes in reverse.
     unsigned long _duration;                  // The total duration.
+    float _repeatCount;                       // The clip's repeat count.
     unsigned long _activeDuration;            // The active duration of the clip.
+    float _speed;                             // The speed that the clip is playing. Default is 1.0. Negative goes in reverse.
     bool _isPlaying;                          // A flag to indicate whether the clip is playing.
-    std::vector<Listener*>* _beginListeners;
-    std::vector<Listener*>* _endListeners;
+    unsigned long _timeStarted;               // The game time when this clip was actually started.
+    unsigned long _elapsedTime;               // Time elapsed while the clip is running.
+    long _runningTime;                        // Keeps track of the Animation's relative time in respect to the active duration.
+    unsigned int* _channelPriority;           // Keeps track of each channel's priority.
+    AnimationClip* _crossFadeToClip;          // The clip to cross fade to
+    unsigned long _crossFadeStart;            // The time at which the cross fade started.
+    unsigned long _crossFadeOutElapsed;       // The amount of time that has elapsed for the crossfade.
+    unsigned long _crossFadeOutDuration;      // The duration of the cross fade.
+    float _blendWeight;                       // The clip's blendweight
+    bool _isFadingOutStarted;                 // Flag to indicate if the cross fade started
+    bool _isFadingOut;                        // Flag to indicate if the clip is fading out
+    bool _isFadingIn;                         // Flag to indicate if the clip is fading in.
+    std::vector<AnimationValue*> _values;     // AnimationValue holder.
+    std::vector<Listener*>* _beginListeners;  // Collection of begin listeners on the clip
+    std::vector<Listener*>* _endListeners;    // Collection of end listeners on the clip
+
 };
 
 }

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä