ソースを参照

- Finalizing ModelNode
- Starting the SkinNode

Panagiotis Christopoulos Charitos 14 年 前
コミット
7173bcf659

+ 11 - 0
anki/collision/Frustum.h

@@ -45,6 +45,9 @@ public:
 	Frustum(FrustumType type_)
 		: CollisionShape(CST_FRUSTUM), type(type_)
 	{}
+
+	virtual ~Frustum()
+	{}
 	/// @}
 
 	/// @name Accessors
@@ -183,6 +186,14 @@ public:
 	/// Implements CollisionShape::testPlane
 	float testPlane(const Plane& p) const;
 
+	/// Calculate and get transformed
+	PerspectiveFrustum getTransformed(const Transform& trf) const
+	{
+		PerspectiveFrustum o = *this;
+		o.transform(trf);
+		return o;
+	}
+
 	/// Re-implements Frustum::transform
 	void transform(const Transform& trf);
 

+ 2 - 2
anki/scene/Camera.h

@@ -26,7 +26,7 @@ public:
 		CT_COUNT
 	};
 
-	/// @name Constructors
+	/// @name Constructors/Destructor
 	/// @{
 	Camera(CameraType type_,
 		const char* name, Scene* scene, // SceneNode
@@ -35,9 +35,9 @@ public:
 		: SceneNode(name, scene), Movable(movableFlags, movParent, *this),
 			Spatial(frustum), Frustumable(frustum), type(type_)
 	{}
-	/// @}
 
 	virtual ~Camera();
+	/// @}
 
 	/// @name Accessors
 	/// @{

+ 12 - 1
anki/scene/Light.cpp

@@ -57,7 +57,18 @@ SpotLight::SpotLight(const char* fmtl,
 	uint movableFlags, Movable* movParent)
 	: Light(LT_SPOT, fmtl, name, scene, movableFlags, movParent, &frustum),
 		Frustumable(&frustum)
-{}
+{
+	PropertyBase& pbase = findPropertyBaseByName("radius");
+	Property<float>& prop = pbase.upCast<Property<float> >();
+	ANKI_CONNECT(&prop, valueChanged, this, updateZFar);
+
+	Property<float>* angProp = new  ReadWriteProperty("angle", 45.0);
+	addNewProperty(angProp);
+	ANKI_CONNECT(angProp, valueChanged, this, updateFov);
+
+	frustum.setAll(angProg->getValue(), angProg->getValue(), 0.1,
+		prop.getValue());
+}
 
 
 } // end namespace

+ 39 - 5
anki/scene/Light.h

@@ -143,6 +143,8 @@ public:
 class SpotLight: public Light, public Frustumable
 {
 public:
+	ANKI_OBSERVING(SpotLight)
+
 	/// @name Constructors/Destructor
 	/// @{
 	SpotLight(const char* fmtl,
@@ -150,15 +152,47 @@ public:
 		uint movableFlags, Movable* movParent);
 	/// @}
 
+	/// @name Movable virtuals
+	/// @{
+
+	/// Overrides Movable::moveUpdate(). This does:
+	/// - Update the collision shape
+	void movableUpdate()
+	{
+		Movable::movableUpdate();
+		frustum.transform(getWorldTransform());
+		viewMat = Mat4(getWorldTransform().getInverse());
+	}
+	/// @}
+
+	/// @name Frustumable virtuals
+	/// @{
+
+	/// Implements Frustumable::frustumUpdate(). Calculate the projection
+	/// matrix
+	void frustumUpdate()
+	{
+		projectionMat = getFrustum().calculateProjectionMatrix();
+	}
+	/// @}
+
 private:
-	PerspectiveFrustum frustumW;
-	PerspectiveFrustum frustumL;
+	PerspectiveFrustum frustum;
+	Mat4 projectionMat;
+	Mat4 viewMat;
+
+	void updateZFar(const float& f)
+	{
+		frustum.setZFar(r);
+	}
+	ANKI_SLOT(updateZFar, const float&)
 
-	void updateFrustum(const PerspectiveFrustum&)
+	void updateFov(const float& f)
 	{
-		//frustumL.setRadius(r);
+		frustum.setFovX(f);
+		frustum.setFovY(f);
 	}
-	ANKI_SLOT(updateFrustum, const PerspectiveFrustum&)
+	ANKI_SLOT(updateFov, const float&)
 };
 
 

+ 33 - 16
anki/scene/ModelNode.cpp

@@ -1,42 +1,59 @@
-#include <boost/foreach.hpp>
 #include "anki/scene/ModelNode.h"
 #include "anki/resource/Model.h"
 #include "anki/resource/Skeleton.h"
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
 
 
 namespace anki {
 
 
 //==============================================================================
-ModelNode::ModelNode(Scene& scene, ulong flags, SceneNode* parent)
-	: SceneNode(SNT_MODEL_NODE, scene, flags, parent)
-{}
-
+// ModelPatchNode                                                              =
+//==============================================================================
 
 //==============================================================================
-ModelNode::~ModelNode()
-{}
+ModelPatchNode::ModelPatchNode(const ModelPatch* modelPatch_,
+	const char* name, Scene* scene,
+	uint movableFlags, Movable* movParent)
+	: SceneNode(name, scene), Movable(movableFlags, movParent, *this),
+		Spatial(&obb), modelPatch(modelPatch_)
+{
+	Renderable::init(*this);
+}
 
 
 //==============================================================================
-void ModelNode::init(const char* filename)
+// ModelNode                                                                   =
+//==============================================================================
+
+//==============================================================================
+ModelNode::ModelNode(const char* modelFname,
+	const char* name, Scene* scene,
+	uint movableFlags, Movable* movParent)
+	: SceneNode(name, scene), Movable(movableFlags, movParent, *this),
+		Spatial(&obb)
 {
-	model.load(filename);
+	model.load(modelFname);
 
+	uint i = 0;
 	BOOST_FOREACH(const ModelPatch& patch, model->getModelPatches())
 	{
-		patches.push_back(new ModelPatchNode(&patch, this));
+		std::string name = model.getResourceName()
+			+ boost::lexical_cast<std::string>(i);
+
+		ModelPatchNode* mpn = new ModelPatchNode(&patch, name.c_str(),
+			scene, Movable::MF_IGNORE_LOCAL_TRANSFORM, this);
+
+		patches.push_back(mpn);
+		++i;
 	}
 }
 
 
 //==============================================================================
-void ModelNode::moveUpdate()
-{
-	// Update bounding shape
-	visibilityShapeWSpace = model->getVisibilityShape().getTransformed(
-		getWorldTransform());
-}
+ModelNode::~ModelNode()
+{}
 
 
 } // end namespace

+ 81 - 71
anki/scene/ModelNode.h

@@ -2,13 +2,15 @@
 #define ANKI_SCENE_MODEL_NODE_H
 
 #include "anki/scene/SceneNode.h"
-#include "anki/resource/Resource.h"
 #include "anki/scene/Renderable.h"
+#include "anki/scene/Movable.h"
+#include "anki/scene/Spatial.h"
+#include "anki/resource/Resource.h"
 #include "anki/resource/Model.h"
 #include "anki/collision/Obb.h"
-#include "anki/scene/MaterialRuntime.h"
+
 #include <boost/array.hpp>
-#include <vector>
+#include <boost/ptr_container/ptr_vector.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <boost/scoped_ptr.hpp>
 
@@ -17,119 +19,127 @@ namespace anki {
 
 
 /// A fragment of the ModelNode
-class ModelPatchNode: public Renderable, public SceneNode
+class ModelPatchNode: public SceneNode, public Movable, public Renderable,
+	public Spatial
 {
 public:
-	ModelPatchNode(const ModelPatch* modelPatch_, SceneNode* parent)
-		: SceneNode(SNT_RENDERABLE_NODE, parent->getScene(),
-			SNF_INHERIT_PARENT_TRANSFORM, parent), modelPatch(modelPatch_)
-	{
-		mtlr.reset(new MaterialRuntime(modelPatch->getMaterial()));
-	}
-
-	/// Implements SceneNode::getVisibilityCollisionShapeWorldSpace
-	const CollisionShape*
-		getVisibilityCollisionShapeWorldSpace() const
-	{
-		return &visibilityShapeWSpace;
-	}
+	/// @name Constructors/Destructor
+	/// @{
+	ModelPatchNode(const ModelPatch* modelPatch_,
+		const char* name, Scene* scene, // Scene
+		uint movableFlags, Movable* movParent); // Movable
+	/// @}
 
-	void init(const char*)
-	{}
+	/// @name SceneNode virtuals
+	/// @{
 
-	/// Re-implements SceneNode::moveUpdate
-	void moveUpdate()
+	/// Override SceneNode::getMovable()
+	Movable* getMovable()
 	{
-		visibilityShapeWSpace =
-			modelPatch->getMesh().getVisibilityShape().getTransformed(
-			getParent()->getWorldTransform());
+		return this;
 	}
 
-	/// Implements Renderable::getVao
-	const Vao& getVao(const PassLevelKey& k)
+	/// Override SceneNode::getSpatial()
+	Spatial* getSpatial()
 	{
-		return modelPatch->getVao(k);
+		return this;
 	}
 
-	/// Implements Renderable::getVertexIdsNum
-	uint getVertexIdsNum(const PassLevelKey& k)
+	/// Override SceneNode::getRenderable
+	Renderable* getRenderable()
 	{
-		return modelPatch->getMesh().getVertsNum();
+		return this;
 	}
+	/// @}
 
-	/// Implements Renderable::getMaterialRuntime
-	MaterialRuntime& getMaterialRuntime()
+	// @name Movable virtuals
+	/// @{
+
+	/// Overrides Movable::moveUpdate(). This does:
+	/// - Update the collision shape
+	void movableUpdate()
 	{
-		return *mtlr;
+		Movable::movableUpdate();
+		obb = modelPatch->getMeshBase().getBoundingShape().getTransformed(
+			getWorldTransform());
 	}
+	/// @}
 
-	/// Implements Renderable::getWorldTransform
-	const Transform& getWorldTransform(const PassLevelKey&)
+	/// @name Renderable virtuals
+	/// @{
+
+	/// Implements Renderable::getModelPatchBase
+	const ModelPatchBase& getModelPatchBase() const
 	{
-		return SceneNode::getWorldTransform();
+		return *modelPatch;
 	}
 
-	/// Implements Renderable::getPreviousWorldTransform
-	const Transform& getPreviousWorldTransform(
-		const PassLevelKey& k)
+	/// Implements  Renderable::getMaterial
+	const Material& getMaterial() const
 	{
-		return SceneNode::getPrevWorldTransform();
+		return modelPatch->getMaterial();
 	}
+	/// @}
 
 private:
-	Obb visibilityShapeWSpace;
-	const ModelPatch* modelPatch;
-	boost::scoped_ptr<MaterialRuntime> mtlr; ///< Material runtime
+	Obb obb; ///< In world space
+	const ModelPatch* modelPatch; ///< The resource
 };
 
 
 /// The model scene node
-class ModelNode: public SceneNode
+class ModelNode: public SceneNode, public Movable, public Spatial
 {
 public:
-	typedef boost::iterator_range<std::vector<ModelPatchNode*>::
-		const_iterator> ConstRangeModelPatchNodes;
+	typedef boost::ptr_vector<ModelPatchNode> ModelPatchNodes;
+
+	typedef boost::iterator_range<ModelPatchNodes::const_iterator>
+		ConstRangeModelPatchNodes;
 
-	typedef boost::iterator_range<std::vector<ModelPatchNode*>::
-		iterator> MutableRangeModelPatchNodes;
+	typedef boost::iterator_range<ModelPatchNodes::iterator>
+		MutableRangeModelPatchNodes;
+
+	/// @name Constructors/Destructor
+	/// @{
+	ModelNode(const char* modelFname,
+		const char* name, Scene* scene, // SceneNode
+		uint movableFlags, Movable* movParent); // Movable
 
-	ModelNode(Scene& scene, ulong flags, SceneNode* parent);
 	virtual ~ModelNode();
+	/// @}
 
-	/// @name Accessors
+	/// @name SceneNode virtuals
 	/// @{
-	ConstRangeModelPatchNodes getModelPatchNodes() const
-	{
-		return ConstRangeModelPatchNodes(patches.begin(), patches.end());
-	}
-	MutableRangeModelPatchNodes getModelPatchNodes()
-	{
-		return MutableRangeModelPatchNodes(patches.begin(), patches.end());
-	}
 
-	const Model& getModel() const
+	/// Override SceneNode::getMovable()
+	Movable* getMovable()
 	{
-		return *model;
+		return this;
 	}
 
-	const CollisionShape*
-		getVisibilityCollisionShapeWorldSpace() const
+	/// Override SceneNode::getSpatial()
+	Spatial* getSpatial()
 	{
-		return &visibilityShapeWSpace;
+		return this;
 	}
 	/// @}
 
-	/// Initialize the node
-	/// - Load the resource
-	void init(const char* filename);
+	/// @name Movable virtuals
+	/// @{
 
-	/// Update the bounding shape
-	void moveUpdate();
+	/// Overrides Movable::moveUpdate(). This does:
+	/// - Update collision shape
+	void movableUpdate()
+	{
+		obb = model->getVisibilityShape().getTransformed(
+			getWorldTransform());
+	}
+	/// @}
 
 private:
-	ModelResourcePointer model;
-	std::vector<ModelPatchNode*> patches;
-	Obb visibilityShapeWSpace;
+	ModelResourcePointer model; ///< The resource
+	ModelPatchNodes patches;
+	Obb obb;
 };
 
 

+ 2 - 2
anki/scene/Particle.cpp

@@ -4,7 +4,7 @@
 
 namespace anki {
 
-
+/*
 //==============================================================================
 // Constructor                                                                 =
 //==============================================================================
@@ -28,7 +28,7 @@ Particle::~Particle()
 void Particle::setNewRigidBody(RigidBody* body_)
 {
 	body.reset(body_);
-}
+}*/
 
 
 } // end namespace

+ 2 - 2
anki/scene/Particle.h

@@ -12,7 +12,7 @@ class RigidBody;
 
 
 /// The scene node particle class
-class Particle: public ModelNode
+/*class Particle: public ModelNode
 {
 	public:
 		Particle(float timeOfDeath, Scene& scene, ulong flags,
@@ -31,7 +31,7 @@ class Particle: public ModelNode
 	private:
 		float timeOfDeath; ///< Life of death. If < 0.0 then dead. In seconds
 		boost::scoped_ptr<RigidBody> body; ///< For garbage collection
-};
+};*/
 
 
 } // end namespace

+ 2 - 2
anki/scene/ParticleEmitterNode.cpp

@@ -12,7 +12,7 @@
 namespace anki {
 
 
-btTransform ParticleEmitterNode::startingTrf(toBt(Mat3::getIdentity()),
+/*btTransform ParticleEmitterNode::startingTrf(toBt(Mat3::getIdentity()),
 	btVector3(10000000.0, 10000000.0, 10000000.0));
 
 
@@ -222,7 +222,7 @@ void ParticleEmitterNode::frameUpdate(float prevUpdateTime, float crntTime)
 	{
 		timeLeftForNextEmission -= crntTime - prevUpdateTime;
 	}
-}
+}*/
 
 
 } // end namespace

+ 2 - 2
anki/scene/ParticleEmitterNode.h

@@ -14,7 +14,7 @@ class btCollisionShape;
 
 namespace anki {
 
-class Particle;
+/*class Particle;
 
 
 /// The particle emitter scene node. This scene node emitts
@@ -45,7 +45,7 @@ class ParticleEmitterNode: public SceneNode, public ParticleEmitterRsrc
 inline ParticleEmitterNode::ParticleEmitterNode(Scene& scene, ulong flags,
 	SceneNode* parent)
 :	SceneNode(SNT_PARTICLE_EMITTER_NODE, scene, flags, parent)
-{}
+{}*/
 
 
 } // end namespace

+ 0 - 71
anki/scene/PointLight.h

@@ -1,71 +0,0 @@
-#ifndef ANKI_SCENE_POINT_LIGHT_H
-#define ANKI_SCENE_POINT_LIGHT_H
-
-#include "anki/scene/Light.h"
-#include "anki/collision/Sphere.h"
-
-
-namespace anki {
-
-
-/// Point light. Defined by its radius
-class PointLight: public Light
-{
-	public:
-		PointLight(Scene& scene, ulong flags, SceneNode* parent);
-
-		/// @name Accessors
-		/// @{
-		float getRadius() const
-		{
-			return radius;
-		}
-		void setRadius(float x)
-		{
-			radius = x;
-			lspaceCShape = Sphere(Vec3(0.0), radius);
-		}
-		/// @}
-
-		void init(const char* filename);
-
-		/// @copydoc SceneNode::getVisibilityCollisionShapeWorldSpace
-		const CollisionShape*
-			getVisibilityCollisionShapeWorldSpace() const
-		{
-			return &wspaceCShape;
-		}
-
-		void moveUpdate()
-		{
-			wspaceCShape = lspaceCShape.getTransformed(getWorldTransform());
-		}
-
-	private:
-		float radius;
-		Sphere lspaceCShape;
-		Sphere wspaceCShape;
-};
-
-
-inline PointLight::PointLight(Scene& scene, ulong flags, SceneNode* parent)
-:	Light(LT_POINT, scene, flags, parent)
-{}
-
-
-inline void PointLight::init(const char* filename)
-{
-	Light::init(filename);
-	if(lightData->getType() != LightRsrc::LT_POINT)
-	{
-		throw ANKI_EXCEPTION("Light data is wrong type");
-	}
-	radius = lightData->getRadius();
-	lspaceCShape = Sphere(Vec3(0.0), radius);
-}
-
-
-} // end namespace
-
-
-#endif

+ 40 - 0
anki/scene/SkinNode.cpp

@@ -9,6 +9,46 @@
 namespace anki {
 
 
+//==============================================================================
+// SkinMesh                                                                    =
+//==============================================================================
+
+//==============================================================================
+SkinMesh::SkinMesh(const Mesh* mesh_)
+	: mesh(mesh_)
+{
+	// Positions
+	if(mesh->getVbo(VBO_POSITIONS))
+	{
+		tfVbos[VBO_TF_POSITIONS].create(
+			GL_ARRAY_BUFFER,
+			mesh->getVbo(VBO_POSITIONS).getSizeInBytes(),
+			NULL,
+			GL_STATIC_DRAW);
+	}
+
+	// Normals
+	if(mesh->getVbo(VBO_NORMALS))
+	{
+		tfVbos[VBO_TF_NORMALS].create(
+			GL_ARRAY_BUFFER,
+			mesh->getVbo(VBO_NORMALS).getSizeInBytes(),
+			NULL,
+			GL_STATIC_DRAW);
+	}
+
+	// Tangents
+	if(mesh->getVbo(VBO_TANGENTS))
+	{
+		tfVbos[VBO_TF_TANGENTS].create(
+			GL_ARRAY_BUFFER,
+			mesh->getVbo(VBO_TANGENTS).getSizeInBytes(),
+			NULL,
+			GL_STATIC_DRAW);
+	}
+}
+
+
 //==============================================================================
 // SkinPatchNode                                                               =
 //==============================================================================

+ 67 - 1
anki/scene/SkinNode.h

@@ -16,8 +16,74 @@ namespace anki {
 class Skin;
 
 
+/// XXX
+class SkinMesh: public MeshBase
+{
+public:
+	/// Transform feedback VBOs
+	enum TfVboId
+	{
+		VBO_TF_POSITIONS, ///< VBO never empty
+		VBO_TF_NORMALS, ///< VBO never empty
+		VBO_TF_TANGENTS, ///< VBO never empty
+		VBOS_TF_NUMBER
+	};
+
+	/// Create the @a tfVbos with empty data
+	SkinMesh(const Mesh* mesh_);
+
+	/// @name Implementations of MeshBase virtuals
+	/// @{
+	const Vbo* getVbo(VboId id) const
+	{
+		switch(id)
+		{
+			case VBO_POSITIONS:
+				return &tfVbos[VBO_TF_POSITIONS];
+			case VBO_NORMALS:
+				return &tfVbos[VBO_TF_NORMALS];
+			case VBO_TANGENTS:
+				return &tfVbos[VBO_TF_TANGENTS];
+			default:
+				return mesh->getVbo(id);
+		}
+	}
+
+	uint getTextureChannelsNumber() const
+	{
+		return mesh->getTextureChannelsNumber();
+	}
+
+	uint getLodsNumber() const
+	{
+		return mesh->getLodsNumber();
+	}
+
+	uint getIndicesNumber(uint lod) const
+	{
+		return mesh->getIndicesNumber(lod);
+	}
+
+	uint getVerticesNumber(uint lod) const
+	{
+		return mesh->getVerticesNumber(lod);
+	}
+
+	const Obb& getBoundingShape() const
+	{
+		return mesh->getBoundingShape();
+	}
+	/// @}
+
+private:
+	boost::array<Vbo, TFV_NUM> tfVbos;
+	const Mesh* mesh; ///< The resource
+};
+
+
 /// A fragment of the SkinNode
-class SkinPatchNode: public Renderable, public SceneNode
+class SkinPatchNode: public SceneNode, public Movable, public Renderable,
+	public Spatial
 {
 	public:
 		enum TransformFeedbackVbo