Browse Source

Model WIP

Panagiotis Christopoulos Charitos 15 years ago
parent
commit
c4b6579410

+ 18 - 6
build/debug/Makefile

@@ -218,9 +218,7 @@ Main.o: ../../src/Main.cpp ../../src/Input/Input.h \
  ../../src/Physics/BtAndAnkiConvertors.h ../../src/Physics/DebugDrawer.h \
  ../../extern/include/bullet/LinearMath/btIDebugDraw.h \
  ../../src/Util/Scanner.h ../../src/Misc/map.h \
- ../../src/Resources/SkelAnim.h \
- ../../src/Scene/Controllers/MeshSkelNodeCtrl.h \
- ../../src/Scene/Controllers/Controller.h ../../src/Misc/Parser.h \
+ ../../src/Resources/SkelAnim.h ../../src/Misc/Parser.h \
  ../../src/Misc/Parser.inl.h ../../src/Misc/Parser.h \
  ../../src/Scene/ParticleEmitter.h ../../src/Scene/GhostNode.h \
  ../../src/Resources/ParticleEmitterProps.h \
@@ -2764,7 +2762,9 @@ Model.o: ../../src/Resources/Model.cpp ../../src/Resources/Model.h \
  ../../src/Math/Transform.inl.h ../../src/Resources/ShaderProg.h \
  ../../extern/include/GL/glew.h ../../src/Util/CharPtrHashMap.h \
  ../../src/Resources/Texture.h ../../src/Resources/Mesh.h \
- ../../src/Resources/SkelAnim.h ../../src/Resources/Helpers/MeshData.h
+ ../../src/Resources/SkelAnim.h ../../src/Resources/Helpers/MeshData.h \
+ ../../src/Renderer/BufferObjects/Vao.h ../../src/Resources/ShaderProg.h \
+ ../../src/Misc/GlException.h ../../src/Resources/Skeleton.h
 	@echo Compiling ../../src/Resources/Model.cpp...
 	@$(CXX) $(INCPATH) $(CFLAGS) ../../src/Resources/Model.cpp -o Model.o
 
@@ -3921,7 +3921,9 @@ ModelNode.o: ../../src/Scene/ModelNode.cpp ../../src/Scene/ModelNode.h \
  ../../src/Math/MathFuncs.inl.h ../../src/Math/Transform.h \
  ../../src/Math/Transform.inl.h ../../src/Util/Exception.h \
  ../../src/Core/Object.h ../../src/Util/Properties.h \
- ../../src/Resources/Core/RsrcPtr.h
+ ../../src/Resources/Core/RsrcPtr.h ../../src/Resources/Model.h \
+ ../../src/Resources/Core/Resource.h ../../src/Util/Util.h \
+ ../../src/Util/Vec.h ../../src/Util/StdTypes.h
 	@echo Compiling ../../src/Scene/ModelNode.cpp...
 	@$(CXX) $(INCPATH) $(CFLAGS) ../../src/Scene/ModelNode.cpp -o ModelNode.o
 
@@ -4169,7 +4171,17 @@ SkelAnimModelNodeCtrl.o: \
  ../../extern/include/SDL/SDL_revision.h \
  ../../extern/include/SDL/SDL_compat.h ../../src/Core/Object.h \
  ../../src/Core/MessageHandler.h ../../src/Scene/ModelNode.h \
- ../../src/Scene/SceneNode.h ../../src/Core/Object.h
+ ../../src/Scene/SceneNode.h ../../src/Core/Object.h \
+ ../../src/Resources/Model.h ../../src/Renderer/MainRenderer.h \
+ ../../src/Renderer/Renderer.h ../../src/Renderer/BufferObjects/Fbo.h \
+ ../../extern/include/GL/glew.h ../../src/Resources/Texture.h \
+ ../../src/Resources/ShaderProg.h ../../src/Util/CharPtrHashMap.h \
+ ../../src/Renderer/BufferObjects/Vbo.h \
+ ../../src/Renderer/BufferObjects/BufferObject.h \
+ ../../src/Renderer/BufferObjects/Vao.h ../../src/Misc/GlException.h \
+ ../../src/Renderer/Ms.h ../../src/Renderer/RenderingPass.h \
+ ../../src/Renderer/Is.h ../../src/Renderer/Pps.h ../../src/Renderer/Bs.h \
+ ../../src/Renderer/Dbg.h
 	@echo Compiling ../../src/Scene/Controllers/SkelAnimModelNodeCtrl.cpp...
 	@$(CXX) $(INCPATH) $(CFLAGS) ../../src/Scene/Controllers/SkelAnimModelNodeCtrl.cpp -o SkelAnimModelNodeCtrl.o
 

+ 11 - 12
src/Main.cpp

@@ -19,7 +19,6 @@
 #include "skybox.h"
 #include "map.h"
 #include "SkelAnim.h"
-#include "MeshSkelNodeCtrl.h"
 #include "LightData.h"
 #include "Parser.h"
 #include "ParticleEmitter.h"
@@ -35,8 +34,8 @@
 #include "Messaging.h"
 
 // map (hard coded)
-MeshNode* floor__,* sarge,* horse,* crate;
-SkelModelNode* imp;
+//MeshNode* floor__,* sarge,* horse,* crate;
+//SkelModelNode* imp;
 PointLight* point_lights[10];
 SpotLight* spot_lights[2];
 ParticleEmitter* partEmitter;
@@ -161,10 +160,10 @@ void init()
 	app->getScene().skybox.load(skybox_fnames);*/
 
 	// horse
-	horse = new MeshNode();
-	horse->init("meshes/horse/horse.mesh");
+	//horse = new MeshNode();
+	//horse->init("meshes/horse/horse.mesh");
 	//horse->init("models/head/head.mesh");
-	horse->setLocalTransform(Transform(Vec3(-2, 0, 1), Mat3::getIdentity(), 1.0));
+	//horse->setLocalTransform(Transform(Vec3(-2, 0, 1), Mat3::getIdentity(), 1.0));
 
 	return;
 
@@ -180,12 +179,12 @@ void init()
 	floor__->setLocalTransform(Transform(Vec3(0.0, -0.19, 0.0), Mat3(Euler(-M::PI/2, 0.0, 0.0)), 0.8));*/
 
 	// imp	
-	imp = new SkelModelNode();
+	/*imp = new SkelModelNode();
 	imp->init("models/imp/imp.smdl");
 	//imp->setLocalTransform(Transform(Vec3(0.0, 2.11, 0.0), Mat3(Euler(-M::PI/2, 0.0, 0.0)), 0.7));
 	SkelAnimCtrl* ctrl = new SkelAnimCtrl(*imp->meshNodes[0]->meshSkelCtrl->skelNode);
 	ctrl->skelAnim.loadRsrc("models/imp/walk.imp.anim");
-	ctrl->step = 0.8;
+	ctrl->step = 0.8;*/
 
 	// cave map
 	/*for(int i=1; i<21; i++)
@@ -196,14 +195,14 @@ void init()
 	}*/
 
 	// sponza map
-	MeshNode* node = new MeshNode();
+	/*MeshNode* node = new MeshNode();
 	node->init("maps/sponza/floor.mesh");
 	node = new MeshNode();
 	node->init("maps/sponza/walls.mesh");
 	node = new MeshNode();
 	node->init("maps/sponza/light-marbles.mesh");
 	node = new MeshNode();
-	node->init("maps/sponza/dark-marbles.mesh");
+	node->init("maps/sponza/dark-marbles.mesh");*/
 	//node->setLocalTransform(Transform(Vec3(0.0, -0.0, 0.0), Mat3::getIdentity(), 0.01));
 
 	return;
@@ -214,10 +213,10 @@ void init()
 	partEmitter->getLocalTransform().origin = Vec3(3.0, 0.0, 0.0);
 
 	// character
-	PhyCharacter::Initializer init;
+	/*PhyCharacter::Initializer init;
 	init.sceneNode = imp;
 	init.startTrf = Transform(Vec3(0, 40, 0), Mat3::getIdentity(), 1.0);
-	character = new PhyCharacter(app->getScene().getPhysics(), init);
+	character = new PhyCharacter(app->getScene().getPhysics(), init);*/
 
 	// crate
 	/*crate = new MeshNode;

+ 3 - 2
src/Renderer/Dbg.cpp

@@ -242,7 +242,8 @@ void Dbg::run()
 	sProg->bind();
 
 	//R::renderGrid();
-	for(uint i=0; i<app->getScene().nodes.size(); i++)
+	/// @todo Uncomment
+	/*for(uint i=0; i<app->getScene().nodes.size(); i++)
 	{
 		SceneNode* node = app->getScene().nodes[i];
 		if
@@ -261,7 +262,7 @@ void Dbg::run()
 			skelNode->render();
 			glEnable(GL_DEPTH_TEST);
 		}
-	}
+	}*/
 
 	// Physics
 	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

+ 12 - 12
src/Renderer/Renderer.cpp

@@ -6,6 +6,8 @@
 #include "Scene.h"
 #include "Exception.h"
 #include "ModelNode.h"
+#include "Model.h"
+#include "Mesh.h"
 
 
 //======================================================================================================================
@@ -93,7 +95,7 @@ void Renderer::drawQuad()
 //======================================================================================================================
 // setupMaterial                                                                                                       =
 //======================================================================================================================
-void Renderer::setupMaterial(const Material& mtl, const SceneNode& sceneNode, const Camera& cam)
+void Renderer::setupMaterial(const Material& mtl, const SceneNode& sceneNode, const Camera& cam) const
 {
 	mtl.getShaderProg().bind();
 	uint textureUnit = 0;
@@ -284,28 +286,26 @@ void Renderer::setupMaterial(const Material& mtl, const SceneNode& sceneNode, co
 //======================================================================================================================
 void Renderer::renderModelNode(const ModelNode& modelNode, const Camera& cam, ModelNodeRenderType type) const
 {
-	const Material* mtl;
-	const Vao* vao;
-
 	for(uint i = 0; i < modelNode.getModel().getSubModels().size(); i++)
 	{
-		Model::SubModel& subModel = modelNode.getModel().getSubModels()[i];
+		const Model::SubModel& subModel = modelNode.getModel().getSubModels()[i];
 
 		const Material* mtl;
 		const Vao* vao;
 		if(type == MNRT_NORMAL)
 		{
-			mtl = subModel.getMaterial();
-			vao = subModel.getVao();
+			mtl = &subModel.getMaterial();
+			vao = &subModel.getVao();
 		}
 		else
 		{
-			mtl = subModel.getDpMaterial();
-			vao = subModel.getDpVao();
+			mtl = &subModel.getDpMaterial();
+			vao = &subModel.getDpVao();
 		}
 
 		// Material
-		setupMaterial(*mtl, modelNode, cam);
+		const SceneNode* sceneNode = &modelNode;
+		setupMaterial(*mtl, *sceneNode, cam);
 
 		// Render
 		if(modelNode.hasSkeleton())
@@ -316,8 +316,8 @@ void Renderer::renderModelNode(const ModelNode& modelNode, const Camera& cam, Mo
 			mtl->getStdUniVar(Material::SUV_SKINNING_ROTATIONS)->setMat3(&modelNode.getBoneRotations()[0],
 			                                                             modelNode.getBoneRotations().size());
 
-			mtl->getStdUniVar(Material::SUV_SKINNING_TRANSLATIONS)->setVec3(&meshSkelCtrl.getBoneTranslations()[0],
-			                                                                meshSkelCtrl.getBoneTranslations().size());
+			mtl->getStdUniVar(Material::SUV_SKINNING_TRANSLATIONS)->setVec3(&modelNode.getBoneTranslations()[0],
+			                                                                modelNode.getBoneTranslations().size());
 		}
 
 		vao->bind();

+ 1 - 1
src/Renderer/Renderer.h

@@ -97,7 +97,7 @@ class Renderer: public Object
 		/// @param mtl The material containing the shader program
 		/// @param sceneNode Needed for some matrices
 		/// @param cam Needed for some matrices
-		void setupMaterial(const class Material& mtl, const SceneNode& sceneNode, const Camera& cam);
+		void setupMaterial(const class Material& mtl, const SceneNode& sceneNode, const Camera& cam) const;
 
 
 		/// Render ModelNode. The method sets up the shader and renders the geometry

+ 2 - 0
src/Resources/Core/RsrcContainers.cpp

@@ -8,6 +8,7 @@
 #include "LightData.h"
 #include "ParticleEmitterProps.h"
 #include "Script.h"
+#include "Model.h"
 
 
 namespace RsrcContainers {
@@ -21,5 +22,6 @@ RsrcContainer<SkelAnim>   skelAnims;
 RsrcContainer<LightData> lightProps;
 RsrcContainer<ParticleEmitterProps> particleEmitterProps;
 RsrcContainer<Script> scripts;
+RsrcContainer<Model> models;
 
 }

+ 25 - 3
src/Resources/Core/RsrcPtr.cpp

@@ -9,6 +9,7 @@
 #include "LightData.h"
 #include "ParticleEmitterProps.h"
 #include "Script.h"
+#include "Model.h"
 
 
 namespace RsrcContainers {
@@ -22,6 +23,7 @@ extern RsrcContainer<SkelAnim> skelAnims;
 extern RsrcContainer<LightData> lightProps;
 extern RsrcContainer<ParticleEmitterProps> particleEmitterProps;
 extern RsrcContainer<Script> scripts;
+extern RsrcContainer<Model> models;
 
 }
 
@@ -120,7 +122,7 @@ bool RsrcPtr<ParticleEmitterProps>::loadRsrc(const char* filename)
 
 
 //======================================================================================================================
-// loadRsrc <Script>                                                                                     =
+// loadRsrc <Script>                                                                                                   =
 //======================================================================================================================
 template<>
 bool RsrcPtr<Script>::loadRsrc(const char* filename)
@@ -129,6 +131,16 @@ bool RsrcPtr<Script>::loadRsrc(const char* filename)
 }
 
 
+//======================================================================================================================
+// loadRsrc <Model>                                                                                                    =
+//======================================================================================================================
+template<>
+bool RsrcPtr<Model>::loadRsrc(const char* filename)
+{
+	LOAD_RSRC(models);
+}
+
+
 //======================================================================================================================
 // unload <Texture>                                                                                                    =
 //======================================================================================================================
@@ -140,7 +152,7 @@ void RsrcPtr<Texture>::unload()
 
 
 //======================================================================================================================
-// unload <ShaderProg>                                                                                                    =
+// unload <ShaderProg>                                                                                                 =
 //======================================================================================================================
 template<>
 void RsrcPtr<ShaderProg>::unload()
@@ -150,7 +162,7 @@ void RsrcPtr<ShaderProg>::unload()
 
 
 //======================================================================================================================
-// unload <Material>                                                                                                    =
+// unload <Material>                                                                                                   =
 //======================================================================================================================
 template<>
 void RsrcPtr<Material>::unload()
@@ -218,3 +230,13 @@ void RsrcPtr<Script>::unload()
 {
 	UNLOAD_RSRC(scripts);
 }
+
+
+//======================================================================================================================
+// unload <Model>                                                                                                      =
+//======================================================================================================================
+template<>
+void RsrcPtr<Model>::unload()
+{
+	UNLOAD_RSRC(models);
+}

+ 12 - 17
src/Resources/Material.cpp

@@ -198,18 +198,6 @@ void Material::load(const char* filename)
 			shaderProg.loadRsrc(shaderFilename.c_str());
 		}
 		//
-		// dpMtl
-		//
-		else if(Parser::isIdentifier(token, "dpMtl"))
-		{
-			if(dpMtl.get())
-			{
-				throw PARSER_EXCEPTION("Depth material already loaded");
-			}
-
-			dpMtl.loadRsrc(Parser::parseString(scanner).c_str());
-		}
-		//
 		// blendingStage
 		//
 		else if(Parser::isIdentifier(token, "blendingStage"))
@@ -230,20 +218,27 @@ void Material::load(const char* filename)
 
 			// sFactor
 			Parser::parseIdentifier(scanner, "sFactor");
-			int gl_enum;
-			if(!searchBlendEnum(Parser::parseIdentifier(scanner).c_str(), gl_enum))
+			int glEnum;
+			if(!searchBlendEnum(Parser::parseIdentifier(scanner).c_str(), glEnum))
 			{
 				throw PARSER_EXCEPTION("Incorrect blending factor \"" + token->getValue().getString() + "\"");
 			}
-			blendingSfactor = gl_enum;
+			blendingSfactor = glEnum;
 
 			// dFactor
 			Parser::parseIdentifier(scanner, "dFactor");
-			if(!searchBlendEnum(Parser::parseIdentifier(scanner).c_str(), gl_enum))
+			if(!searchBlendEnum(Parser::parseIdentifier(scanner).c_str(), glEnum))
 			{
 				throw PARSER_EXCEPTION("Incorrect blending factor \"" + token->getValue().getString() + "\"");
 			}
-			blendingDfactor = gl_enum;
+			blendingDfactor = glEnum;
+
+			// }
+			token = &scanner.getNextToken();
+			if(token->getCode() != Scanner::TC_RBRACKET)
+			{
+				throw PARSER_EXCEPTION_EXPECTED("}");
+			}
 
 		}
 		//

+ 3 - 2
src/Resources/Material.h

@@ -155,13 +155,15 @@ class Material: public Resource
 		const ShaderProg::AttribVar* getStdAttribVar(StdAttribVars id) const {return stdAttribVars[id];}
 		const ShaderProg::UniVar* getStdUniVar(StdUniVars id) const {return stdUniVars[id];}
 		const ShaderProg& getShaderProg() const {return *shaderProg.get();}
-		const Material& getDepthMtl() const {return *dpMtl.get();}
 		const boost::ptr_vector<UserDefinedUniVar>& getUserDefinedVars() const {return userDefinedVars;}
 		/// @}
 
 		/// @return Return true if the shader has references to hardware skinning
 		bool hasHWSkinning() const {return stdAttribVars[SAV_VERT_WEIGHT_BONES_NUM] != NULL;}
 
+		/// @return Return true if the shader has references to texture coordinates
+		bool hasTexCoords() const {return stdAttribVars[SAV_TEX_COORDS] != NULL;}
+
 		bool isBlendingEnabled() const {return blendingSfactor != GL_ONE || blendingDfactor != GL_ZERO;}
 
 	//====================================================================================================================
@@ -189,7 +191,6 @@ class Material: public Resource
 		const ShaderProg::AttribVar* stdAttribVars[SAV_NUM];
 		const ShaderProg::UniVar* stdUniVars[SUV_NUM];
 		RsrcPtr<ShaderProg> shaderProg; ///< The most important aspect of materials
-		RsrcPtr<Material> dpMtl; ///< The material for depth passes. To be removed when skinning is done using transform feedback
 		boost::ptr_vector<UserDefinedUniVar> userDefinedVars;
 
 		/// The func sweeps all the variables of the shader program to find standard shader program variables. It updates

+ 3 - 17
src/Resources/Mesh.cpp

@@ -28,29 +28,15 @@ void Mesh::load(const char* filename)
 
 	try
 	{
-		/*//
+		//
 		// Sanity checks
 		//
 		if(meshData.getVertIndeces().size() < 1 || meshData.getVertCoords().size() < 1 ||
-			 meshData.getVertNormals().size() < 1)
-		{
-			throw EXCEPTION("Empty required arrays");
-		}
-
-		// shader needs text coords and mesh does not have any
-		if(material->getStdAttribVar(Material::SAV_TEX_COORDS) != NULL && meshData.getTexCoords().size() < 1)
+			 meshData.getVertNormals().size() < 1 || meshData.getVertTangents().size() < 1)
 		{
-			throw EXCEPTION("The shader program (\"" + material->getShaderProg().getRsrcName() +
-											"\") needs texture coord information that the mesh doesn't have");
+			throw EXCEPTION("Empty one of the required vectors");
 		}
 
-		// shader has HW skinning and mesh does not have vert weights
-		if(material->hasHWSkinning() && meshData.getVertWeights().size() < 1)
-		{
-			throw EXCEPTION("The shader program (\"" + material->getShaderProg().getRsrcName() +
-											"\") needs vertex weights that the mesh doesn't have");
-		}*/
-
 		createVbos(meshData);
 	}
 	catch(std::exception& e)

+ 10 - 6
src/Resources/Mesh.h

@@ -19,12 +19,12 @@ class Mesh: public Resource, public Object
 		/// Used in @ref vbos array
 		enum Vbos
 		{
-			VBO_VERT_POSITIONS,
-			VBO_VERT_NORMALS,
-			VBO_VERT_TANGENTS,
-			VBO_TEX_COORDS,
-			VBO_VERT_INDECES,
-			VBO_VERT_WEIGHTS,
+			VBO_VERT_POSITIONS, ///< VBO never empty
+			VBO_VERT_NORMALS, ///< VBO never empty
+			VBO_VERT_TANGENTS, ///< VBO never empty
+			VBO_TEX_COORDS, ///< VBO may be empty
+			VBO_VERT_INDECES, ///< VBO never empty
+			VBO_VERT_WEIGHTS, ///< VBO may be empty
 			VBOS_NUM
 		};
 
@@ -43,6 +43,10 @@ class Mesh: public Resource, public Object
 		/// Implements @ref Resource::load
 		void load(const char* filename);
 
+		bool hasTexCoords() const {return vbos[VBO_TEX_COORDS] != NULL;}
+
+		bool hasVertWeights() const {return vbos[VBO_VERT_WEIGHTS] != NULL;}
+
 	private:
 		Vbo* vbos[VBOS_NUM]; ///< The vertex buffer objects
 

+ 87 - 21
src/Resources/Model.cpp

@@ -118,27 +118,42 @@ void Model::load(const char* filename)
 	//
 	// Sanity checks
 	//
-	if(skelAnims.size() > 0 && !hasSkeleton())
+	try
 	{
-		throw MDL_EXCEPTION("You have skeleton animations but no skeleton");
-	}
+		if(skelAnims.size() > 0 && !hasSkeleton())
+		{
+			throw EXCEPTION("You have skeleton animations but no skeleton");
+		}
 
-	for(uint i = 0; i < skelAnims.size(); i++)
-	{
-		if(skelAnims[i]->bones.size() != skeleton->bones.size())
+		for(uint i = 0; i < skelAnims.size(); i++)
 		{
-			throw MDL_EXCEPTION("SkelAnim \"" + skelAnims[i]->getRsrcName() + "\" and Skeleton \"" +
-			                    skeleton->getRsrcName() + "\" dont have equal bone count");
+			// Bone number problem
+			if(skelAnims[i]->bones.size() != skeleton->bones.size())
+			{
+				throw EXCEPTION("SkelAnim \"" + skelAnims[i]->getRsrcName() + "\" and Skeleton \"" +
+				                skeleton->getRsrcName() + "\" dont have equal bone count");
+			}
 		}
-	}
 
-	//
-	// Create VAOs
-	//
-	for(Vec<SubModel>::iterator it = subModels.begin(); it != subModels.end(); it++)
+		for(uint i = 0; i < subModels.size(); i++)
+		{
+			if(hasSkeleton())
+			{
+				if(!subModels[i].hasHwSkinning())
+				{
+					throw EXCEPTION("SubModel " + boost::lexical_cast<std::string>(i) + " material does not have HW skinning");
+				}
+
+				if(!subModels[i].hasHwSkinning())
+				{
+					throw EXCEPTION("SubModel " + boost::lexical_cast<std::string>(i) + " DP material does not have HW skinning");
+				}
+			}
+		}
+	}
+	catch(std::exception& e)
 	{
-		createVao(*it->material, *it->mesh, *it, it->vao);
-		createVao(*it->dpMaterial, *it->mesh, *it, it->dpVao);
+		throw MDL_EXCEPTION(e.what());
 	}
 }
 
@@ -168,20 +183,71 @@ void Model::parseSubModel(Scanner& scanner)
 
 	// Load the stuff
 	subModels.push_back(SubModel());
-	SubModel& subModel = subModels.back();
+	subModels.back().load(mesh.c_str(), material.c_str(), dpMaterial.c_str());
+}
+
+
+//======================================================================================================================
+// hasHwSkinning                                                                                                       =
+//======================================================================================================================
+bool Model::SubModel::hasHwSkinning() const
+{
+	return material->hasHWSkinning();
+}
 
-	subModel.mesh.loadRsrc(mesh.c_str());
-	subModel.material.loadRsrc(material.c_str());
-	subModel.dpMaterial.loadRsrc(dpMaterial.c_str());
 
-	/// @todo Sanity checks. See MeshNode.cpp
+//======================================================================================================================
+// load                                                                                                                =
+//======================================================================================================================
+void Model::SubModel::load(const char* meshFName, const char* mtlFName, const char* dpMtlFName)
+{
+	//
+	// Load
+	//
+	mesh.loadRsrc(meshFName);
+	material.loadRsrc(mtlFName);
+	dpMaterial.loadRsrc(dpMtlFName);
+
+	//
+	// Sanity checks
+	//
+	#define EXCEPTION_INCOMPATIBLE_RSRCS(x, y) \
+		EXCEPTION("Resource \"" + x->getRsrcName() + "\" and \"" + y->getRsrcName() + "\" are incompatible")
+
+	// if mtl needs tex coords then mesh should have
+	if(material->hasTexCoords() && !mesh->hasTexCoords())
+	{
+		throw EXCEPTION_INCOMPATIBLE_RSRCS(material, mesh);
+	}
+
+	if(dpMaterial->hasTexCoords() && !mesh->hasTexCoords())
+	{
+		throw EXCEPTION_INCOMPATIBLE_RSRCS(dpMaterial, mesh);
+	}
+
+	// if mtl needs weights then mesh should have
+	if(material->hasHWSkinning() && !mesh->hasVertWeights())
+	{
+		throw EXCEPTION_INCOMPATIBLE_RSRCS(material, mesh);
+	}
+
+	if(dpMaterial->hasHWSkinning() && !mesh->hasVertWeights())
+	{
+		throw EXCEPTION_INCOMPATIBLE_RSRCS(dpMaterial, mesh);
+	}
+
+	//
+	// VAOs
+	//
+	createVao(*material, *mesh, *this, vao);
+	createVao(*dpMaterial, *mesh, *this, dpVao);
 }
 
 
 //======================================================================================================================
 // createVao                                                                                                           =
 //======================================================================================================================
-void Model::createVao(const Material& mtl, const Mesh& mesh, SubModel& subModel, Vao*& vao)
+void Model::SubModel::createVao(const Material& mtl, const Mesh& mesh, SubModel& subModel, Vao*& vao)
 {
 	vao = new Vao(&subModel);
 

+ 12 - 9
src/Resources/Model.h

@@ -44,11 +44,19 @@ class Model: public Resource
 		/// This is basically a container around mesh and materials. It also has the VAOs.
 		class SubModel: public Object
 		{
-			friend class Model;
-
 			public:
 				SubModel(): Object(NULL) {}
 
+				/// Load the resources
+				void load(const char* meshFName, const char* mtlFName, const char* dpMtlFName);
+
+				/// Creates a VAO for an individual SubModel
+				/// @param[in] material Needed for the shader program uniform variables
+				/// @param[in] mesh For providing the VBOs
+				/// @param[in,out] subModel For setting a parent to the vao
+				/// @param[out] vao The output
+				static void createVao(const Material& material, const Mesh& mesh, SubModel& subModel, Vao*& vao);
+
 				/// @name Accessors
 				/// @{
 				const Mesh& getMesh() const {return *mesh;}
@@ -58,6 +66,8 @@ class Model: public Resource
 				const Vao& getDpVao() const {return *dpVao;}
 				/// @}
 
+				bool hasHwSkinning() const;
+
 			private:
 				RsrcPtr<Mesh> mesh; ///< The geometry
 				RsrcPtr<Material> material; ///< Material for MS and BS
@@ -86,13 +96,6 @@ class Model: public Resource
 
 		/// Parses a submodel from after the "subModel" until the closing bracket
 		void parseSubModel(Scanner& scanner);
-
-		/// Creates a VAO for an individual SubModel
-		/// @param[in] material Needed for the shader program uniform variables
-		/// @param[in] mesh For providing the VBOs
-		/// @param[in,out] subModel For setting a parent to the vao
-		/// @param[out] vao The output
-		static void createVao(const Material& material, const Mesh& mesh, SubModel& subModel, Vao*& vao);
 };
 
 

+ 0 - 41
src/Scene/Controllers/MeshSkelNodeCtrl.h

@@ -1,41 +0,0 @@
-#ifndef MESH_SKEL_CTRL_H
-#define MESH_SKEL_CTRL_H
-
-#include "Controller.h"
-#include "Vbo.h"
-
-
-class MeshNode;
-class SkelNode;
-class Mesh;
-
-
-/// Skeleton controller
-/// It controls a mesh node using a skeleton node and the skeleton node's controllers
-class MeshSkelNodeCtrl: public Controller
-{
-	public:
-		SkelNode* skelNode;
-		MeshNode* meshNode;
-
-		/*struct
-		{
-			Vbo positions;
-			Vbo normals;
-			Vbo tangents;
-		} vbos;*/
-
-
-		MeshSkelNodeCtrl(SkelNode* skelNode_, MeshNode* meshNode_):
-			Controller(CT_SKEL),
-			skelNode(skelNode_),
-			meshNode(meshNode_)
-		{}
-
-		/// Do nothing! We use HW skinning so its not necessary to update anything in the meshNode.
-		/// The skelNode's controllers provide us with sufficient data to do the trick.
-		void update(float) {}
-};
-
-
-#endif

+ 18 - 0
src/Scene/ModelNode.cpp

@@ -1,2 +1,20 @@
 #include "ModelNode.h"
+#include "Model.h"
+#include "Skeleton.h"
 
+
+//======================================================================================================================
+// init                                                                                                                =
+//======================================================================================================================
+void ModelNode::init(const char* filename)
+{
+	model.loadRsrc(filename);
+
+	if(model->hasSkeleton())
+	{
+		heads.resize(model->getSkeleton().bones.size());
+		tails.resize(model->getSkeleton().bones.size());
+		boneRotations.resize(model->getSkeleton().bones.size());
+		boneTranslations.resize(model->getSkeleton().bones.size());
+	}
+}

+ 7 - 38
src/Scene/ModelNode.h

@@ -13,6 +13,11 @@ class SkelAnimModelNodeCtrl;
 /// The model scene node
 class ModelNode: public SceneNode
 {
+	PROPERTY_RW(Vec<Vec3>, heads, setHeads, getHeads)
+	PROPERTY_RW(Vec<Vec3>, tails, setTails, getTails)
+	PROPERTY_RW(Vec<Mat3>, boneRotations, setBoneRotations, getBoneRotations)
+	PROPERTY_RW(Vec<Vec3>, boneTranslations, setBoneTranslations, getBoneTranslations)
+
 	public:
 		SkelAnimModelNodeCtrl* skelAnimModelNodeCtrl; ///< @todo Clean this
 
@@ -21,53 +26,17 @@ class ModelNode: public SceneNode
 		/// @name Accessors
 		/// @{
 		const Model& getModel() const {return *model;}
-		Vec<Vec3>& getHeads();
-		Vec<Vec3>& getTails();
-		Vec<Mat3>& getBoneRotations();
-		Vec<Vec3>& getBoneTranslations();
 		/// @}
 
 		/// @return True if the model support skeleton animation
 		bool hasSkeleton() const {return boneRotations.size() > 0;}
 
-		/// @todo write this sucker
-		void init(const char* filename) {}
+		/// @todo
+		void init(const char* filename);
 
 	private:
 		RsrcPtr<Model> model;
-		Vec<Vec3> heads;
-		Vec<Vec3> tails;
-		Vec<Mat3> boneRotations;
-		Vec<Vec3> boneTranslations;
 };
 
 
-inline Vec<Vec3>& ModelNode::getHeads()
-{
-	RASSERT_THROW_EXCEPTION(!hasSkeleton());
-	return heads;
-}
-
-
-inline Vec<Vec3>& ModelNode::getTails()
-{
-	RASSERT_THROW_EXCEPTION(!hasSkeleton());
-	return tails;
-}
-
-
-inline Vec<Mat3>& ModelNode::getBoneRotations()
-{
-	RASSERT_THROW_EXCEPTION(!hasSkeleton());
-	return boneRotations;
-}
-
-
-inline Vec<Vec3>& ModelNode::getBoneTranslations()
-{
-	RASSERT_THROW_EXCEPTION(!hasSkeleton());
-	return boneTranslations;
-}
-
-
 #endif

+ 1 - 0
src/Scene/ParticleEmitter.h

@@ -6,6 +6,7 @@
 #include "SceneNode.h"
 #include "GhostNode.h"
 #include "ParticleEmitterProps.h"
+#include "RsrcPtr.h"
 
 
 class RigidBody;

+ 0 - 18
src/Scene/Scene.cpp

@@ -36,15 +36,6 @@ void Scene::registerNode(SceneNode* node)
 		case SceneNode::SNT_CAMERA:
 			putBackNode(cameras, static_cast<Camera*>(node));
 			break;
-		case SceneNode::SNT_MESH:
-			putBackNode(meshNodes, static_cast<MeshNode*>(node));
-			break;
-		case SceneNode::SNT_SKELETON:
-			putBackNode(skelNodes, static_cast<SkelNode*>(node));
-			break;
-		case SceneNode::SNT_SKEL_MODEL:
-			// ToDo
-			break;
 		case SceneNode::SNT_PARTICLE_EMITTER:
 			putBackNode(particleEmitters, static_cast<ParticleEmitter*>(node));
 			break;
@@ -67,15 +58,6 @@ void Scene::unregisterNode(SceneNode* node)
 		case SceneNode::SNT_CAMERA:
 			eraseNode(cameras, static_cast<Camera*>(node));
 			break;
-		case SceneNode::SNT_MESH:
-			eraseNode(meshNodes, static_cast<MeshNode*>(node));
-			break;
-		case SceneNode::SNT_SKELETON:
-			eraseNode(skelNodes, static_cast<SkelNode*>(node));
-			break;
-		case SceneNode::SNT_SKEL_MODEL:
-			// ToDo
-			break;
 		case SceneNode::SNT_PARTICLE_EMITTER:
 			eraseNode(particleEmitters, static_cast<ParticleEmitter*>(node));
 			break;

+ 1 - 1
src/Scene/Scene.h

@@ -32,7 +32,7 @@ class Scene: public Object
 		Container<Camera> cameras;
 		Container<Controller> controllers;
 		Container<ParticleEmitter> particleEmitters;
-		Skybox skybox; // ToDo to be removed
+		Skybox skybox; /// @todo to be removed
 
 		// The funcs
 		Scene(Object* parent);