Commits

TWO  committed 02192d4

Added more python bindings
Refractoring
Fixed bugs

  • Participants
  • Parent commits d906fdd

Comments (0)

Files changed (30)

File PolyMain/PolyMain.vcxproj

     <ClInclude Include="include\game\PolyComponentManager.h" />
     <ClInclude Include="include\game\PolyEntity.h" />
     <ClInclude Include="include\game\PolyEntityEvent.h" />
+    <ClInclude Include="include\game\PolyEntityManagerListener.h" />
     <ClInclude Include="include\game\PolyEntityLogic.h" />
     <ClInclude Include="include\game\PolyEntityManager.h" />
     <ClInclude Include="include\game\PolyEntityTemplate.h" />

File PolyMain/PolyMain.vcxproj.filters

     <ClInclude Include="include\game\PolyLevelManager.h">
       <Filter>game\level</Filter>
     </ClInclude>
+    <ClInclude Include="include\game\PolyEntityManagerListener.h">
+      <Filter>game\entity</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="include\PolyPrerequisites.cpp" />

File PolyMain/include/core/PolyEngine.cpp

 				pFunc();
 			}
 			else {
+				SystemUtil::showMessageBox("DLL Error", "Cannot find symbol dllStartPlugin in plugin '" + path + "'! DLL Corrupt?");
 				POLY_LOG_CRITICAL("Cannot find symbol dllStartPlugin in plugin '" << path << "'!");
 			}
 		}
 		else {
-			POLY_LOG_CRITICAL("Failed to load plugin '" << path << "'");
+			SystemUtil::showMessageBox("DLL Error", "Failed to load plugin '" + path + "'!");
+			POLY_LOG_CRITICAL("Failed to load plugin '" << path << "'!");
 		}
 	}
 

File PolyMain/include/game/PolyEntity.cpp

 	void Entity::addTag(const String& _tag) {
 		InternString tag(_tag);
 
-		msTags[mEID].insert(tag);
+		msTags[mID].insert(tag);
 		msAllTags.insert(tag);
 
 		EntitySet& entities = msEntitiesByTag[tag];
 	void Entity::removeTag(const String& _tag) {
 		InternString tag(_tag);
 
-		msTags[mEID].erase(tag);
+		msTags[mID].erase(tag);
 
 		EntitySet& entities = msEntitiesByTag[tag];
 		entities.erase(*this);
 		InternString tag(_tag);
 
 		TagSet::const_iterator itr;
-		itr = msTags[mEID].find(tag);
+		itr = msTags[mID].find(tag);
 
-		return itr != msTags[mEID].end();
+		return itr != msTags[mID].end();
 	}
 
 	const EntitySet& Entity::getForTag(const String& _tag) {
 	}
 
 	Component* Entity::getComponent(const String& familyName, bool _throw) const {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
+		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 		TypeNameComponentMap::const_iterator itr;
 
 		itr = components.find(InternString(familyName));
 	}
 
 	void Entity::createComponent(const String& typeName, const StringVariantMap& values) {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
+		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
 		POLY_ASSERT(isValid());
 
 		Component* newComponent = gEnv.componentMgr->createComponent(*this, typeName, values);
 		POLY_ASSERT(component);
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 
 		// Notify other components of this one
 		BOOST_FOREACH(TypeNameComponentMap::value_type pair, components)
 		POLY_ASSERT(isValid());
 		POLY_ASSERT(component->getEntity() == *this);
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 
 		// Notify other components of this one
 		BOOST_FOREACH(TypeNameComponentMap::value_type pair, components) {
 	void Entity::_destroyAllComponents() {
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 
 		TypeNameComponentMap::iterator itr;
 		for(itr = components.begin(); itr != components.end();) {

File PolyMain/include/game/PolyEntity.h

 		bool						isValid() const;
 
 		Level						getLevel() const;
-		void						_setID(EntityID eid);
 		EntityID					getID() const;
 
 		// Tags
 		template<typename ComponentType>
 		bool						hasComponent() const;
 		bool						hasComponent(const String& familyName) const;
+		bool						hasComponent(const InternString& familyName) const;
 
 		/** Get Component by family name.
 		*/
 		void						_destroyAllComponents();
 
 		// Type name
-		void						_setTypeName(const InternString& typeName);
 		const InternString&			getTypeName() const;
 
 		// Serialization
 		void						load(IStream& bs);
 
 	protected:
-		EntityID					mEID;
+		EntityID					mID;
 
 		static bool					msValid[(EntityID)-1];
 		static Level				msScene[(EntityID)-1];
 	};
 
 	inline Entity::Entity()
-	:	mEID(UNASSIGNED_ENTITY_ID) {
+	:	mID(UNASSIGNED_ENTITY_ID) {
 	}
 
 	inline Entity::Entity(const Entity& other)
-	:	mEID(other.mEID) {
+	:	mID(other.mID) {
 	}
 
 	inline Entity::operator bool() const {
 	}
 
 	inline Entity& Entity::operator =(const Entity& other) {
-		mEID = other.mEID;
+		mID = other.mID;
 		return *this;
 	}
 
 	inline bool Entity::operator ==(const Entity& other) const {
-		return msScene == other.msScene && mEID == other.mEID;
+		return msScene == other.msScene && mID == other.mID;
 	}
 
 	inline  bool Entity::operator <(const Entity& other) const {
-		return mEID < other.mEID;
+		return mID < other.mID;
 	}
 
 	inline bool Entity::isValid() const {
-		return mEID != UNASSIGNED_ENTITY_ID && msValid[mEID];
+		return mID != UNASSIGNED_ENTITY_ID && msValid[mID];
 	}
 
 	inline Level Entity::getLevel() const {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
-		return msScene[mEID];
-	}
-
-	inline void Entity::_setID(EntityID eid) {
-		mEID = eid;
+		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
+		return msScene[mID];
 	}
 
 	inline EntityID Entity::getID() const {
-		return mEID;
+		return mID;
 	}
 
 	inline const TagSet& Entity::getAllTags() {
 	bool Entity::hasComponent() const {
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 		TypeNameComponentMap::const_iterator itr;
 
 		const InternString& familyName = ComponentType::GetFamilyName();
 	}
 
 	inline bool Entity::hasComponent(const String& familyName) const {
+		return hasComponent(InternString(familyName));
+	}
+
+	inline bool Entity::hasComponent(const InternString& familyName) const {
 		POLY_ASSERT(isValid());
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 		TypeNameComponentMap::const_iterator itr;
 
 		itr = components.find(InternString(familyName));
 
 	template<typename ComponentType>
 	ComponentType* Entity::getComponent(bool _throw) const {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
+		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
 
-		TypeNameComponentMap& components = msComponentsByFamily[mEID];
+		TypeNameComponentMap& components = msComponentsByFamily[mID];
 		TypeNameComponentMap::const_iterator itr;
 
 		const InternString& familyName = ComponentType::GetFamilyName();
 	}
 
 	inline const Entity::TypeNameComponentMap&	Entity::getComponents() const {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
-		return msComponentsByFamily[mEID];
+		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
+		return msComponentsByFamily[mID];
 	}
 
-	inline void Entity::_setTypeName(const InternString& typeName) {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
-		msTypeName[mEID] = typeName;
-	}
 	inline const InternString& Entity::getTypeName() const {
-		POLY_ASSERT(mEID != UNASSIGNED_ENTITY_ID);
-		return msTypeName[mEID];
+		POLY_ASSERT(mID != UNASSIGNED_ENTITY_ID);
+		return msTypeName[mID];
 	}
 }
 

File PolyMain/include/game/PolyEntityLogic.cpp

 */
 
 #include "PolyPrerequisites.h"
-#include "core/PolyEngine.h"
-#include "game/PolyEntityManager.h"
 
 #include "PolyEntityLogic.h"
 
 
 namespace Poly {
-	EntityLogic::EntityLogic(const String& name)
-	:	mName(name) {
-	}
-
-	EntityLogic::~EntityLogic() {
-	}
+	// TODO delete file
 }

File PolyMain/include/game/PolyEntityLogic.h

 	class _PolyExport EntityLogic {
 	public:
 		/** Constructor
+		@param componentsOfInterest The Components this logic subscribes to. 
 		@param name Used for debug purposes.
 		*/
 								EntityLogic(const String& name="");
 		virtual					~EntityLogic();
 
 		const String&			getName() const;
-
-		/** Update all currently active Entities. Prefer updating an interest group to this.
-		*/
-		virtual void			updateEntities(const EntityList& entities) {}
-
-		void					getComponentTypesOfInterest(ComponentNameSet& typeNames) const;
+		const ComponentNameSet&	getComponentsOfInterest() const;
 
 		/** Update Entities with Component types of interest.
-		@param typeName The name of the Component type to be updated.
 		@param entities The entities containing the component type.
 		*/
-		virtual void			updateEntitiesOfInterest(const String& typeName, const EntityList& entities) {}
-
-		virtual void			entityTypeRegistered(const String& typeName) {}
+		virtual void			updateEntitiesOfInterest(const EntityVector& entities) {}
 
 	protected:
 		String					mName;
-		ComponentNameSet		mComponentTypesOfInterest;
+		ComponentNameSet		mComponentsOfInterest;
 	};
 
+	inline EntityLogic::EntityLogic(const String& name)
+	:	mName(name) {
+	}
+
+	inline EntityLogic::~EntityLogic() {
+	}
+
 	inline const String& EntityLogic::getName() const {
 		return mName;
 	}
 
-	inline void EntityLogic::getComponentTypesOfInterest(ComponentNameSet& typeNames) const {
-		typeNames = mComponentTypesOfInterest;
+	inline const ComponentNameSet& EntityLogic::getComponentsOfInterest() const {
+		return mComponentsOfInterest;
 	}
 }
 

File PolyMain/include/game/PolyEntityManager.cpp

 		Entity::msTypeName[id] = InternString(); 
 
 		Entity newEntity;
-		newEntity._setID(id);
+		newEntity.mID = id;
 
 		mEntitiesToBeAdded.push_back(newEntity);
 
 		if(!entity)
 			return;
 
-		EntityList::iterator itr, end = mEntities.end();
+		EntityVector::iterator itr, end = mEntities.end();
 		for(itr = mEntities.begin(); itr != end; ++itr) {
 			if(*itr == entity) {
 				mEntities.erase(itr);
 		}
 	}
 
+	void EntityManager::addListener(EntityManagerListenerPtr listener) {
+		mListener.push_back(listener);
+	}
+
 	void EntityManager::updateGameplay() {
 		Entity entity;
 
 
 		// Delete marked Entities
 		BOOST_FOREACH(entity, mEntitiesToBeRemoved) {
-			EntityList::iterator itr, end = mEntities.end();
+			EntityVector::iterator itr, end = mEntities.end();
 			for(itr = mEntities.begin(); itr != end; ++itr) {
 				if(*itr == entity) {
 					mEntities.erase(itr);
 
 		// Update
 		BOOST_FOREACH(EntityLogicPtr logic, mLogics) {
-			// TODO optimize this loop
+			// TODO cache this
 
-			logic->updateEntities(mEntities);
+			EntityVector entitiesOfInterest;
 
-			ComponentNameSet typeNames;
-			logic->getComponentTypesOfInterest(typeNames);
-
-			if(!typeNames.empty()) {
-				BOOST_FOREACH(InternString typeName, typeNames) {
-					const EntitySet& entities = Entity::getWithComponent(typeName);
-
-					logic->updateEntitiesOfInterest(typeName.get(), EntityList(entities.begin(), entities.end()));
+			BOOST_FOREACH(Entity entity, mEntities) {
+				bool interested = true;
+				BOOST_FOREACH(const InternString& name, logic->getComponentsOfInterest()) {
+					if(!entity.hasComponent(name)) {
+						interested = false;
+						break;
+					}
+				}
+				if(interested) {
+					entitiesOfInterest.push_back(entity);
 				}
 			}
+
+			logic->updateEntitiesOfInterest(entitiesOfInterest);
 		}
 	}
 
 	}
 
 	void EntityManager::fireEntityTypeRegistered(const String& typeName) {
-		BOOST_FOREACH(EntityLogicPtr logic, mLogics)
-			logic->entityTypeRegistered(typeName);
+		BOOST_FOREACH(EntityManagerListenerPtr listener, mListener)
+			listener->entityTypeRegistered(typeName);
 	}
 
 	Ogre::ScriptTranslator* EntityManager::getTranslator(const Ogre::AbstractNodePtr& node){

File PolyMain/include/game/PolyEntityManager.h

 
 #include "core/PolyEngineListener.h"
 #include "PolyEntity.h"
+#include "PolyEntityManagerListener.h"
 #include "PolyEntityTemplate.h"
 #include "PolyEntityTemplateTranslator.h"
 
 		void				destroyEntityImmediate(Entity entity);
 
 		Entity				getEntity(EntityID id) const;
-		EntityList&			getEntities();
-		const EntityList&	getEntities() const;
+		EntityVector&		getEntities();
+		const EntityVector&	getEntities() const;
 
 		// Helpers
 		void				getEntitiesInSphere(const Vector3& position, float radius, EntityVector& entities) const;
 
 		// EntityLogic
-		///
 		void				addEntityLogic(EntityLogicPtr logic);
 		void				removeEntityLogic(EntityLogicPtr logic);
 
+		// EntityManagerListener
+		void				addListener(EntityManagerListenerPtr listener);
+
 		// Implement EngineListener
 		virtual void		updateGameplay();
 
 		typedef map<InternString, EntityTemplate>::type TypeNameTemplateMap;
 		TypeNameTemplateMap	mTemplates;
 
-		EntityList			mEntities;
+		EntityVector		mEntities;
 		EntityList			mEntitiesToBeAdded;
 		EntitySet			mEntitiesToBeRemoved;
 
 		typedef vector<EntityLogicPtr>::type LogicContainer;
 		LogicContainer		mLogics;
 
+		typedef vector<EntityManagerListenerPtr>::type ListenerContainer;
+		ListenerContainer	mListener;
+
 		EntityID			allocateEntityID();
 		void				_destroyEntity(Entity entity);
 
 		void				fireEntityTypeRegistered(const String& typeName);
 	};
 
-	inline Entity EntityManager::getEntity(EntityID eid) const {
+	inline Entity EntityManager::getEntity(EntityID id) const {
 		Entity entity;
-		entity._setID(eid);
+		entity.mID = id;
 
 		return entity;
 	}
 
-	inline EntityList& EntityManager::getEntities() {
+	inline EntityVector& EntityManager::getEntities() {
 		return mEntities;
 	}
 
-	inline const EntityList& EntityManager::getEntities() const {
+	inline const EntityVector& EntityManager::getEntities() const {
 		return mEntities;
 	}
 

File PolyMain/include/game/PolyEntityManagerListener.h

+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    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 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#ifndef PolyEntityManagerListener_h
+#define PolyEntityManagerListener_h
+
+namespace Poly {
+	class IEntityManagerListener {
+	public:
+		virtual void entityTypeRegistered(const String& typeName) = 0;
+	};
+
+	typedef boost::shared_ptr<IEntityManagerListener> EntityManagerListenerPtr;
+}
+
+#endif

File PolyMain/include/game/PolyGame.h

 #include "PolyCameraComponent.h"
 #include "PolyLightComponent.h"
 #include "PolyBoxColliderComponent.h"
+#include "PolyMeshColliderComponent.h"
 #include "PolyPhysicsDynamicComponent.h"
 #include "PolyPhysicsStaticComponent.h"
 #include "PolyCharacterControllerComponent.h"

File PolyMain/include/game/PolyLevel.h

 
 		LevelID						getID() const;
 
-		Ogre::SceneManager*	getSceneMgr() const { POLY_ASSERT(isValid()); return msSceneMgr[mSID]; }
-		RenderDrawUtil*		getDraw2D() const { POLY_ASSERT(isValid()); return msDraw2D[mSID]; }
-		physx::PxScene*		getPhysics() const { POLY_ASSERT(isValid()); return msPhysics[mSID]; }
+		Ogre::SceneManager*			getSceneMgr() const { POLY_ASSERT(isValid()); return msSceneMgr[mID]; }
+		RenderDrawUtil*				getDraw2D() const { POLY_ASSERT(isValid()); return msDraw2D[mID]; }
+		physx::PxScene*				getPhysics() const { POLY_ASSERT(isValid()); return msPhysics[mID]; }
 
 	private:
-		LevelID						mSID;
+		LevelID						mID;
 
 		static Ogre::SceneManager*	msSceneMgr[(LevelID)-2];
 		static RenderDrawUtil*		msDraw2D[(LevelID)-2];
 	typedef vector<Level>::type LevelContainer;
 
 	inline Level::Level()
-	:	mSID(UNASSIGNED_SCENE_ID) {
+	:	mID(UNASSIGNED_SCENE_ID) {
 	}
 
 	inline Level::Level(const Level& other)
-	:	mSID(other.mSID) {
+	:	mID(other.mID) {
 	}
 
 	inline Level::operator bool() const {
 		return isValid();
 	}
 	inline bool Level::isValid() const {
-		return mSID != UNASSIGNED_SCENE_ID;
+		return mID != UNASSIGNED_SCENE_ID;
 	}
 
 	inline bool Level::operator==(const Level& other) const {
-		return mSID == other.mSID;
+		return mID == other.mID;
 	}
 
 	inline LevelID Level::getID() const {
-		return mSID;
+		return mID;
 	}
 }
 

File PolyMain/include/game/PolyLevelManager.cpp

 	Level LevelManager::createLevel(const String& name, LevelType sceneType) {
 		LevelID id = mNextFreeSceneID++;
 
-		POLY_LOG("Creating scene '" << name << "' (sid=" << (uint)id << ")");
+		POLY_LOG("Creating Level '" << name << "' (id=" << (uint)id << ")");
 
 		Level scene;
-		scene.mSID = id;
+		scene.mID = id;
 
 		mLevels.push_back(scene);
 		if(name != "")
 			return itr->second;
 
 		POLY_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
-			"Scene with name '" + name + "' not found!",
-			"SceneManager::getScene");
+			"Level with name '" + name + "' not found!",
+			"LevelManager::getLevel");
 	}
 
 	void LevelManager::destroyLevel(Level level) {

File PolyMain/include/game/PolyPhysicsEntityLogic.cpp

 namespace Poly {
 	PhysicsEntityLogic::PhysicsEntityLogic()
 	:	EntityLogic("Physics") {
-		mComponentTypesOfInterest.insert(InternString("Physics"));
+		mComponentsOfInterest.insert(InternString("Physics"));
 	}
 
-	void PhysicsEntityLogic::updateEntitiesOfInterest(const String& typeName, const EntityList& entities) {
+	void PhysicsEntityLogic::updateEntitiesOfInterest(const EntityVector& entities) {
 		BOOST_FOREACH(Entity entity, entities) {
 			TransformComponent* transformC = entity.getComponent<TransformComponent>();
 			

File PolyMain/include/game/PolyPhysicsEntityLogic.h

 	public:
 						PhysicsEntityLogic();
 
-		virtual void	updateEntitiesOfInterest(const String& typeName, const EntityList& entities);
+		virtual void	updateEntitiesOfInterest(const EntityVector& entities);
 	};
 }
 

File PolyMain/include/util/PolySystemUtil.cpp

 		// TODO support more platforms
 	}
 
+	SystemUtil::MessageBoxResult SystemUtil::showMessageBox(const String& caption, const String& text) throw() {
+		return showMessageBox(caption.c_str(), text.c_str());
+	}
+
 	SystemUtil::MessageBoxResult SystemUtil::handleException(const String& description) throw() {
 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
 		return showMessageBox("Exception", description.c_str());

File PolyMain/include/util/PolySystemUtil.h

 			MBR_IGNORE
 		};
 
+		/** Show a message box to the user.
+		*/
 		static MessageBoxResult	showMessageBox(const char* caption, const char* text) throw();
+		static MessageBoxResult	showMessageBox(const String& caption, const String& text) throw();
 
 		/** Show a message window to the user describing the error. May include a callstack
-			on support platforms.
+			on supported platforms.
 		*/
 		static MessageBoxResult	handleException(const String& description) throw();
 		static MessageBoxResult	handleException(const std::exception& e) throw();

File PolyPython/PolyPython.vcxproj

     <ClInclude Include="include\PolyPythonBindings.h" />
     <ClInclude Include="include\PolyPythonCoreBindings.h" />
     <ClInclude Include="include\PolyPythonGameBindings.h" />
+    <ClInclude Include="include\PolyPythonPhysicsBindings.h" />
     <ClInclude Include="include\PolyPythonPrerequisites.h" />
     <ClInclude Include="include\PolyPythonRenderBindings.h" />
   </ItemGroup>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
     </ClCompile>
+    <ClCompile Include="include\PolyPython.cpp" />
     <ClCompile Include="include\PolyPythonBindings.cpp" />
     <ClCompile Include="include\PolyPythonPrerequisites.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

File PolyPython/PolyPython.vcxproj.filters

     <ClCompile Include="include\converter\type_id.cpp">
       <Filter>python</Filter>
     </ClCompile>
+    <ClCompile Include="include\PolyPython.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="include\PolyPython.h" />
     <ClInclude Include="include\PolyPythonRenderBindings.h" />
     <ClInclude Include="include\PolyPythonGameBindings.h" />
     <ClInclude Include="include\PolyPythonCoreBindings.h" />
+    <ClInclude Include="include\PolyPythonPhysicsBindings.h" />
   </ItemGroup>
   <ItemGroup>
     <Filter Include="python">

File PolyPython/include/PolyPython.cpp

+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    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 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#include "PolyPythonPrerequisites.h"
+#include "PolyPythonBindings.h"
+
+#include "PolyPython.h"
+
+
+namespace Poly {
+	namespace Python {
+		bp::object main_module;
+		bp::object main_namespace;
+
+		void init() {
+			PyImport_AppendInittab("poly", &PyInit_poly);
+
+			Py_Initialize();
+			if(!Py_IsInitialized()) {
+				POLY_LOG_CRITICAL("Failed to initialize Python!");
+				return;
+			}
+
+			try {
+				main_module = bp::import("__main__");
+				main_namespace = main_module.attr("__dict__");
+
+				init_print(main_namespace);
+			}
+			catch(const bp::error_already_set&) {
+				_fetchError();
+			}
+
+			addNativeComponentType<TransformComponent>();
+			addNativeComponentType<AnimationComponent>();
+			addNativeComponentType<MeshComponent>();
+			addNativeComponentType<LightComponent>();
+			addNativeComponentType<CameraComponent>();
+			addNativeComponentType<PhysicsDynamicComponent>();
+			addNativeComponentType<PhysicsStaticComponent>();
+			addNativeComponentType<AudioListenerComponent>();
+			addNativeComponentType<BoxColliderComponent>();
+			addNativeComponentType<MeshColliderComponent>();
+		}
+
+		void runScript(const String& fileName) {
+			try {
+				POLY_LOG("Running script '" << fileName << "'");
+
+				Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(fileName);
+				String content = stream->getAsString();
+
+				bp::exec(content.c_str(), main_namespace, main_namespace);
+			}
+			catch(const bp::error_already_set&) {
+				_fetchError();
+			}
+		}
+
+		void _fetchError() {
+			PyObject* ptype, *pvalue, *ptraceback;
+			PyErr_Fetch( &ptype, &pvalue, &ptraceback );
+
+			//Extract error message
+			String strErrorMessage = bp::extract<String>( pvalue );
+
+			bp::handle<> hType( ptype );
+			bp::object extype( hType );
+
+			long lineno = 0;
+			String filename;
+			String funcname;
+
+			if(ptraceback) {
+				bp::handle<> hTraceback( ptraceback );
+				bp::object traceback( hTraceback );
+
+				lineno = bp::extract<long> (traceback.attr("tb_lineno"));
+				filename = bp::extract<String>(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));
+				funcname = bp::extract<String>(traceback.attr("tb_frame").attr("f_code").attr("co_name"));
+			}
+
+			String msg = "Error " + filename + "(" + StringConverter::toString( lineno ) + ") : " + strErrorMessage;
+
+			POLY_LOG_CRITICAL(msg);
+		}
+
+		bool isNativeComponentType(const String& str) {
+			NameConverterMap::const_iterator itr;
+			itr = gNativeComponentToPythonConverters.find(str);
+
+			return itr != gNativeComponentToPythonConverters.end();
+		}
+
+		bp::object convertNativeComponentToPython(const String& str, Component* component) {
+			NameConverterMap::const_iterator itr;
+			itr = gNativeComponentToPythonConverters.find(str);
+
+			if(itr != gNativeComponentToPythonConverters.end())
+				return itr->second->toPython(component);
+
+			return bp::object();
+		}
+	}
+}

File PolyPython/include/PolyPython.h

 
 #include "PolyPythonPrerequisites.h"
 
+namespace Poly {
+	namespace Python {
+		struct INativeComponentToPython {
+			virtual bp::object toPython(Component*) = 0;
+		};
+		typedef boost::shared_ptr<INativeComponentToPython> NativeComponentToPythonPtr;
+		template<typename T>
+		struct NativeComponentToPythonImpl : public INativeComponentToPython {
+			virtual bp::object toPython(Component* c) {
+				return bp::object(dynamic_cast<T*>(c));
+			}
+		};
+
+		typedef map<String, NativeComponentToPythonPtr>::type NameConverterMap;
+		static NameConverterMap gNativeComponentToPythonConverters;
+
+		_PolyPythonExport void init();
+		_PolyPythonExport void runScript(const String& fileName);
+		_PolyPythonExport void _fetchError();
+
+		/** Add a native component type which then can be accessed in python.
+		*/
+		template<typename T>
+		void addNativeComponentType() {
+			NativeComponentToPythonPtr converter(new NativeComponentToPythonImpl<T>());
+			gNativeComponentToPythonConverters.insert(std::make_pair(T::GetFamilyName(), converter));
+		}
+
+		bool isNativeComponentType(const String& str);
+		bp::object convertNativeComponentToPython(const String& str, Component* component);
+	}
+}
+
 #endif

File PolyPython/include/PolyPythonBindings.cpp

 #include "PolyPythonPrerequisites.h"
 #include "PolyPythonCoreBindings.h"
 #include "PolyPythonRenderBindings.h"
+#include "PolyPythonPhysicsBindings.h"
 #include "PolyPythonGameBindings.h"
 
 #include "PolyPythonBindings.h"
 	bindCore();
 	bindGame();
 	bindRender();
+	bindPhysics();
 
 	// Runtime environment
 	EntityManager* entityMgr =  gEnv.entityMgr.get();
 	bp::scope().attr("entityMgr") = boost::ref(entityMgr); 
+
+	GameStateManager* gameStateMgr = gEnv.gameStateMgr.get();
+	bp::scope().attr("gameStateMgr") = boost::ref(gameStateMgr); 
+
+	LevelManager* levelMgr = gEnv.levelMgr.get();
+	bp::scope().attr("levelMgr") = boost::ref(levelMgr); 
+
+	PhysicsSystem* physics =  gEnv.physics.get();
+	bp::scope().attr("physics") = boost::ref(physics); 
 }
 
 void init_print(bp::object mainNamespace) {

File PolyPython/include/PolyPythonCoreBindings.h

 	bp::def("_log_hook", &logDefault);
 	bp::def("_log_error_hook", &logError);
 
+	bp::class_<Radian>("Radian");
+
+	bp::class_<Ray>("Ray", bp::init<>())
+		.add_property("origin",
+			bp::make_function(&Ray::getOrigin, bp::return_value_policy<bp::copy_const_reference>()),
+			&Ray::setOrigin)
+		.add_property("direction",
+			bp::make_function(&Ray::getDirection, bp::return_value_policy<bp::copy_const_reference>()),
+			&Ray::setDirection)
+		
+		.def(bp::init<const Vector3&, const Vector3&>())
+		;
+
 	bp::object v3 = bp::class_<Vector3>("Vector3", bp::init<>())
 		.def_readwrite("x", &Vector3::x)
 		.def_readwrite("y", &Vector3::y)
 
 		.def("length", &Vector3::length)
 		;
+	v3.attr("ZERO") = boost::ref(Vector3::ZERO);
+	v3.attr("UNIT_X") = boost::ref(Vector3::UNIT_X);
+	v3.attr("UNIT_Y") = boost::ref(Vector3::UNIT_Y);
+	v3.attr("UNIT_Z") = boost::ref(Vector3::UNIT_Z);
+	v3.attr("NEGATIVE_UNIT_X") = boost::ref(Vector3::NEGATIVE_UNIT_X);
+	v3.attr("NEGATIVE_UNIT_Y") = boost::ref(Vector3::NEGATIVE_UNIT_Y);
+	v3.attr("NEGATIVE_UNIT_Z") = boost::ref(Vector3::NEGATIVE_UNIT_Z);
 
-	v3.attr("ZERO") = boost::ref(Vector3::ZERO);
+	bp::object q = bp::class_<Quaternion>("Quaternion", bp::init<>())
+		.def_readwrite("w", &Quaternion::w)
+		.def_readwrite("x", &Quaternion::x)
+		.def_readwrite("y", &Quaternion::y)
+		.def_readwrite("z", &Quaternion::z)
+
+		.def(bp::init<const Quaternion&>())
+		.def(bp::init<const Radian&, const Vector3&>())
+
+		.def("xAxis", &Quaternion::xAxis)
+		.def("yAxis", &Quaternion::yAxis)
+		.def("zAxis", &Quaternion::zAxis)
+
+		.def(bp::self + Quaternion())
+		.def(bp::self - Quaternion())
+		.def(bp::self * Quaternion())
+		.def(bp::self * float())
+
+		.def("Dot", &Quaternion::Dot)
+		.def("normalise", &Quaternion::normalise)
+		.def("Inverse", &Quaternion::Inverse)
+		;
+	q.attr("ZERO") = boost::ref(Quaternion::ZERO);
+	q.attr("IDENTITY") = boost::ref(Quaternion::IDENTITY);
 }
 
 #endif

File PolyPython/include/PolyPythonGameBindings.h

 #ifndef PolyPythonGameBindings_h
 #define PolyPythonGameBindings_h
 
+#include "PolyPython.h"
+
+
 class PythonEntityLogic : public EntityLogic {
 public:
 	PythonEntityLogic(PyObject* p)
-		:	mSelf(p) {}
+	:	mSelf(p) {}
 	PythonEntityLogic(PyObject* p, const EntityLogic& self)
-		:	mSelf(p), EntityLogic(self) {}
+	:	mSelf(p), EntityLogic(self) {}
 
-	virtual void updateEntities(const EntityList& entities) {
+	virtual void updateEntitiesOfInterest(const EntityVector& entities) {
 		try {
-			bp::call_method<void>(mSelf, "updateEntities", entities);
+			bp::call_method<void>(mSelf, "updateEntitiesOfInterest", entities);
 		}
 		catch(const bp::error_already_set&) {
 			Poly::Python::_fetchError();
 		}
 	}
-	static void updateEntitiesDefault(EntityLogic& self, const EntityList& entities) {
-		self.EntityLogic::updateEntities(entities);
+	static void updateEntitiesOfInterestDefault(EntityLogic& self, const EntityVector& entities) {
+		self.EntityLogic::updateEntitiesOfInterest(entities);
 	}
 
-	virtual void updateEntitiesOfInterest(const String& typeName, const EntityList& entities) {
-		try {
-			bp::call_method<void>(mSelf, "updateEntitiesOfInterest", typeName, entities);
-		}
-		catch(const bp::error_already_set&) {
-			Poly::Python::_fetchError();
-		}
+	ComponentNameSet& getComponentsOfInterest() {
+		return mComponentsOfInterest;
 	}
-	static void updateEntitiesOfInterestDefault(EntityLogic& self, const String& typeName, const EntityList& entities) {
-		self.EntityLogic::updateEntitiesOfInterest(typeName, entities);
-	}
-
-	ComponentNameSet& getComponentTypesOfInterest() {
-		return mComponentTypesOfInterest;
-	}
-	void setComponentTypesOfInterest(ComponentNameSet& set) {
-		mComponentTypesOfInterest = set;
+	void setComponentsOfInterest(ComponentNameSet& set) {
+		mComponentsOfInterest = set;
 	}
 
 private:
 	PyObject* mSelf;
 };
 
-class PythonComponent : public Component {
+class PythonGameState : public GameState {
 public:
-	POLY_COMPONENT_BASE;
+	PythonGameState(PyObject* p)
+	:	mSelf(p), GameState("Python") {}
+	PythonGameState(PyObject* p, const GameState& self)
+	:	mSelf(p), GameState(self) {}
+
+	virtual void startup() {
+		try {
+			bp::call_method<void>(mSelf, "startup");
+		}
+		catch(const bp::error_already_set&) {
+			Poly::Python::_fetchError();
+		}
+	}
+	static void startupDefault(GameState& self) {
+		self.GameState::startup();
+	}
+
+private:
+	PyObject* mSelf;
 };
 
-POLY_COMPONENT_BASE_IMPL(PythonComponent, "Python", "Python");
-
-bp::object Entity_GetComponent(Entity& self, bp::object componentType) {
-	String typeName = bp::extract<String>(componentType.attr("__name__"));
-	
+bp::object Entity_GetComponent(Entity& self, const String& typeName) {
 	bp::object ret;
 
-	if(typeName == TransformComponent::GetFamilyName()) {
-		ret = bp::object(self.getComponent<TransformComponent>());
+	if(Poly::Python::isNativeComponentType(typeName)) {
+		Component* component = self.getComponent(typeName);
+
+		return Poly::Python::convertNativeComponentToPython(typeName, component);
 	}
 	else {
-		// Try to convert to PythonComponent
-		PythonComponent* component = dynamic_cast<PythonComponent*>(self.getComponent(typeName));
+		// TODO
 
-		if(component)
-			ret = bp::object(component);
+		return bp::object();
 	}
+}
 
-	return ret;
+bp::object Entity_GetComponent_2(Entity& self, bp::object componentType) {
+	String typeName = bp::extract<String>(componentType.attr("__name__"));
+
+	return Entity_GetComponent(self, typeName);
 }
 
 void ComponentNameSet_add(ComponentNameSet& self, const String& str) {
 	self.insert(InternString(str));
 }
 
+Level LevelManager_createLevel(LevelManager& self) {
+	return self.createLevel();
+}
+
+Entity EntityManager_createEntity(EntityManager& self, Level level, const String& typeName) {
+	StringVariantMap _props;
+
+	return self.createEntity(level, typeName, _props);
+}
+
 void bindGame() {
+	bp::class_<Level>("Level", bp::no_init);
+
+	bp::class_<LevelManager, boost::noncopyable>("LevelManager", bp::no_init)
+		.def("createLevel", &LevelManager_createLevel);
+
+	// Component
 	bp::class_<Component, boost::noncopyable>("Component", bp::no_init);
 
 	bp::class_<TransformComponent, bp::bases<Component>>("Transform")
 		.add_property("sceneNode", bp::make_getter(&TransformComponent::sceneNode, bp::return_internal_reference<>()));
 
-	bp::class_<Entity>("Entity")
-		.def("getComponent", &Entity_GetComponent);
+	// Entity
+	bp::class_<Entity>("Entity", bp::no_init)
+		.add_property("level", &Entity::getLevel)
+
+		.def("getComponent", &Entity_GetComponent)
+		.def("getComponent", &Entity_GetComponent_2);
 
 	bp::class_<EntityList>("EntityList")
 		.def("__iter__", bp::iterator<EntityList>())
 		.def("add", &ComponentNameSet_add);
 
 	bp::class_<EntityLogic, PythonEntityLogic, EntityLogicPtr>("EntityLogic")
-		.def("updateEntities", &PythonEntityLogic::updateEntitiesDefault)
 		.def("updateEntitiesOfInterest", &PythonEntityLogic::updateEntitiesOfInterestDefault)
 
-		.add_property("componentTypesOfInterest",
-			bp::make_function(&PythonEntityLogic::getComponentTypesOfInterest, bp::return_value_policy<bp::reference_existing_object>()),
-			&PythonEntityLogic::setComponentTypesOfInterest)
+		.add_property("componentsOfInterest",
+			bp::make_function(&PythonEntityLogic::getComponentsOfInterest, bp::return_value_policy<bp::reference_existing_object>()),
+			&PythonEntityLogic::setComponentsOfInterest)
 		;
 
-	bp::class_<EntityManager, boost::noncopyable>("EntityManager")
-		.def("addEntityLogic", &EntityManager::addEntityLogic);
+	bp::class_<EntityManager, boost::noncopyable>("EntityManager", bp::no_init)
+		.def("addEntityLogic", &EntityManager::addEntityLogic)
+		
+		.def("createEntity", &EntityManager_createEntity);
+
+	// GameState
+ 	bp::class_<GameState, PythonGameState, GameStatePtr>("GameState")
+		.def("startup", &PythonGameState::startupDefault);
+ 
+ 	bp::class_<GameStateManager, boost::noncopyable>("GameStateManager", bp::no_init)
+ 		.def("pushGameState", &GameStateManager::pushGameState);
 }
 
 #endif

File PolyPython/include/PolyPythonPhysicsBindings.h

+/*
+    Copyright (c) Oliver 'SirPolly' Weitzel
+                                                                                  
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+                                                                                  
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+                                                                                  
+    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 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE. 
+    
+*/
+
+#ifndef PolyPythonPhysicsBindings_h
+#define PolyPythonPhysicsBindings_h
+
+void bindPhysics() {
+	bp::class_<PhysicsRaycastHit>("PhysicsRaycastHit", bp::init<>())
+		.def_readwrite("result", &PhysicsRaycastHit::result)
+		.def_readwrite("distance", &PhysicsRaycastHit::distance)
+		.def_readwrite("impact", &PhysicsRaycastHit::impact)
+		.def_readwrite("normal", &PhysicsRaycastHit::normal)
+		.def_readwrite("entity", &PhysicsRaycastHit::entity)
+
+		.def(bp::init<const PhysicsRaycastHit&>())
+		;
+
+	bp::class_<PhysicsSystem, boost::noncopyable>("PhysicsSystem", bp::no_init)
+		.def("raycastSingle", (PhysicsRaycastHit(PhysicsSystem::*)(Level,const Ray&,float))&PhysicsSystem::raycastSingle)
+		;
+}
+
+#endif

File PolyPython/include/PolyPythonPrerequisites.cpp

 */
 
 #include "PolyPythonPrerequisites.h"
-#include "PolyPythonBindings.h"
-
-
-namespace Poly {
-	namespace Python {
-		bp::object main_module;
-		bp::object main_namespace;
-
-		void init() {
-			PyImport_AppendInittab("poly", &PyInit_poly);
-
-			Py_Initialize();
-			if(!Py_IsInitialized()) {
-				POLY_LOG_CRITICAL("Failed to initialize Python!");
-				return;
-			}
-
-			try {
-				main_module = bp::import("__main__");
-				main_namespace = main_module.attr("__dict__");
-				
-				init_print(main_namespace);
-			}
-			catch(const bp::error_already_set&) {
-				_fetchError();
-			}
-		}
-
-		void runScript(const String& fileName) {
-			try {
-				POLY_LOG("Running script '" << fileName << "'");
-
-				Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(fileName);
-				String content = stream->getAsString();
-
-				bp::exec(content.c_str(), main_namespace, main_namespace);
-			}
-			catch(const bp::error_already_set&) {
-				_fetchError();
-			}
-		}
-
-		void _fetchError() {
-			PyObject* ptype, *pvalue, *ptraceback;
-			PyErr_Fetch( &ptype, &pvalue, &ptraceback );
-
-			//Extract error message
-			String strErrorMessage = bp::extract<String>( pvalue );
-
-			bp::handle<> hType( ptype );
-			bp::object extype( hType );
-
-			long lineno = 0;
-			String filename;
-			String funcname;
-
-			if(ptraceback) {
-				bp::handle<> hTraceback( ptraceback );
-				bp::object traceback( hTraceback );
-
-				lineno = bp::extract<long> (traceback.attr("tb_lineno"));
-				filename = bp::extract<String>(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));
-				funcname = bp::extract<String>(traceback.attr("tb_frame").attr("f_code").attr("co_name"));
-			}
-
-			String msg = "Error " + filename + "(" + StringConverter::toString( lineno ) + ") : " + strErrorMessage;
-
-			POLY_LOG_CRITICAL(msg);
-		}
-	}
-}

File PolyPython/include/PolyPythonPrerequisites.h

 #include "Poly.h"
 using namespace Poly;
 
-// Note: Needs stackless Python 3.2! Only the headers, source files are included in this project.
+// Note: Needs stackless Python 3.2! Source files are included in this project.
 #include <boost/python.hpp>
 namespace bp = boost::python;
 
 #	define _PolyPythonExport
 #endif
 
-namespace Poly {
-	namespace Python {
-		_PolyPythonExport void init();
-		_PolyPythonExport void runScript(const String& fileName);
-		_PolyPythonExport void _fetchError();
-	}
-}
-
 #endif

File PolyPython/include/PolyPythonRenderBindings.h

 #define PolyPythonRenderBindings_h
 
 void bindRender() {
-	bp::class_<Ogre::Node, boost::noncopyable>("Node", bp::no_init)
+	bp::object node = bp::class_<Ogre::Node, boost::noncopyable>("Node", bp::no_init)
 		.add_property("position",
 			bp::make_function(&Ogre::Node::getPosition, bp::return_value_policy<bp::copy_const_reference>()),
-			(void(Ogre::Node::*)(const Vector3&))&Ogre::Node::setPosition);
+			(void(Ogre::Node::*)(const Vector3&))&Ogre::Node::setPosition)
+		.add_property("orientation",
+			bp::make_function(&Ogre::Node::getOrientation, bp::return_value_policy<bp::copy_const_reference>()),
+			(void(Ogre::Node::*)(const Quaternion&))&Ogre::Node::setOrientation)
+
+		.def("yaw", &Ogre::Node::yaw)
+		.def("pitch", &Ogre::Node::pitch)
+		.def("roll", &Ogre::Node::roll)
+
+		//.def("translate", (void(Ogre::Node::*)(const Vector3&))&Ogre::Node::translate)
+		.def("translate", (void(Ogre::Node::*)(const Vector3&, Ogre::Node::TransformSpace))&Ogre::Node::translate)
+		;
+
+	{
+		bp::scope s(node);
+
+		bp::enum_<Ogre::Node::TransformSpace>("TransformSpace")
+			.value("TS_LOCAL", Ogre::Node::TS_LOCAL)
+			.value("TS_PARENT", Ogre::Node::TS_PARENT)
+			.value("TS_WORLD", Ogre::Node::TS_WORLD)
+			;
+	}
 
 	bp::class_<Ogre::SceneNode, bp::bases<Ogre::Node>, boost::noncopyable>("SceneNode", bp::no_init);
 }
 
 - Multithread engine
-- Reimplement debug drawing (DONE)
-- Reimplement raycast entity result (DONE)
 
 - Implement 2D drawing
 - Implement unique GUID for entities in addition to the runtime ID
 
 - REMOVE DEPENDENCIES WHICH ARE TOO BIG (most of boost)
 
-- Remove all remains of scripting
 - Implement entity template parent/child relations!
 
 - Make the StringVariant map faster (remove boost variant, build own value holder. Should not be that hard)
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PolyPython", "PolyPython\PolyPython.vcxproj", "{5C7D060D-DEF2-4EFF-B694-DB083CC9804C}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PolyHammer", "PolyHammer\PolyHammer.vcxproj", "{A932B06F-69C7-4150-B005-E3C2FAFB47B7}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
 		{5C7D060D-DEF2-4EFF-B694-DB083CC9804C}.Debug|Win32.Build.0 = Debug|Win32
 		{5C7D060D-DEF2-4EFF-B694-DB083CC9804C}.Release|Win32.ActiveCfg = Release|Win32
 		{5C7D060D-DEF2-4EFF-B694-DB083CC9804C}.Release|Win32.Build.0 = Release|Win32
+		{A932B06F-69C7-4150-B005-E3C2FAFB47B7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A932B06F-69C7-4150-B005-E3C2FAFB47B7}.Debug|Win32.Build.0 = Debug|Win32
+		{A932B06F-69C7-4150-B005-E3C2FAFB47B7}.Release|Win32.ActiveCfg = Release|Win32
+		{A932B06F-69C7-4150-B005-E3C2FAFB47B7}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE