1 | // Copyright (C) 2016-2016 ChaosForge Ltd
|
---|
2 | // http://chaosforge.org/
|
---|
3 | //
|
---|
4 | // This file is part of Nova libraries.
|
---|
5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
6 |
|
---|
7 | #include "nv/engine/ragdoll_manager.hh"
|
---|
8 |
|
---|
9 | #include "nv/lua/lua_math.hh"
|
---|
10 |
|
---|
11 | using namespace nv;
|
---|
12 |
|
---|
13 | nv::ragdoll_manager::ragdoll_manager( model_manager* model )
|
---|
14 | : m_world( nullptr ), m_model( model )
|
---|
15 | {
|
---|
16 |
|
---|
17 | }
|
---|
18 |
|
---|
19 | void nv::ragdoll_manager::initialize( lua::state* state )
|
---|
20 | {
|
---|
21 | lua_resource_manager< ragdoll_data >::initialize( state );
|
---|
22 | }
|
---|
23 |
|
---|
24 | bool nv::ragdoll_manager::load_resource( lua::table_guard& table, shash64 id )
|
---|
25 | {
|
---|
26 | NV_ASSERT_ALWAYS( m_world, "Physics world not setup in ragdoll_manager!" );
|
---|
27 | bool result = false;
|
---|
28 | nv::string64 model_id = table["model"].get_string64();
|
---|
29 | nv::resource< model > mr = m_model->get( model_id );
|
---|
30 | if ( !mr ) return false;
|
---|
31 | nv::resource< animator_bind_data > bindr;
|
---|
32 | if ( auto m = mr.lock() )
|
---|
33 | bindr = mr.lock()->bind_data;
|
---|
34 | if ( !bindr ) return false;
|
---|
35 |
|
---|
36 | ragdoll_data* d = new ragdoll_data;
|
---|
37 | {
|
---|
38 | nv::lua::table_guard root( table, 1 );
|
---|
39 | result = load_ragdoll( root, bindr, d, -1 );
|
---|
40 | }
|
---|
41 | if ( result )
|
---|
42 | {
|
---|
43 | if ( auto bind = bindr.lock() )
|
---|
44 | {
|
---|
45 | const nv::data_node_list& bl = bind->get_bone_list();
|
---|
46 | d->bone_mask.resize( bl.size(), true );
|
---|
47 | for ( nv::uint32 i = 1; i < d->parts.size(); ++i )
|
---|
48 | {
|
---|
49 | d->bone_mask[d->parts[i].bone_id] = false;
|
---|
50 | }
|
---|
51 | }
|
---|
52 |
|
---|
53 | add( id, d );
|
---|
54 | }
|
---|
55 | return result;
|
---|
56 | }
|
---|
57 |
|
---|
58 | void nv::ragdoll_manager::release( ragdoll_data* p )
|
---|
59 | {
|
---|
60 | for ( auto& part : p->parts )
|
---|
61 | m_world->release( part.shape );
|
---|
62 | }
|
---|
63 |
|
---|
64 | bool nv::ragdoll_manager::load_ragdoll( lua::table_guard& table, resource< animator_bind_data > rbind, ragdoll_data* data, int pindex )
|
---|
65 | {
|
---|
66 | if ( auto bind_data = rbind.lock() )
|
---|
67 | {
|
---|
68 | data->id = table["id"].get_string32();
|
---|
69 | int index = data->parts.size();
|
---|
70 | data->parts.emplace_back();
|
---|
71 | auto& part = data->parts.back();
|
---|
72 | part.name = table["name"].get_shash64();
|
---|
73 | part.bone_id = nv::uint32( bind_data->get_bone_list().resolve( table["bone"].get_shash64() ) );
|
---|
74 | NV_ASSERT( part.bone_id < 256, "Bone ID not found!" );
|
---|
75 | float radius = table["radius"].get_f32();
|
---|
76 | float length = 0.0f;
|
---|
77 | if ( table[ "target" ] )
|
---|
78 | {
|
---|
79 | const auto& of = bind_data->get_bone_transforms().m_offsets;
|
---|
80 | int target = bind_data->get_bone_list().resolve( table["target"].get_shash64() );
|
---|
81 | if ( target < 0 ) return false;
|
---|
82 | length = math::distance( of[part.bone_id].get_position(), of[target].get_position() );
|
---|
83 | }
|
---|
84 | else
|
---|
85 | {
|
---|
86 | length = table["length"].get_f32();
|
---|
87 | }
|
---|
88 | NV_ASSERT( radius > 0.0f && length > 0.0f, "Bad parameters!" );
|
---|
89 | part.shape = m_world->create_capsule( radius, length );
|
---|
90 | part.parent_idx = pindex;
|
---|
91 | part.mass = table["mass"].get_f32( 1.0f );
|
---|
92 | part.cone_twist = false;
|
---|
93 | // Joints
|
---|
94 | if ( pindex != -1 )
|
---|
95 | {
|
---|
96 | part.cone_twist = table["joint"].get_shash64() == shash64( "cone_twist"_ls );
|
---|
97 | part.limits = table["limits"].as< vec3 >();
|
---|
98 | }
|
---|
99 | uint32 child_count = table.size();
|
---|
100 | bool result = true;
|
---|
101 | if ( child_count > 0 )
|
---|
102 | {
|
---|
103 | for( uint32 i = 1; i <= child_count; ++i )
|
---|
104 | {
|
---|
105 | lua::table_guard child_table( table, i );
|
---|
106 | result = load_ragdoll( child_table, rbind, data, index );
|
---|
107 | if ( !result ) return false;
|
---|
108 | }
|
---|
109 | }
|
---|
110 | return result;
|
---|
111 | }
|
---|
112 | return false;
|
---|
113 | }
|
---|