Browse Source

Putting the last pies on the model node instaning

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
a0e3f52a5d
4 changed files with 66 additions and 30 deletions
  1. 5 20
      include/anki/scene/ModelNode.h
  2. 45 9
      src/renderer/Drawer.cpp
  3. 12 0
      src/scene/ModelNode.cpp
  4. 4 1
      testapp/Main.cpp

+ 5 - 20
include/anki/scene/ModelNode.h

@@ -18,6 +18,7 @@ namespace anki {
 class ModelPatchNodeInstance: public SceneNode, public Movable, public Spatial
 {
 	friend class ModelPatchNode;
+	friend class ModelNode;
 
 public:
 	ModelPatchNodeInstance(
@@ -44,6 +45,7 @@ class ModelPatchNode: public SceneNode, public Movable, public Renderable,
 	public Spatial
 {
 	friend class ModelPatchNodeInstance;
+	friend class ModelNode;
 
 public:
 	/// @name Constructors/Destructor
@@ -56,16 +58,6 @@ public:
 	~ModelPatchNode();
 	/// @}
 
-	/// @name SceneNode virtuals
-	/// @{
-
-	/// Override SceneNode::frameUpdate
-	void frameUpdate(F32 prevUpdateTime, F32 crntTime, I frame)
-	{
-		SceneNode::frameUpdate(prevUpdateTime, crntTime, frame);
-	}
-	/// @}
-
 	/// @name Movable virtuals
 	/// @{
 
@@ -134,16 +126,6 @@ public:
 	}
 	/// @}
 
-	/// @name SceneNode virtuals
-	/// @{
-
-	/// Override SceneNode::frameUpdate
-	void frameUpdate(float prevUpdateTime, float crntTime, int frame)
-	{
-		SceneNode::frameUpdate(prevUpdateTime, crntTime, frame);
-	}
-	/// @}
-
 	/// @name Movable virtuals
 	/// @{
 
@@ -155,6 +137,9 @@ public:
 	}
 	/// @}
 
+	/// Set the local transform of one instance
+	void setInstanceLocalTransform(U instanceIndex, const Transform& trf);
+
 private:
 	ModelResourcePointer model; ///< The resource
 	ModelPatchNodes patches;

+ 45 - 9
src/renderer/Drawer.cpp

@@ -34,7 +34,7 @@ struct SetupRenderableVariableVisitor
 	const ShaderProgramUniformVariable* uni;
 
 	// Used for 
-	U32* subSpatialIndices = nullptr;
+	const U32* subSpatialIndices = nullptr;
 	U32 subSpatialIndicesCount = 0;
 
 	/// Set a uniform in a client block
@@ -50,7 +50,7 @@ struct SetupRenderableVariableVisitor
 	{
 		const U32 instancesCount = renderable->getRenderableInstancesCount();
 		const U32 uniArrSize = uni->getSize();
-		const U32 size = std::min(instancesCount, uniArrSize);
+		U32 size = std::min(instancesCount, uniArrSize);
 
 		// Set uniform
 		//
@@ -69,9 +69,21 @@ struct SetupRenderableVariableVisitor
 			{
 				Array<Mat4, ANKI_MAX_INSTANCES> mvp;
 
-				for(U i = 0; i < size; i++)
+				if(subSpatialIndicesCount == 0)
+				{
+					for(U i = 0; i < size; i++)
+					{
+						mvp[i] = vp * Mat4(trfs[i]);
+					}
+				}
+				else
 				{
-					mvp[i] = vp * Mat4(trfs[i]);
+					for(size = 0; size < subSpatialIndicesCount; size++)
+					{
+						ANKI_ASSERT(size < instancesCount 
+							&& size < uniArrSize);
+						mvp[size] = vp * Mat4(trfs[subSpatialIndices[size]]);
+					}
 				}
 
 				uniSet(*uni, &mvp[0], size);
@@ -87,9 +99,22 @@ struct SetupRenderableVariableVisitor
 				ANKI_ASSERT(trfs != nullptr);
 				Array<Mat4, ANKI_MAX_INSTANCES> mv;
 
-				for(U i = 0; i < size; i++)
+				if(subSpatialIndicesCount == 0)
+				{
+					for(U i = 0; i < size; i++)
+					{
+						mv[i] = v * Mat4(trfs[i]);
+					}
+				}
+				else
 				{
-					mv[i] = v * Mat4(trfs[i]);
+					for(size = 0; size < subSpatialIndicesCount; size++)
+					{
+						ANKI_ASSERT(size < instancesCount 
+							&& size < uniArrSize);
+
+						mv[size] = v * Mat4(trfs[subSpatialIndices[size]]);
+					}
 				}
 
 				uniSet(*uni, &mv[0], size);
@@ -103,10 +128,21 @@ struct SetupRenderableVariableVisitor
 			{
 				Array<Mat3, ANKI_MAX_INSTANCES> normm;
 
-				for(U i = 0; i < size; i++)
+				if(subSpatialIndicesCount == 0)
+				{
+					for(U i = 0; i < size; i++)
+					{
+						Mat4 mv = v * Mat4(trfs[i]);
+						normm[i] = mv.getRotationPart();
+					}
+				}
+				else
 				{
-					Mat4 mv = v * Mat4(trfs[i]);
-					normm[i] = mv.getRotationPart();
+					for(size = 0; size < subSpatialIndicesCount; size++)
+					{
+						Mat4 mv = v * Mat4(trfs[subSpatialIndices[size]]);
+						normm[size] = mv.getRotationPart();
+					}
 				}
 
 				uniSet(*uni, &normm[0], size);

+ 12 - 0
src/scene/ModelNode.cpp

@@ -220,4 +220,16 @@ ModelNode::~ModelNode()
 	}
 }
 
+//==============================================================================
+void ModelNode::setInstanceLocalTransform(U instanceIndex, const Transform& trf)
+{
+	ANKI_ASSERT(patches.size() > 0);
+	ANKI_ASSERT(instanceIndex < patches[0]->instances.size());
+
+	for(ModelPatchNode* patch : patches)
+	{
+		patch->instances[instanceIndex]->setLocalTransform(trf);
+	}
+}
+
 } // end namespace anki

+ 4 - 1
testapp/Main.cpp

@@ -246,6 +246,9 @@ void init()
 		"data/models/red_barrel/red_barrel.mdl", 2);
 	redBarrel->setLocalTransform(Transform(Vec3(+2, 0, 0), Mat3::getIdentity(),
 		0.7));
+
+	redBarrel->setInstanceLocalTransform(1, 
+		Transform(Vec3(1.0), Mat3(Euler(getPi<F32>() / 2, 0.0, 0.0)), 2.0));
 #endif
 
 #if 0
@@ -517,7 +520,7 @@ void initSubsystems(int argc, char* argv[])
 	nwinit.minorVersion = glminor;
 	nwinit.depthBits = 0;
 	nwinit.stencilBits = 0;
-	nwinit.fullscreenDesktopRez = true;
+	nwinit.fullscreenDesktopRez = false;
 	win = new NativeWindow;	
 	win->create(nwinit);