source: trunk/src/engine/ragdoll_manager.cc @ 552

Last change on this file since 552 was 540, checked in by epyon, 8 years ago
  • lua::stack_proxy RTTI read support
  • missing RTTI declarations
  • new lua::table_guard syntax
File size: 3.2 KB
Line 
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
11using namespace nv;
12
13nv::ragdoll_manager::ragdoll_manager( model_manager* model )
14        : m_world( nullptr ), m_model( model )
15{
16
17}
18
19void nv::ragdoll_manager::initialize( lua::state* state )
20{
21        lua_resource_manager< ragdoll_data >::initialize( state );
22}
23
24bool 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
58void nv::ragdoll_manager::release( ragdoll_data* p )
59{
60        for ( auto& part : p->parts )
61                m_world->release( part.shape );
62}
63
64bool 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}
Note: See TracBrowser for help on using the repository browser.