Переглянути джерело

Add the most basic, untested, dirty, inefficient, 100% crash guaranteed sprite animation code

Daniele Bartolini 12 роки тому
батько
коміт
f5ae410d29

+ 29 - 0
engine/lua/LuaSprite.cpp

@@ -110,6 +110,32 @@ CE_EXPORT int sprite_set_local_pose(lua_State* L)
 	return 0;
 }
 
+//-----------------------------------------------------------------------------
+CE_EXPORT int sprite_play_animation(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Sprite* sprite = stack.get_sprite(1);
+	uint32_t start = stack.get_int(2);
+	uint32_t end = stack.get_int(3);
+	float time = stack.get_float(4);
+	bool loop = stack.get_bool(5);
+
+	sprite->play_animation(start, end, time, loop);
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int sprite_stop_animation(lua_State* L)
+{
+	LuaStack stack(L);
+
+	Sprite* sprite = stack.get_sprite(1);
+
+	sprite->stop_animation();
+	return 0;
+}
+
 //-----------------------------------------------------------------------------
 void load_sprite(LuaEnvironment& env)
 {
@@ -119,6 +145,9 @@ void load_sprite(LuaEnvironment& env)
 	env.load_module_function("Sprite", "set_local_position", 	sprite_set_local_position);
 	env.load_module_function("Sprite", "set_local_rotation", 	sprite_set_local_rotation);
 	env.load_module_function("Sprite", "set_local_pose", 		sprite_set_local_pose);
+
+	env.load_module_function("Sprite", "play_animation", 		sprite_play_animation);
+	env.load_module_function("Sprite", "stop_animation", 		sprite_stop_animation);	
 }
 
 } // namespace crown

+ 2 - 2
engine/renderers/RenderWorld.cpp

@@ -216,7 +216,7 @@ Gui* RenderWorld::lookup_gui(GuiId id)
 }
 
 //-----------------------------------------------------------------------------
-void RenderWorld::update(const Matrix4x4& view, const Matrix4x4& projection, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
+void RenderWorld::update(const Matrix4x4& view, const Matrix4x4& projection, uint16_t x, uint16_t y, uint16_t width, uint16_t height, float dt)
 {
 	Renderer* r = device()->renderer();
 
@@ -251,7 +251,7 @@ void RenderWorld::update(const Matrix4x4& view, const Matrix4x4& projection, uin
 	for (uint32_t s = 0; s < m_sprite.size(); s++)
 	{
 		r->set_program(texture_program);
-		m_sprite[s]->render(*r, u_albedo_0);
+		m_sprite[s]->render(*r, u_albedo_0, dt);
 	}
 
 	// Draw all guis

+ 1 - 1
engine/renderers/RenderWorld.h

@@ -76,7 +76,7 @@ public:
 	void		destroy_gui(GuiId id);
 	Gui*		lookup_gui(GuiId id);
 
-	void		update(const Matrix4x4& view, const Matrix4x4& projection, uint16_t x, uint16_t y, uint16_t width, uint16_t height);
+	void		update(const Matrix4x4& view, const Matrix4x4& projection, uint16_t x, uint16_t y, uint16_t width, uint16_t height, float dt);
 
 private:
 

+ 36 - 4
engine/renderers/Sprite.cpp

@@ -44,7 +44,12 @@ Sprite::Sprite(RenderWorld& render_world, SceneGraph& sg, int32_t node, const Sp
 	, m_scene_graph(sg)
 	, m_node(node)
 	, m_resource(sr)
-	, m_frame(0)
+	, m_start_frame(0)
+	, m_cur_frame(0)
+	, m_tot_time(1.0)
+	, m_anim_time(0.0)
+	, m_loop(false)
+	, m_is_playing(false)
 {
 	m_vb = sr->vertex_buffer();
 	m_ib = sr->index_buffer();
@@ -109,11 +114,27 @@ void Sprite::set_local_pose(Unit* unit, const Matrix4x4& pose)
 	unit->set_local_pose(m_node, pose);
 }
 
+//-----------------------------------------------------------------------------
+void Sprite::play_animation(uint32_t start, uint32_t end, float time, bool loop)
+{
+	m_start_frame = start;
+	m_end_frame = end;
+	m_tot_time = time;
+	m_anim_time = 0.0;
+	m_loop = loop;
+}
+
+//-----------------------------------------------------------------------------
+void Sprite::stop_animation()
+{
+	m_cur_frame = 0;
+}
+
 //-----------------------------------------------------------------------------
 void Sprite::set_frame(uint32_t i)
 {
 	CE_ASSERT(i < m_resource->num_frames(), "Frame out of bounds"); 
-	m_frame = i;
+	m_cur_frame = i;
 }
 
 //-----------------------------------------------------------------------------
@@ -123,8 +144,13 @@ void Sprite::set_material(MaterialId mat)
 }
 
 //-----------------------------------------------------------------------------
-void Sprite::render(Renderer& r, UniformId uniform)
+void Sprite::render(Renderer& r, UniformId uniform, float dt)
 {
+	// Compute current frame
+	uint32_t cur_frame = ((m_end_frame - m_start_frame) / m_tot_time) * m_anim_time;
+	m_cur_frame = cur_frame > m_end_frame ? m_end_frame : cur_frame;
+	m_anim_time += dt;
+
 	Material* material = m_render_world.lookup_material(m_material);
 	material->bind(r, uniform);
 
@@ -135,10 +161,16 @@ void Sprite::render(Renderer& r, UniformId uniform)
 		| STATE_BLEND_EQUATION_ADD 
 		| STATE_BLEND_FUNC(STATE_BLEND_FUNC_SRC_ALPHA, STATE_BLEND_FUNC_ONE_MINUS_SRC_ALPHA));
 	r.set_vertex_buffer(m_vb);
-	const uint32_t start_index = m_frame * 6;
+	const uint32_t start_index = m_cur_frame * 6;
 	r.set_index_buffer(m_ib, start_index, 6);
 	r.set_pose(world_pose());
 	r.commit(0);
+
+	if (m_cur_frame == m_end_frame && m_loop)
+	{
+		m_anim_time = 0.0;
+		m_cur_frame = m_start_frame;
+	}
 }
 
 } // namespace crown

+ 16 - 2
engine/renderers/Sprite.h

@@ -59,9 +59,16 @@ struct Sprite
 	void					set_local_rotation(Unit* unit, const Quaternion& rot);
 	void					set_local_pose(Unit* unit, const Matrix4x4& pose);
 
+	/// Plays the animation from frame @a start to frame @a.
+	/// @a time is for how long the animation has to be played.
+	void					play_animation(uint32_t start, uint32_t end, float time, bool loop);
+
+	/// Stops the current animation.
+	void					stop_animation();
+
 	void					set_frame(uint32_t i);
 	void					set_material(MaterialId mat);
-	void					render(Renderer& r, UniformId uniform);
+	void					render(Renderer& r, UniformId uniform, float dt);
 
 public:
 
@@ -69,7 +76,14 @@ public:
 	SceneGraph&				m_scene_graph;	
 	int32_t					m_node;
 	const SpriteResource*	m_resource;
-	uint32_t				m_frame;
+
+	uint32_t				m_start_frame;
+	uint32_t				m_cur_frame;
+	uint32_t				m_end_frame;
+	float 					m_tot_time;
+	float					m_anim_time;
+	bool					m_loop;
+	bool					m_is_playing;
 
 	MaterialId				m_material;
 	VertexBufferId			m_vb;

+ 10 - 1
engine/world/World.cpp

@@ -37,6 +37,7 @@ namespace crown
 World::World()
 	: m_unit_pool(default_allocator(), MAX_UNITS, sizeof(Unit), CE_ALIGNOF(Unit))
 	, m_camera_pool(default_allocator(), MAX_CAMERAS, sizeof(Camera), CE_ALIGNOF(Camera))
+	, m_events(default_allocator())
 {
 	m_id.id = INVALID_ID;
 	m_sound_world = SoundWorld::create(default_allocator());
@@ -83,6 +84,10 @@ UnitId World::spawn_unit(UnitResource* ur, const Vector3& pos, const Quaternion&
 	const UnitId unit_id = m_units.create(unit);
 	unit->set_id(unit_id);
 
+	// SpawnUnitEvent ev;
+	// ev.unit = unit_id;
+	// event_stream::write(m_events, EventType::SPAWN, ev);
+
 	return unit_id;
 }
 
@@ -93,6 +98,10 @@ void World::destroy_unit(UnitId id)
 
 	CE_DELETE(m_unit_pool, m_units.lookup(id));
 	m_units.destroy(id);
+
+	// DestroyUnitEvent ev;
+	// ev.unit = id;
+	// event_stream::write(m_events, EventType::DESTROY, ev);
 }
 
 //-----------------------------------------------------------------------------
@@ -163,7 +172,7 @@ void World::update(float dt)
 void World::render(Camera* camera)
 {
 	m_render_world.update(camera->world_pose(), camera->m_projection, camera->m_view_x, camera->m_view_y,
-							camera->m_view_width, camera->m_view_height);
+							camera->m_view_width, camera->m_view_height, device()->last_delta_time());
 }
 
 //-----------------------------------------------------------------------------

+ 3 - 0
engine/world/World.h

@@ -40,6 +40,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Vector.h"
 #include "WorldTypes.h"
 #include "SoundWorld.h"
+#include "EventStream.h"
 
 namespace crown
 {
@@ -114,6 +115,8 @@ private:
 	SoundWorld*							m_sound_world;
 
 	WorldId								m_id;
+
+	EventStream							m_events;
 };
 
 } // namespace crown