Ver código fonte

Scene updates

Panagiotis Christopoulos Charitos 13 anos atrás
pai
commit
c388c7f23e

+ 2 - 2
include/anki/math/Mat4.inl.h

@@ -879,8 +879,8 @@ inline Mat4 Mat4::combineTransformations(const Mat4& m0, const Mat4& m1)
 	// See the clean code in < r664
 
 	// one of the 2 mat4 doesnt represent transformation
-	ANKI_ASSERT(Math::isZero(m0(3, 0) + m0(3, 1) + m0(3, 2) + m0(3, 3)-1.0) 
-		&& Math::isZero(m1(3, 0) + m1(3, 1) + m1(3, 2) + m1(3, 3)-1.0));
+	ANKI_ASSERT(Math::isZero(m0(3, 0) + m0(3, 1) + m0(3, 2) + m0(3, 3) - 1.0)
+		&& Math::isZero(m1(3, 0) + m1(3, 1) + m1(3, 2) + m1(3, 3) - 1.0));
 
 	Mat4 m4;
 

+ 5 - 4
include/anki/physics/MotionState.h

@@ -34,10 +34,11 @@ public:
 
 		if(node)
 		{
-			Transform& nodeTrf = node->getLocalTransform();
-			float originalScale = nodeTrf.getScale();
-			nodeTrf = toAnki(worldTrans);
-			nodeTrf.setScale(originalScale);
+			Transform newTrf;
+			float originalScale = node->getLocalTransform().getScale();
+			newTrf = toAnki(worldTrans);
+			newTrf.setScale(originalScale);
+			node->setLocalTransform(newTrf);
 		}
 	}
 	/// @}

+ 23 - 14
include/anki/scene/Movable.h

@@ -4,6 +4,7 @@
 #include "anki/util/Object.h"
 #include "anki/util/Flags.h"
 #include "anki/math/Math.h"
+#include "anki/scene/Scene.h"
 
 namespace anki {
 
@@ -22,7 +23,6 @@ public:
 	{
 		MF_NONE = 0,
 		MF_IGNORE_LOCAL_TRANSFORM = 1, ///< Get the parent's world transform
-		MF_MOVED = 2 ///< Moved in the previous frame
 	};
 
 	/// @name Constructors & destructor
@@ -46,22 +46,22 @@ public:
 	void setLocalTransform(const Transform& x)
 	{
 		lTrf = x;
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void setLocalTranslation(const Vec3& x)
 	{
 		lTrf.setOrigin(x);
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void setLocalRotation(const Mat3& x)
 	{
 		lTrf.setRotation(x);
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void setLocalScale(float x)
 	{
 		lTrf.setScale(x);
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 
 	const Transform& getWorldTransform() const
@@ -80,35 +80,40 @@ public:
 	void rotateLocalX(float angDegrees)
 	{
 		lTrf.getRotation().rotateXAxis(angDegrees);
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void rotateLocalY(float angDegrees)
 	{
 		lTrf.getRotation().rotateYAxis(angDegrees);
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void rotateLocalZ(float angDegrees)
 	{
 		lTrf.getRotation().rotateZAxis(angDegrees);
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void moveLocalX(float distance)
 	{
 		Vec3 x_axis = lTrf.getRotation().getColumn(0);
 		lTrf.getOrigin() += x_axis * distance;
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void moveLocalY(float distance)
 	{
 		Vec3 y_axis = lTrf.getRotation().getColumn(1);
 		lTrf.getOrigin() += y_axis * distance;
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	void moveLocalZ(float distance)
 	{
 		Vec3 z_axis = lTrf.getRotation().getColumn(2);
 		lTrf.getOrigin() += z_axis * distance;
-		enableFlag(MF_MOVED);
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
+	}
+	void scale(float s)
+	{
+		lTrf.getScale() += s;
+		lastUpdateFrame = SceneSingleton::get().getFramesCount();
 	}
 	/// @}
 
@@ -125,14 +130,18 @@ public:
 	void update();
 
 protected:
-	Transform lTrf; ///< The transformation in local space
+	/// The transformation in local space
+	Transform lTrf = Transform::getIdentity();
 
 	/// The transformation in world space (local combined with parent's
 	/// transformation)
-	Transform wTrf;
+	Transform wTrf = Transform::getIdentity();
 
 	/// Keep the previous transformation for checking if it moved
-	Transform prevWTrf;
+	Transform prevWTrf = Transform::getIdentity();
+
+	/// The frame where it was last moved
+	uint32_t lastUpdateFrame = SceneSingleton::get().getFramesCount();
 
 	/// Called for every frame. It updates the @a wTrf if @a shouldUpdateWTrf
 	/// is true. Then it moves to the children.

+ 17 - 9
include/anki/scene/Scene.h

@@ -9,6 +9,9 @@
 
 namespace anki {
 
+/// @addtogroup Scene
+/// @{
+
 /// The Scene contains all the dynamic entities
 ///
 /// XXX Add physics
@@ -76,13 +79,9 @@ public:
 		return nodes.end();
 	}
 
-	const VisibilityInfo& getVisibilityInfo() const
-	{
-		return vinfo;
-	}
-	VisibilityInfo& getVisibilityInfo()
+	uint32_t getFramesCount() const
 	{
-		return vinfo;
+		return frame;
 	}
 	/// @}
 
@@ -90,7 +89,15 @@ public:
 	void registerNode(SceneNode* node);
 	void unregisterNode(SceneNode* node);
 
-	void update(float prevUpdateTime, float crntTime, int frame);
+	void updateFrameStart()
+	{}
+
+	void update(float prevUpdateTime, float crntTime);
+
+	void updateFrameEnd()
+	{
+		++frame;
+	}
 
 	void doVisibilityTests(Camera& cam);
 
@@ -106,7 +113,7 @@ private:
 	Vec3 ambientCol = Vec3(1.0); ///< The global ambient color
 	Camera* mainCam = nullptr;
 	VisibilityTester vtester;
-	VisibilityInfo vinfo;
+	uint32_t frame = 1;
 
 	/// Add to a container
 	template<typename T>
@@ -159,7 +166,8 @@ private:
 };
 
 typedef Singleton<Scene> SceneSingleton;
+/// @}
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 8 - 11
include/anki/scene/VisibilityTester.h

@@ -13,6 +13,9 @@ class Frustumable;
 class Renderable;
 class Light;
 
+/// @addtogroup Scene
+/// @{
+
 /// Its actually a container for visible entities
 class VisibilityInfo
 {
@@ -54,15 +57,6 @@ private:
 class VisibilityTester
 {
 public:
-	enum Test
-	{
-		T_NONE_BIT = 0
-		T_RENDERABLES_BIT = 1,
-		T_LIGHTS_BIT = 2,
-		T_CAMERAS_BIT = 4,
-		T_ALL_BIT = T_RENDERABLES_BIT | T_LIGHTS_BIT | T_CAMERAS_BIT
-	};
-
 	/// Constructor
 	VisibilityTester()
 	{}
@@ -72,9 +66,12 @@ public:
 	/// This method:
 	/// - Gets the visible renderables and frustumables
 	/// - For every frustumable perform tests
-	static void test(Frustumable& cam, Scene& scene, VisibilityInfo& vinfo,
-		uint32_t testMask = T_ALL_BIT);
+	static void test(Frustumable& ref, Scene& scene);
+
+private:
+	static void testLight(Light& light, Scene& scene);
 };
+/// @}
 
 } // end namespace anki
 

+ 2 - 1
src/renderer/Is.cpp

@@ -254,7 +254,8 @@ void Is::run()
 
 	GlStateSingleton::get().enable(GL_STENCIL_TEST);
 
-	VisibilityInfo& vi = r->getScene().getVisibilityInfo();
+	VisibilityInfo& vi =
+		r->getScene().getActiveCamera().getFrustumable()->getVisibilityInfo();
 	for(auto it = vi.getLightsBegin();
 		it != vi.getLightsEnd(); ++it)
 	{

+ 2 - 1
src/renderer/Ms.cpp

@@ -69,7 +69,8 @@ void Ms::run()
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 	// render all
-	VisibilityInfo& vi = r->getScene().getVisibilityInfo();
+	VisibilityInfo& vi =
+		r->getScene().getActiveCamera().getFrustumable()->getVisibilityInfo();
 	for(auto it = vi.getRenderablesBegin();
 		it != vi.getRenderablesEnd(); ++it)
 	{

+ 2 - 4
src/renderer/Sm.cpp

@@ -119,12 +119,10 @@ void Sm::run(Light& light, float distance)
 
 	// Visibility tests
 	SpotLight& slight = static_cast<SpotLight&>(light);
-	VisibilityInfo vi;
-	VisibilityTester vt;
-	vt.test(slight, r->getScene(), vi);
 
 	// render all
-	for(auto it = vi.getRenderablesBegin(); it != vi.getRenderablesEnd(); ++it)
+	for(auto it = slight.getVisibilityInfo().getRenderablesBegin();
+		it != slight.getVisibilityInfo().getRenderablesEnd(); ++it)
 	{
 		r->getSceneDrawer().render(r->getScene().getActiveCamera(), 1, *(*it));
 	}

+ 10 - 47
src/scene/Movable.cpp

@@ -5,18 +5,12 @@ namespace anki {
 
 //==============================================================================
 Movable::Movable(uint32_t flags_, Movable* parent, PropertyMap& pmap)
-	: Base(this, parent), Flags(flags_ | MF_MOVED)
+	: Base(this, parent), Flags(flags_)
 {
 	pmap.addNewProperty(
 		new ReadWritePointerProperty<Transform>("localTransform", &lTrf));
 	pmap.addNewProperty(
 		new ReadPointerProperty<Transform>("worldTransform", &wTrf));
-
-	lTrf.setIdentity();
-	wTrf.setIdentity();
-	// Change the wTrf so it wont be the same as lTrf. This means that in the
-	// updateWorldTransform() the "is moved" check will return true
-	wTrf.setScale(0.0);
 }
 
 //==============================================================================
@@ -37,62 +31,31 @@ void Movable::updateWorldTransform()
 {
 	prevWTrf = wTrf;
 	Movable* parent = getParent();
+	uint32_t sceneFramesCount = SceneSingleton::get().getFramesCount();
 
 	if(parent)
 	{
-		if(isFlagEnabled(MF_IGNORE_LOCAL_TRANSFORM))
-		{
-			wTrf = parent->getWorldTransform();
-		}
-		else
+		if(parent->lastUpdateFrame == sceneFramesCount
+			|| lastUpdateFrame == sceneFramesCount)
 		{
-			wTrf = parent->getWorldTransform().getTransformed(lTrf);
-		}
-	}
-	else // else copy
-	{
-		wTrf = lTrf;
-	}
-
-	// Moved?
-	if(prevWTrf != wTrf)
-	{
-		enableFlag(MF_MOVED);
-		movableUpdate();
-	}
-	else
-	{
-		disableFlag(MF_MOVED);
-	}
-
-
-
-	///////////////////
-	if(parent)
-	{
-		if(parent->isFlagEnabled(MF_MOVED) || isFlagEnabled(MF_MOVED))
-		{
-			enableFlag(MF_MOVED);
 			if(isFlagEnabled(MF_IGNORE_LOCAL_TRANSFORM))
 			{
 				wTrf = parent->getWorldTransform();
 			}
 			else
 			{
-				wTrf = parent->getWorldTransform().getTransformed(lTrf);
+				wTrf = Transform::combineTransformations(
+					parent->getWorldTransform(), lTrf);
 			}
+			lastUpdateFrame = sceneFramesCount;
 		}
 	}
-	else
+	else if(lastUpdateFrame == sceneFramesCount)
 	{
-		if(isFlagEnabled(MF_MOVED))
-		{
-			wTrf = lTrf;
-		}
+		wTrf = lTrf;
 	}
-	///////////////////
 
-	if(isFlagEnabled(MF_MOVED))
+	if(lastUpdateFrame == sceneFramesCount)
 	{
 		movableUpdate();
 	}

+ 2 - 2
src/scene/Scene.cpp

@@ -30,7 +30,7 @@ void Scene::unregisterNode(SceneNode* node)
 }
 
 //==============================================================================
-void Scene::update(float prevUpdateTime, float crntTime, int frame)
+void Scene::update(float prevUpdateTime, float crntTime)
 {
 	for(SceneNode* n : nodes)
 	{
@@ -50,7 +50,7 @@ void Scene::doVisibilityTests(Camera& cam)
 {
 	Frustumable* f = cam.getFrustumable();
 	ANKI_ASSERT(f != nullptr);
-	vtester.test(*f, *this, vinfo);
+	vtester.test(*f, *this);
 }
 
 } // end namespace anki

+ 51 - 5
src/scene/VisibilityTester.cpp

@@ -11,9 +11,9 @@ VisibilityTester::~VisibilityTester()
 {}
 
 //==============================================================================
-void VisibilityTester::test(Frustumable& cam, Scene& scene,
-	VisibilityInfo& vinfo, uint32_t testMask)
+void VisibilityTester::test(Frustumable& ref, Scene& scene)
 {
+	VisibilityInfo& vinfo = ref.getVisibilityInfo();
 	vinfo.renderables.clear();
 	vinfo.lights.clear();
 
@@ -23,7 +23,7 @@ void VisibilityTester::test(Frustumable& cam, Scene& scene,
 
 		Frustumable* fr = node->getFrustumable();
 		// Wont check the same
-		if(&cam == fr)
+		if(&ref == fr)
 		{
 			continue;
 		}
@@ -34,9 +34,8 @@ void VisibilityTester::test(Frustumable& cam, Scene& scene,
 			continue;
 		}
 
-		if(!cam.insideFrustum(*sp))
+		if(!ref.insideFrustum(*sp))
 		{
-			sp->disableFlag(Spatial::SF_VISIBLE);
 			continue;
 		}
 
@@ -52,6 +51,53 @@ void VisibilityTester::test(Frustumable& cam, Scene& scene,
 		if(l)
 		{
 			vinfo.lights.push_back(l);
+
+			if(l->getShadowEnabled() && fr)
+			{
+				testLight(*l, scene);
+			}
+		}
+	}
+}
+
+//==============================================================================
+void VisibilityTester::testLight(Light& light, Scene& scene)
+{
+	Frustumable& ref = *light.getFrustumable();
+	ANKI_ASSERT(&ref != nullptr);
+
+	VisibilityInfo& vinfo = ref.getVisibilityInfo();
+	vinfo.renderables.clear();
+	vinfo.lights.clear();
+
+	for(auto it = scene.getAllNodesBegin(); it != scene.getAllNodesEnd(); it++)
+	{
+		SceneNode* node = *it;
+
+		Frustumable* fr = node->getFrustumable();
+		// Wont check the same
+		if(&ref == fr)
+		{
+			continue;
+		}
+
+		Spatial* sp = node->getSpatial();
+		if(!sp)
+		{
+			continue;
+		}
+
+		if(!ref.insideFrustum(*sp))
+		{
+			continue;
+		}
+
+		sp->enableFlag(Spatial::SF_VISIBLE);
+
+		Renderable* r = node->getRenderable();
+		if(r)
+		{
+			vinfo.renderables.push_back(r);
 		}
 	}
 }

+ 12 - 6
testapp/Main.cpp

@@ -91,7 +91,7 @@ void init()
 	point1->setRadius(3.0);
 	point1->setDiffuseColor(Vec4(2.0, 2.0, 2.0, 0.0));
 	point1->setSpecularColor(Vec4(3.0, 3.0, 0.0, 0.0));
-	point1->getLocalTransform().setOrigin(Vec3(-3.0, 2.0, 0.0));
+	point1->setLocalTranslation(Vec3(-3.0, 2.0, 0.0));
 
 	// horse
 	horse = new ModelNode("meshes/horse/horse.mdl", "horse", &scene,
@@ -145,8 +145,14 @@ void mainLoopExtra()
 	if(in.getKey(SDL_SCANCODE_S)) mover->moveLocalZ(dist);
 	if(in.getKey(SDL_SCANCODE_Q)) mover->rotateLocalZ(ang);
 	if(in.getKey(SDL_SCANCODE_E)) mover->rotateLocalZ(-ang);
-	if(in.getKey(SDL_SCANCODE_PAGEUP)) mover->getLocalTransform().getScale() += scale ;
-	if(in.getKey(SDL_SCANCODE_PAGEDOWN)) mover->getLocalTransform().getScale() -= scale ;
+	if(in.getKey(SDL_SCANCODE_PAGEUP))
+	{
+		mover->scale(scale);
+	}
+	if(in.getKey(SDL_SCANCODE_PAGEDOWN))
+	{
+		mover->scale(-scale);
+	}
 }
 
 //==============================================================================
@@ -208,6 +214,7 @@ void main()
 
 	while(1)
 	{
+		SceneSingleton::get().updateFrameStart();
 		HighRezTimer timer;
 		timer.start();
 
@@ -217,8 +224,7 @@ void main()
 		// Update
 		//
 		mainLoopExtra();
-		SceneSingleton::get().update(prevUpdateTime, crntTime,
-			MainRendererSingleton::get().getFramesCount());
+		SceneSingleton::get().update(prevUpdateTime, crntTime);
 		EventManagerSingleton::get().updateAllEvents(prevUpdateTime, crntTime);
 		MainRendererSingleton::get().render(SceneSingleton::get());
 
@@ -261,7 +267,7 @@ void main()
 			break;
 		}
 #endif
-
+		SceneSingleton::get().updateFrameEnd();
 	}
 
 	ANKI_LOGI("Exiting main loop (" << mainLoopTimer.getElapsedTime()