Browse Source

Physics & scene work

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
1ba97bc74f

+ 42 - 13
include/anki/physics/MotionState.h

@@ -1,38 +1,67 @@
 #ifndef ANKI_PHYSICS_MOTION_STATE_H
 #define ANKI_PHYSICS_MOTION_STATE_H
 
-#include "anki/scene/MoveComponent.h"
+#include "anki/Math.h"
+#include "anki/physics/Converters.h"
 #include <LinearMath/btMotionState.h>
 
 namespace anki {
 
-/// A custom motion state
+/// A custom and generic bullet motion state
 class MotionState: public btMotionState
 {
 public:
-	MotionState();
-	MotionState(const Transform& initialTransform, MoveComponent* node);
+	MotionState()
+		: MotionState(toBt(Transform::getIdentity()))
+	{}
+
+	MotionState(const btTransform& worldTransform_)
+		: worldTransform(worldTransform_), updated(false)
+	{}
 
 	~MotionState()
 	{}
 
-	MotionState& operator=(const MotionState& b);
+	MotionState& operator=(const MotionState& b)
+	{
+		worldTransform = b.worldTransform;
+		updated = b.updated;
+		return *this;
+	}
+
+	/// @name Accessors
+	/// @{
+	Bool getUpdated() const
+	{
+		return updated;
+	}
+	void setUpdated(Bool x)
+	{
+		updated = x;
+	}
+	const btTransform& getWorldTransform2() const
+	{
+		return worldTransform;
+	}
+	/// @}
 
 	/// @name Bullet implementation of virtuals
 	/// @{
-	void getWorldTransform(btTransform& worldTrans) const;
+	void getWorldTransform(btTransform& out) const
+	{
+		out = worldTransform;
+	}
 
-	void setWorldTransform(const btTransform& worldTrans);
+	void setWorldTransform(const btTransform& in)
+	{
+		worldTransform = in;
+		updated = true;
+	}
 	/// @}
 
-	/// This function will actualy update the transform of the node. It is 
-	/// called
-	void sync();
-
 private:
 	btTransform worldTransform;
-	MoveComponent* node; ///< Pointer cause it may be NULL
-	Bool8 needsUpdate;
+	Bool8 updated;
 };
 
 } // end namespace anki

+ 6 - 2
include/anki/physics/RigidBody.h

@@ -2,6 +2,7 @@
 #define ANKI_PHYSICS_RIGID_BODY_H
 
 #include "anki/physics/PhysicsObject.h"
+#include "anki/scene/SceneComponent.h"
 #include "anki/Math.h"
 #include "anki/physics/MotionState.h"
 #include <btBulletDynamicsCommon.h>
@@ -12,7 +13,8 @@ namespace anki {
 class MoveComponent;
 
 /// Wrapper for rigid body
-class RigidBody: public PhysicsObject, public btRigidBody
+class RigidBody: public PhysicsObject, public btRigidBody, 
+	public SceneComponent
 {
 	friend class PhysicsWorld;
 
@@ -23,9 +25,9 @@ public:
 		F32 mass = 0.0;
 		Transform startTrf = Transform::getIdentity();
 		btCollisionShape* shape = nullptr;
-		MoveComponent* movable = nullptr;
 		I32 group = -1;
 		I32 mask = -1;
+		Bool kinematic = false;
 	};
 
 	/// Init and register. Only the PhysicsWorld can construct it
@@ -34,6 +36,8 @@ public:
 	/// Unregister. Only the PhysicsWorld can destroy it
 	~RigidBody();
 
+	void syncUpdate(SceneNode& node, F32 prevTime, F32 crntTime);
+
 private:
 	MotionState motionState;
 };

+ 39 - 0
include/anki/scene/SceneComponent.h

@@ -0,0 +1,39 @@
+#ifndef ANKI_SCENE_SCENE_COMPONENT_H
+#define ANKI_SCENE_SCENE_COMPONENT_H
+
+#include "anki/scene/Common.h"
+#include "anki/core/Timestamp.h"
+
+namespace anki {
+
+/// Scene node component
+class SceneComponent
+{
+public:
+	/// Do some updating on the thread safe sync section
+	virtual void syncUpdate(SceneNode& node, F32 prevTime, F32 crntTime)
+	{}
+
+	/// Do some updating
+	virtual void update(SceneNode& node, F32 prevTime, F32 crntTime)
+	{}
+
+	/// Called only by the SceneGraph
+	void updateReal(SceneNode& node, F32 prevTime, F32 crntTime)
+	{
+		update(node, prevTime, crntTime);
+		timestamp = getTimestamp();
+	}
+
+	Timestamp getTimestamp() const
+	{
+		return timestamp;
+	}
+
+private:
+	Timestamp timestamp;
+};
+
+} // end namespace anki
+
+#endif

+ 4 - 0
src/physics/Character.cpp

@@ -11,6 +11,8 @@
 
 namespace anki {
 
+#if 0
+
 //==============================================================================
 // Character::Initializer                                                      = 
 //==============================================================================
@@ -108,4 +110,6 @@ void Character::jump()
 	character->jump();
 }
 
+#endif
+
 } // end namespace

+ 0 - 63
src/physics/MotionState.cpp

@@ -1,63 +0,0 @@
-#include "anki/physics/MotionState.h"
-#include "anki/physics/Converters.h"
-
-namespace anki {
-
-//==============================================================================
-MotionState::MotionState()
-{
-	worldTransform = toBt(Transform::getIdentity());
-	node = nullptr;
-	needsUpdate = true;
-}
-
-//==============================================================================
-MotionState::MotionState(const Transform& initialTransform, 
-	MoveComponent* node_)
-	: worldTransform(toBt(initialTransform)), node(node_)
-{
-	needsUpdate = true;
-}
-
-//==============================================================================
-MotionState& MotionState::operator=(const MotionState& b)
-{
-	worldTransform = b.worldTransform;
-	node = b.node;
-	return *this;
-}
-
-//==============================================================================
-void MotionState::getWorldTransform(btTransform& worldTrans) const
-{
-	worldTrans = worldTransform;
-}
-
-//==============================================================================
-void MotionState::setWorldTransform(const btTransform& worldTrans)
-{
-	worldTransform = worldTrans;
-	needsUpdate = true;
-
-	/// XXX
-	sync();
-}
-
-//==============================================================================
-void MotionState::sync()
-{
-	if(node && needsUpdate)
-	{
-		// Set local transform and preserve scale
-		Transform newTrf;
-		F32 originalScale = node->getLocalTransform().getScale();
-		newTrf = toAnki(worldTransform);
-		newTrf.setScale(originalScale);
-		node->setLocalTransform(newTrf);
-
-		// Set the flag
-		needsUpdate = false;
-	}
-}
-
-} // end namespace anki

+ 53 - 2
src/physics/RigidBody.cpp

@@ -1,7 +1,7 @@
 #include "anki/physics/RigidBody.h"
 #include "anki/physics/PhysicsWorld.h"
 #include "anki/scene/SceneGraph.h"
-#include "anki/physics/MotionState.h"
+#include "anki/scene/MoveComponent.h"
 
 namespace anki {
 
@@ -26,7 +26,7 @@ RigidBody::RigidBody(PhysicsWorld* world, const Initializer& init)
 		localInertia = btVector3(0.0, 0.0, 0.0);
 	}
 
-	motionState = MotionState(init.startTrf, init.movable);
+	motionState = MotionState(toBt(init.startTrf));
 
 	btRigidBody::btRigidBodyConstructionInfo cInfo(
 		init.mass, &motionState, init.shape, localInertia);
@@ -36,6 +36,11 @@ RigidBody::RigidBody(PhysicsWorld* world, const Initializer& init)
 	setContactProcessingThreshold(
 		getPhysicsWorld().defaultContactProcessingThreshold);
 
+	if(init.kinematic)
+	{
+		// XXX
+	}
+
 	//forceActivationState(ISLAND_SLEEPING);
 
 	// register
@@ -56,4 +61,50 @@ RigidBody::~RigidBody()
 	getPhysicsWorld().dynamicsWorld->removeRigidBody(this);
 }
 
+//==============================================================================
+void RigidBody::syncUpdate(SceneNode& node, F32 prevTime, F32 crntTime)
+{
+	MoveComponent* move = node.getMoveComponent();
+	if(ANKI_UNLIKELY(move == nullptr))
+	{
+		return;
+	}
+
+	Bool updated = move->bitsEnabled(MoveComponent::MF_MARKED_FOR_UPDATE);
+	Transform oldTrf = move->getLocalTransform();
+
+	// Sync from motion state to move component
+	if(motionState.getUpdated())
+	{
+		// Set local transform and preserve scale
+		Transform newTrf;
+		F32 originalScale = move->getLocalTransform().getScale();
+		newTrf = toAnki(motionState.getWorldTransform2());
+		newTrf.setScale(originalScale);
+		std::cout << newTrf.getOrigin().toString() << std::endl;
+		move->setLocalTransform(newTrf);
+
+		// Set the flag
+		motionState.setUpdated(false);
+
+		std::cout << "From motion state to move component" << std::endl;
+	}
+
+	// Sync from move component to motion state
+	if(updated)
+	{
+		std::cout << "Activating again " << oldTrf.getOrigin().toString() << std::endl;
+
+		setWorldTransform(toBt(oldTrf));
+		//motionState.setWorldTransform(toBt(oldTrf));
+		//forceActivationState(ACTIVE_TAG);
+		activate();
+		//clearForces();
+		//setLinearVelocity(btVector3(0.0, 0.0, 0.0));
+		//setAngularVelocity(btVector3(0.0, 0.0, 0.0));
+
+		//setGravity(getPhysicsWorld().dynamicsWorld->getGravity());
+	}
+}
+
 } // end namespace anki

+ 0 - 1
src/scene/ModelNode.cpp

@@ -202,7 +202,6 @@ ModelNode::ModelNode(
 		init.mass = 1.0;
 		init.shape = const_cast<btCollisionShape*>(model->getCollisionShape());
 		init.startTrf.getOrigin().y() = 20.0;
-		init.movable = this;
 
 		RigidBody* body;
 		

+ 0 - 1
src/scene/ParticleEmitter.cpp

@@ -135,7 +135,6 @@ Particle::Particle(
 	:	ParticleBase(name, scene, PT_PHYSICS)
 {
 	RigidBody::Initializer init = init_;
-	init.movable = this;
 
 	getSceneGraph().getPhysics().newPhysicsObject<RigidBody>(body, init);
 

+ 13 - 1
src/scene/SceneGraph.cpp

@@ -6,6 +6,7 @@
 #include "anki/core/Counters.h"
 #include "anki/renderer/Renderer.h"
 #include "anki/misc/Xml.h"
+#include "anki/physics/RigidBody.h"
 
 namespace anki {
 
@@ -224,7 +225,18 @@ void SceneGraph::update(F32 prevUpdateTime, F32 crntTime, Renderer& renderer)
 	// Sync point. Here we wait for all scene's threads
 	//
 
-	// XXX
+	iterateSceneNodes([&](SceneNode& sn)
+	{
+		RigidBody* body = sn.getRigidBody();
+		if(body)
+		{
+			MoveComponent* move = sn.getMoveComponent();
+			if(move)
+			{
+				body->syncUpdate(sn, prevUpdateTime, crntTime);
+			}
+		}
+	});
 
 	//
 	// Reset the frame mem pool

+ 7 - 2
testapp/Main.cpp

@@ -365,8 +365,13 @@ void mainLoopExtra()
 
 	if(in.getKey(KC_L) == 1)
 	{
-		Light* l = SceneGraphSingleton::get().findSceneNode("point1").getLight();
-		static_cast<PointLight*>(l)->setRadius(10.0);
+		SceneNode& l = 
+			SceneGraphSingleton::get().findSceneNode("crate");
+		
+		Transform trf;
+		trf.setIdentity();
+		trf.getOrigin().y() = 20.0;
+		l.getMoveComponent()->setLocalTransform(trf);
 	}
 
 	if(in.getKey(KC_F1) == 1)