1 #include "xr_skl_motion.h"
2 #include "xr_envelope.h"
3 #include "xr_utils.h"
4 #include "xr_string_utils.h"
5 #include "xr_file_system.h"
6 
7 using namespace xray_re;
8 
xr_bone_motion()9 xr_bone_motion::xr_bone_motion(): m_flags(0)
10 {
11 	std::uninitialized_fill_n(m_envelopes, xr_dim(m_envelopes), static_cast<xr_envelope*>(0));
12 }
13 
xr_bone_motion(const char * name)14 xr_bone_motion::xr_bone_motion(const char* name): m_name(name), m_flags(0)
15 {
16 	std::uninitialized_fill_n(m_envelopes, xr_dim(m_envelopes), static_cast<xr_envelope*>(0));
17 }
18 
~xr_bone_motion()19 xr_bone_motion::~xr_bone_motion()
20 {
21 	delete_envelopes();
22 }
23 
evaluate(float time,fvector3 & t,fvector3 & r) const24 void xr_bone_motion::evaluate(float time, fvector3& t, fvector3& r) const
25 {
26 	t.x = m_envelopes[0]->evaluate(time);
27 	t.y = m_envelopes[1]->evaluate(time);
28 	t.z = m_envelopes[2]->evaluate(time);
29 	r.x = m_envelopes[4]->evaluate(time);
30 	r.y = m_envelopes[3]->evaluate(time);
31 	r.z = m_envelopes[5]->evaluate(time);
32 }
33 
create_envelopes()34 void xr_bone_motion::create_envelopes()
35 {
36 	for (uint_fast32_t i = 6; i != 0;)
37 		m_envelopes[--i] = new xr_envelope;
38 }
39 
delete_envelopes()40 void xr_bone_motion::delete_envelopes()
41 {
42 	for (uint_fast32_t i = 6; i != 0;)
43 		delete m_envelopes[--i];
44 }
45 
load_0(xr_reader & r)46 void xr_bone_motion::load_0(xr_reader& r)
47 {
48 	m_flags = uint8_t(r.r_u32() & UINT8_MAX);
49 	create_envelopes();
50 	for (uint_fast32_t i = 0; i != 6; ++i)
51 		m_envelopes[i]->load_1(r);
52 }
53 
load_1(xr_reader & r)54 void xr_bone_motion::load_1(xr_reader& r)
55 {
56 	r.r_sz(m_name);
57 	m_flags = uint8_t(r.r_u32() & UINT8_MAX);
58 	create_envelopes();
59 	for (uint_fast32_t i = 0; i != 6; ++i)
60 		m_envelopes[i]->load_1(r);
61 }
62 
load_2(xr_reader & r)63 void xr_bone_motion::load_2(xr_reader& r)
64 {
65 	r.r_sz(m_name);
66 	m_flags = r.r_u8();
67 	create_envelopes();
68 	for (uint_fast32_t i = 0; i != 6; ++i)
69 		m_envelopes[i]->load_2(r);
70 }
71 
save(xr_writer & w) const72 void xr_bone_motion::save(xr_writer& w) const
73 {
74 	w.w_sz(m_name);
75 	w.w_u8(m_flags);
76 	for (uint_fast32_t i = 0; i != 6; ++i)
77 		m_envelopes[i]->save(w);
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 
load(xr_reader & r)82 void xr_motion_marks::load(xr_reader& r)
83 {
84 	r.r_s(m_name);
85 	r.r_seq(r.r_u32(), *this);
86 }
87 
save(xr_writer & w) const88 void xr_motion_marks::save(xr_writer& w) const
89 {
90 	w.w_s(m_name);
91 	w.w_size_u32(size());
92 	w.w_seq(*this);
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 
xr_skl_motion()97 xr_skl_motion::xr_skl_motion(): xr_motion(MT_SKELETON),
98 	m_bone_or_part(ALL_PARTITIONS),
99 	m_speed(1.f), m_accrue(2.f), m_falloff(2.f), m_power(1.f),
100 	m_flags(0) {}
101 
~xr_skl_motion()102 xr_skl_motion::~xr_skl_motion()
103 {
104 	delete_elements(m_bone_motions);
105 	delete_elements(m_marks);
106 }
107 
108 struct read_bm_0 {
109 	int index;
read_bm_0read_bm_0110 	read_bm_0(): index(0) {}
operator ()read_bm_0111 	void operator()(xr_bone_motion*& bm, xr_reader& r) {
112 		char name[8];
113 		xr_snprintf(name, sizeof(name), "%d", index++);
114 		bm = new xr_bone_motion(name);
115 		bm->load_0(r);
116 	}
117 };
118 
load(xr_reader & r)119 void xr_skl_motion::load(xr_reader& r)
120 {
121 	xr_motion::load(r);
122 	uint16_t version = r.r_u16();
123 	if (version == SMOTION_VERSION_4) {
124 		m_bone_or_part = r.r_u16();
125 		if (r.r_bool())
126 			m_flags |= SMF_FX;
127 		else
128 			m_flags &= ~SMF_FX;
129 		if (r.r_bool())
130 			m_flags |= SMF_STOP_AT_END;
131 		else
132 			m_flags &= ~SMF_STOP_AT_END;
133 		m_speed = r.r_float();
134 		m_accrue = r.r_float();
135 		m_falloff = r.r_float();
136 		m_power = r.r_float();
137 		r.r_seq(r.r_u32(), m_bone_motions, read_bm_0());
138 	} else if (version == SMOTION_VERSION_5) {
139 		m_flags = r.r_u32();
140 		m_bone_or_part = uint16_t(r.r_u32() & UINT16_MAX);
141 		m_speed = r.r_float();
142 		m_accrue = r.r_float();
143 		m_falloff = r.r_float();
144 		m_power = r.r_float();
145 		r.r_seq(r.r_u32(), m_bone_motions, xr_reader::f_r_new<xr_bone_motion>(&xr_bone_motion::load_1));
146 	} else if (version == SMOTION_VERSION_6) {
147 		m_flags = r.r_u8();
148 		m_bone_or_part = r.r_u16();
149 		m_speed = r.r_float();
150 		m_accrue = r.r_float();
151 		m_falloff = r.r_float();
152 		m_power = r.r_float();
153 		r.r_seq(r.r_u16(), m_bone_motions, xr_reader::f_r_new<xr_bone_motion>(&xr_bone_motion::load_2));
154 	} else if (version == SMOTION_VERSION_7) {
155 		xr_not_implemented();
156 	} else {
157 		xr_not_expected();
158 	}
159 }
160 
save(xr_writer & w) const161 void xr_skl_motion::save(xr_writer& w) const
162 {
163 	xr_motion::save(w);
164 	w.w_u16(SMOTION_VERSION_6);
165 	w.w_u8(uint8_t(m_flags & 0xff));
166 	w.w_u16(m_bone_or_part);
167 	w.w_float(m_speed);
168 	w.w_float(m_accrue);
169 	w.w_float(m_falloff);
170 	w.w_float(m_power);
171 	w.w_size_u16(m_bone_motions.size());
172 	w.w_seq(m_bone_motions, xr_writer::f_w_const<xr_bone_motion>(&xr_bone_motion::save));
173 }
174 
load_skl(const char * path)175 bool xr_skl_motion::load_skl(const char* path)
176 {
177 	xr_file_system& fs = xr_file_system::instance();
178 	xr_reader* r = fs.r_open(path);
179 	if (r == 0)
180 		return false;
181 	xr_reader* s = r->open_chunk(EOBJ_CHUNK_SMOTION);
182 	xr_assert(s);
183 	load(*s);
184 	r->close_chunk(s);
185 	fs.r_close(r);
186 	return true;
187 }
188 
save_skl(const char * path) const189 bool xr_skl_motion::save_skl(const char* path) const
190 {
191 	xr_memory_writer* w = new xr_memory_writer();
192 	w->open_chunk(EOBJ_CHUNK_SMOTION);
193 	save(*w);
194 	w->close_chunk();
195 	bool status = w->save_to(path);
196 	delete w;
197 	return status;
198 }
199 
evaluate(uint16_t bone_id,float time,fvector3 & t,fvector3 & r) const200 void xr_skl_motion::evaluate(uint16_t bone_id, float time, fvector3& t, fvector3& r) const
201 {
202 	m_bone_motions.at(bone_id)->evaluate(time, t, r);
203 }
204