1 #include <limits>
2 #include <algorithm>
3 #include "actor_init.h"
4 #include "load_gl_extensions.h"
5 #include <cal3d/cal3d.h>
6 #include <map>
7 #include "bbox_tree.h"
8 #include "io/elfilewrapper.h"
9 #include "gl_init.h"
10 #include "shadows.h"
11 #include "map.h"
12 #include "optimizer.hpp"
13 #include "md5.h"
14 #include "errors.h"
15 
16 Uint32 use_animation_program = 1;
17 Uint32 max_bones_per_mesh = 27;
18 
19 class HardwareMeshData
20 {
21 	private:
22 		const Sint32 m_mesh_index;
23 		const Uint32 m_size;
24 		float* m_buffer;
25 
26 		const HardwareMeshData &operator=(const HardwareMeshData &hmd);
27 
28 	public:
HardwareMeshData(const Sint32 mesh_index,const Uint32 size)29 		inline HardwareMeshData(const Sint32 mesh_index,
30 			const Uint32 size): m_mesh_index(mesh_index),
31 			m_size(size)
32 		{
33 			m_buffer = new float[m_size * 4];
34 		}
35 
HardwareMeshData(const HardwareMeshData & hmd)36 		inline HardwareMeshData(const HardwareMeshData &hmd):
37 			m_mesh_index(hmd.m_mesh_index), m_size(hmd.m_size)
38 		{
39 			m_buffer = new float[m_size * 4];
40 			memcpy(m_buffer, hmd.m_buffer,
41 				sizeof(float) * 4 * m_size);
42 		}
43 
~HardwareMeshData()44 		inline ~HardwareMeshData()
45 		{
46 			delete[] m_buffer;
47 		}
48 
set_buffer_value(const Uint32 index,const float value)49 		inline void set_buffer_value(const Uint32 index, const float value)
50 		{
51 			m_buffer[index] = value;
52 		}
53 
get_buffer(const Uint32 index=0) const54 		inline float* get_buffer(const Uint32 index = 0) const
55 		{
56 			return &m_buffer[index];
57 		}
58 
get_size() const59 		inline Uint32 get_size() const
60 		{
61 			return m_size;
62 		}
63 
get_mesh_index() const64 		inline Sint32 get_mesh_index() const
65 		{
66 			return m_mesh_index;
67 		}
68 };
69 
70 struct ActorVertex
71 {
72 	float m_vertex[3];
73 	Uint8 m_weight[4];
74 	float m_normal[3];
75 	Uint8 m_index[4];
76 	float m_texture[2];
77 //	float m_bone_count;
78 };
79 
80 typedef std::map<Sint32, HardwareMeshData> IntMap;
81 
82 int last_actor_type = -1;
83 bool use_normals;
84 
85 GLuint vertex_program_ids[5];
86 
load_vertex_program(const std::string & name)87 static inline GLuint load_vertex_program(const std::string &name)
88 {
89 	GLuint id;
90 	GLint support;
91 	el_file_ptr file;
92 	std::string str;
93 	std::stringstream s1;
94 	std::stringstream s2;
95 	size_t pos;
96 
97 	file = el_open(name.c_str());
98 
99 	if ((el_get_pointer(file) == 0) || (el_get_size(file) == 0))
100 	{
101 		use_animation_program = 0;
102 
103 		return 0;
104 	}
105 
106 	str = std::string(reinterpret_cast<char*>(el_get_pointer(file)), el_get_size(file));
107 
108 	el_close(file);
109 
110 	ELglGenProgramsARB(1, &id);
111 	ELglBindProgramARB(GL_VERTEX_PROGRAM_ARB, id);
112 
113 	s1 << (max_bones_per_mesh * 3);
114 	pos = str.find("%d");
115 	if (pos == str.npos)
116 	{
117 		LOG_ERROR("File '%s' is invalid.", name.c_str());
118 		return 0;
119 	}
120 	str.replace(pos, 2, s1.str());
121 	s2 << (max_bones_per_mesh * 3 - 1);
122 	pos = str.find("%d");
123 	if (pos == str.npos)
124 	{
125 		use_animation_program = 0;
126 
127 		LOG_ERROR("File '%s' is invalid.", name.c_str());
128 
129 		return 0;
130 	}
131 	str.replace(pos, 2, s2.str());
132 
133 	ELglProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
134 		str.size(), str.c_str());
135 
136 	if (glGetError() != GL_NO_ERROR)
137 	{
138 		use_animation_program = 0;
139 
140 		LOG_ERROR("GL error at actor animation program");
141 
142 		return 0;
143 	}
144 
145 
146 	ELglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &support);
147 
148 	if (support != GL_TRUE)
149 	{
150 		use_animation_program = 0;
151 
152 		LOG_ERROR("Actor animation program not supported by OpenGL");
153 
154 		return 0;
155 	}
156 
157 	ELglBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0);
158 
159 	return id;
160 }
161 
unload_vertex_programs()162 extern "C" void unload_vertex_programs()
163 {
164 	ELglDeleteProgramsARB(5, vertex_program_ids);
165 
166 	memset(vertex_program_ids, 0, sizeof(vertex_program_ids));
167 }
168 
render_mesh_shader(actor_types * a,actor * act,Sint32 index,const HardwareMeshData & hmd,const bool use_glow)169 static inline void render_mesh_shader(actor_types *a, actor *act, Sint32 index, const HardwareMeshData &hmd, const bool use_glow)
170 {
171 	Uint32 element_index, count, i;
172 	Sint32 bone_id, glow;
173 	float reverse_scale;
174 	CalSkeleton *skel;
175 
176 	if (index >= 0)
177 	{
178 		bone_id = -1;
179 		glow = -1;
180 
181 		if (act->is_enhanced_model)
182 		{
183 			if (act->cur_shield >= 0)
184 			{
185 				if ((Sint32)a->shield[act->cur_shield].mesh_index == hmd.get_mesh_index())
186 				{
187 					bone_id = 21;
188 					glow = a->shield[act->cur_shield].glow;
189 				}
190 			}
191 			if (act->cur_weapon >= 0)
192 			{
193 				if ((Sint32)a->weapon[act->cur_weapon].mesh_index == hmd.get_mesh_index())
194 				{
195 					bone_id = 26;
196 					glow = a->weapon[act->cur_weapon].glow;
197 				}
198 			}
199 		}
200 
201 		if (use_glow)
202 		{
203 			if (glow > 0)
204 			{
205 				ELglVertexAttrib4f(4, glow_colors[glow].r * 3.0f,
206 					glow_colors[glow].g * 3.0f, glow_colors[glow].b * 3.0f, 1.0f);
207 			}
208 			else
209 			{
210 				if (act->ghost || (act->buffs & BUFF_INVISIBILITY))
211 				{
212 					if ((act->buffs & BUFF_INVISIBILITY))
213 					{
214 						ELglVertexAttrib4f(4, 1.0f, 1.0f, 1.0f, 0.25f);
215 					}
216 					else
217 					{
218 						ELglVertexAttrib4f(4, 1.0f, 1.0f, 1.0f, 1.0f);
219 					}
220 				}
221 				else
222 				{
223 					ELglVertexAttrib4f(4, -1.0f, -1.0f, -1.0f, -1.0f);
224 				}
225 			}
226 		}
227 
228 		a->hardware_model->selectHardwareMesh(index);
229 
230 		count = a->hardware_model->getBoneCount() * 3;
231 		for (i = 0; i < count; i++)
232 		{
233 			ELglProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i,
234 				hmd.get_buffer(i * 4));
235 		}
236 
237 		if (bone_id != -1)
238 		{
239 			glPushMatrix();
240 			reverse_scale = 1.0f / a->skel_scale;
241 
242 			skel = act->calmodel->getSkeleton();
243 
244 			const CalVector &point = skel->getBone(bone_id)->getTranslationAbsolute();
245 
246 			glTranslatef(point[0], point[1], point[2]);
247 			glScalef(reverse_scale, reverse_scale, reverse_scale);
248 			glTranslatef(-point[0], -point[1], -point[2]);
249 
250 		}
251 
252 		element_index = a->hardware_model->getStartIndex() * a->index_size;
253 
254 		glDrawElements(GL_TRIANGLES, a->hardware_model->getFaceCount() * 3, a->index_type,
255 			reinterpret_cast<void*>(element_index));
256 
257 		if (bone_id != -1)
258 		{
259 			glPopMatrix();
260 		}
261 	}
262 }
263 
set_actor_animation_program(Uint32 pass,Uint32 ghost)264 extern "C" void set_actor_animation_program(Uint32 pass, Uint32 ghost)
265 {
266 	Uint32 index, i;
267 	VECTOR4 zero;
268 	VECTOR4 one;
269 
270 	switch (pass)
271 	{
272 		case DEFAULT_RENDER_PASS:
273 		{
274 			if (ghost != 0)
275 			{
276 				index = 3;
277 			}
278 			else
279 			{
280 				index = 0;
281 			}
282 
283 			use_normals = ghost == 0;
284 
285 			break;
286 		}
287 		case REFLECTION_RENDER_PASS:
288 		{
289 			assert(ghost == 0);
290 
291 			index = 0;
292 
293 			use_normals = ghost == 0;
294 
295 			break;
296 		}
297 		case DEPTH_RENDER_PASS:
298 		{
299 			assert(ghost == 0);
300 
301 			index = 1;
302 
303 			use_normals = false;
304 
305 			break;
306 		}
307 		case SHADOW_RENDER_PASS:
308 		{
309 			if (ghost != 0)
310 			{
311 				index = 4;
312 			}
313 			else
314 			{
315 				index = 2;
316 			}
317 
318 			use_normals = ghost == 0;
319 
320 			break;
321 		}
322 		default:
323 		{
324 			index = 0;
325 			break;
326 		}
327 	}
328 
329 	zero[0] = 0.0f;
330 	zero[1] = 0.0f;
331 	zero[2] = 0.0f;
332 	zero[3] = 0.0f;
333 
334 	one[0] = 1.0f;
335 	one[1] = 1.0f;
336 	one[2] = 1.0f;
337 	one[3] = 1.0f;
338 
339 	for (i = 0; i < 8; i++)
340 	{
341 		if (glIsEnabled(GL_LIGHT0 + i) == GL_FALSE)
342 		{
343 			glLightfv(GL_LIGHT0 + i, GL_POSITION, one);
344 			glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, zero);
345 			glLightfv(GL_LIGHT0 + i, GL_SPECULAR, zero);
346 			glLightfv(GL_LIGHT0 + i, GL_AMBIENT, zero);
347 		}
348 		glLightf(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, 1.0f);
349 		glLightf(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, 0.0f);
350 	}
351 
352 	glEnable(GL_VERTEX_PROGRAM_ARB);
353 
354 	ELglEnableVertexAttribArrayARB(0);
355 	ELglEnableVertexAttribArrayARB(1);
356 	ELglEnableVertexAttribArrayARB(3);
357 
358 	ELglBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertex_program_ids[index]);
359 }
360 
disable_actor_animation_program()361 extern "C" void disable_actor_animation_program()
362 {
363 	ELglBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0);
364 
365 	ELglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
366 	ELglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
367 
368 	ELglDisableVertexAttribArrayARB(0);
369 	ELglDisableVertexAttribArrayARB(1);
370 	ELglDisableVertexAttribArrayARB(2);
371 	ELglDisableVertexAttribArrayARB(3);
372 	ELglDisableVertexAttribArrayARB(8);
373 
374 	glDisable(GL_VERTEX_PROGRAM_ARB);
375 
376 	last_actor_type = -1;
377 
378 }
379 
load_vertex_programs()380 extern "C" int load_vertex_programs()
381 {
382 	GLint t0, t1, max_instructions;
383 
384 #ifdef OSX
385 	ELglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &t0);
386 #else
387 	ELglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_PARAMETERS_ARB, &t0);
388 #endif
389 	ELglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &t1);
390 
391 	ELglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB,
392 		&max_instructions);
393 	max_bones_per_mesh = (std::min(t0 - 43, t1)) / 3;
394 
395 	if (max_bones_per_mesh < 17)
396 	{
397 		return 0;
398 	}
399 
400 	vertex_program_ids[0] = load_vertex_program("shaders/anim.vert");
401 	vertex_program_ids[1] = load_vertex_program("shaders/anim_depth.vert");
402 	vertex_program_ids[2] = load_vertex_program("shaders/anim_shadow.vert");
403 	vertex_program_ids[3] = load_vertex_program("shaders/anim_ghost.vert");
404 	vertex_program_ids[4] = load_vertex_program("shaders/anim_ghost_shadow.vert");
405 
406 	if ((vertex_program_ids[0] == 0) || (vertex_program_ids[1] == 0) ||
407 		(vertex_program_ids[2] == 0) || (vertex_program_ids[3] == 0) ||
408 		(vertex_program_ids[4] == 0))
409 	{
410 		return 0;
411 	}
412 	else
413 	{
414 		return 1;
415 	}
416 }
417 
cal_render_actor_shader(actor * act,Uint32 use_lightning,Uint32 use_textures,Uint32 use_glow)418 extern "C" void cal_render_actor_shader(actor *act, Uint32 use_lightning, Uint32 use_textures, Uint32 use_glow)
419 {
420 	actor_types* a;
421 	IntMap* im;
422 	float s;
423 
424 	assert(act->calmodel);
425 
426 	s = get_actor_scale(act);
427 
428 	if (s != 1.0f)
429 	{
430 		glScalef(s, s, s);
431 	}
432 
433 	a = &actors_defs[act->actor_type];
434 
435 	if (last_actor_type != act->actor_type)
436 	{
437 		ELglBindBufferARB(GL_ARRAY_BUFFER_ARB, a->vertex_buffer);
438 		ELglVertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, sizeof(ActorVertex),
439 			reinterpret_cast<void*>(0 * sizeof(float) + 0 * sizeof(Uint8)));
440 		ELglVertexAttribPointerARB(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ActorVertex),
441 			reinterpret_cast<void*>(3 * sizeof(float) + 0 * sizeof(Uint8)));
442 		if (use_normals && use_lightning)
443 		{
444 			ELglEnableVertexAttribArrayARB(2);
445 			ELglVertexAttribPointerARB(2, 3, GL_FLOAT, GL_FALSE, sizeof(ActorVertex),
446 				reinterpret_cast<void*>(3 * sizeof(float) + 4 * sizeof(Uint8)));
447 		}
448 		else
449 		{
450 			ELglDisableVertexAttribArrayARB(2);
451 		}
452 		ELglVertexAttribPointerARB(3, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(ActorVertex),
453 			reinterpret_cast<void*>(6 * sizeof(float) + 4 * sizeof(Uint8)));
454 		if (use_textures)
455 		{
456 			ELglEnableVertexAttribArrayARB(8);
457 			ELglVertexAttribPointerARB(8, 2, GL_FLOAT, GL_FALSE, sizeof(ActorVertex),
458 				reinterpret_cast<void*>(6 * sizeof(float) + 8 * sizeof(Uint8)));
459 		}
460 		else
461 		{
462 			ELglDisableVertexAttribArrayARB(8);
463 		}
464 		ELglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, a->index_buffer);
465 		last_actor_type = act->actor_type;
466 	}
467 
468 	im = reinterpret_cast<IntMap*>(act->calmodel->getUserData());
469 
470 	assert(im);
471 
472 	for (const auto& it: *im)
473 	{
474 		render_mesh_shader(a, act, it.first, it.second, use_glow);
475 	}
476 }
477 
calculate_face_and_vertex_count(CalCoreModel * core_model,Uint32 & face_count,Uint32 & vertex_count)478 static inline void calculate_face_and_vertex_count(CalCoreModel* core_model, Uint32 &face_count,
479 	Uint32 &vertex_count)
480 {
481 	CalCoreMesh *core_mesh;
482 	Sint32 i, j;
483 	Sint32 count;
484 
485 	face_count = 0;
486 	vertex_count = 0;
487 
488 	for (i = 0; i < core_model->getCoreMeshCount(); i++)
489 	{
490 		core_mesh = core_model->getCoreMesh(i);
491 		count = core_mesh->getCoreSubmeshCount();
492 		for (j = 0; j < count; j++)
493 		{
494 			CalCoreSubmesh *core_sub_mesh = core_mesh->getCoreSubmesh(j);
495 			face_count += core_sub_mesh->getFaceCount();
496 			vertex_count += core_sub_mesh->getVertexCount();
497 		}
498 	}
499 }
500 
convert_indices(Uint32 * data,const CalIndex * indices,const Uint32 count)501 static inline void convert_indices(Uint32* data, const CalIndex* indices, const Uint32 count)
502 {
503 	Uint32 i;
504 
505 	for (i = 0; i < count * 3; i++)
506 	{
507 		data[i] = indices[i];
508 	}
509 }
510 
pack_indices(Uint16 * data,const Uint32 * indices,const Uint32 count)511 static inline void pack_indices(Uint16* data, const Uint32* indices, const Uint32 count)
512 {
513 	Uint32 i;
514 
515 	for (i = 0; i < count * 3; i++)
516 	{
517 		data[i] = indices[i];
518 	}
519 }
520 
build_buffers(actor_types * a)521 extern "C" void build_buffers(actor_types* a)
522 {
523 	float* vertex_buffer;
524 	float* normal_buffer;
525 	float* weight_buffer;
526 	float* matrix_index_buffer;
527 	float* texture_coordinate_buffer;
528 	CalIndex* indices;
529 	ActorVertex* buffer;
530 	Uint32* data32;
531 	Uint32 face_count, vertex_count, max_index;
532 	Sint32 i, j;
533 	Uint32 offset, count;
534 #ifdef	USE_ACTORS_OPTIMIZER
535 	MD5_DIGEST digest;
536 	Uint32 size, tmp;
537 	bool loaded;
538 #endif	/* USE_ACTORS_OPTIMIZER */
539 
540 	face_count = 0;
541 	vertex_count = 0;
542 
543 	LOG_INFO("Build vertex buffers for '%s'", a->actor_name);
544 
545 	calculate_face_and_vertex_count(a->coremodel, face_count, vertex_count);
546 
547 	a->hardware_model = new CalHardwareModel(a->coremodel);
548 
549 	vertex_buffer = new float[32768 * 3];
550 	normal_buffer = new float[32768 * 3];
551 	weight_buffer = new float[32768 * 4];
552 	matrix_index_buffer = new float[32768 * 4];
553 	texture_coordinate_buffer = new float[32768 * 2];
554 	indices = new CalIndex[65536 * 3];
555 
556 	a->hardware_model->setVertexBuffer(reinterpret_cast<char*>(vertex_buffer),
557 		3 * sizeof(float));
558 	a->hardware_model->setNormalBuffer(reinterpret_cast<char*>(normal_buffer),
559 		3 * sizeof(float));
560 	a->hardware_model->setWeightBuffer(reinterpret_cast<char*>(weight_buffer),
561 		4 * sizeof(float));
562 	a->hardware_model->setMatrixIndexBuffer(reinterpret_cast<char*>(matrix_index_buffer),
563 		4 * sizeof(float));
564 	a->hardware_model->setTextureCoordNum(1);
565 	a->hardware_model->setTextureCoordBuffer(0,
566 		reinterpret_cast<char*>(texture_coordinate_buffer), 2 * sizeof(float));
567 	a->hardware_model->setIndexBuffer(indices);
568 
569 	a->hardware_model->load(0, 0, max_bones_per_mesh);
570 
571 	buffer = new ActorVertex[a->hardware_model->getTotalVertexCount()];
572 
573 	for (i = 0; i < a->hardware_model->getTotalVertexCount(); i++)
574 	{
575 //		buffer[i].m_bone_count = 0;
576 		for (j = 0; j < 3; j++)
577 		{
578 			buffer[i].m_vertex[j] = vertex_buffer[i * 3 + j];
579 		}
580 		for (j = 0; j < 4; j++)
581 		{
582 			buffer[i].m_weight[j] = (Uint8)(weight_buffer[i * 4 + j] * 255.0f + 0.5f);
583 /*			if (weight_buffer[i * 4 + j] > 0.0f)
584 			{
585 				buffer[i].m_bone_count = j + 1;
586 			}*/
587 		}
588 		for (j = 0; j < 3; j++)
589 		{
590 			buffer[i].m_normal[j] = normal_buffer[i * 3 + j];
591 		}
592 		for (j = 0; j < 4; j++)
593 		{
594 			buffer[i].m_index[j] = (Uint8)(matrix_index_buffer[i * 4 + j]);
595 		}
596 		for (j = 0; j < 2; j++)
597 		{
598 			buffer[i].m_texture[j] = texture_coordinate_buffer[i * 2 + j];
599 		}
600 	}
601 
602 	ELglGenBuffersARB(1, &a->vertex_buffer);
603 	ELglBindBufferARB(GL_ARRAY_BUFFER_ARB, a->vertex_buffer);
604 
605 	ELglBufferDataARB(GL_ARRAY_BUFFER_ARB, a->hardware_model->getTotalVertexCount() *
606 		sizeof(ActorVertex), buffer, GL_STATIC_DRAW_ARB);
607 
608 	ELglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
609 
610 	max_index = 0;
611 
612 	for (i = 0; i < a->hardware_model->getHardwareMeshCount(); i++)
613 	{
614 		a->hardware_model->selectHardwareMesh(i);
615 
616 		offset = a->hardware_model->getStartIndex();
617 		count = a->hardware_model->getBaseVertexIndex();
618 
619 		for (j = 0; j < a->hardware_model->getFaceCount(); j++)
620 		{
621 			indices[j * 3 + 0 + offset] += count;
622 			indices[j * 3 + 1 + offset] += count;
623 			indices[j * 3 + 2 + offset] += count;
624 			max_index = std::max(max_index, static_cast<Uint32>(indices[j * 3 + 0 + offset]));
625 			max_index = std::max(max_index, static_cast<Uint32>(indices[j * 3 + 1 + offset]));
626 			max_index = std::max(max_index, static_cast<Uint32>(indices[j * 3 + 2 + offset]));
627 		}
628 	}
629 
630 	ELglGenBuffersARB(1, &a->index_buffer);
631 	ELglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, a->index_buffer);
632 
633 	data32 = new Uint32[a->hardware_model->getTotalFaceCount() * 3];
634 
635 	convert_indices(data32, indices, a->hardware_model->getTotalFaceCount());
636 
637 #ifdef	USE_ACTORS_OPTIMIZER
638 	loaded = false;
639 
640 	size = a->hardware_model->getTotalFaceCount() * 3 * sizeof(Uint32);
641 
642 	{
643 		MD5 md5;
644 
645 		MD5Open(&md5);
646 
647 		MD5Digest(&md5, data32, size);
648 
649 		MD5Close(&md5, digest);
650 	}
651 
652 	try
653 	{
654 		std::ostringstream file_name;
655 
656 		file_name << "cache/actor_" << a->actor_type << "_" << max_bones_per_mesh << ".elc";
657 
658 		if (eternal_lands::el_file::file_exists(file_name.str(), get_path_config_base()))
659 		{
660 			eternal_lands::el_file file(file_name.str(), true, get_path_config_base());
661 			if (static_cast<Uint32>(file.get_size()) != (size + sizeof(MD5_DIGEST) + sizeof(Uint32) * 2))
662 			{
663 				EXTENDED_EXCEPTION(ExtendedException::ec_io_error, "File '" <<
664 					file_name.str() << "' has wrong size. Size " << (size +
665 					sizeof(MD5_DIGEST) + sizeof(Uint32) * 2) << " expected, "
666 					<< "but found size " << file.get_size());
667 			}
668 			if (memcmp(digest, file.get_pointer(), sizeof(MD5_DIGEST)) != 0)
669 			{
670 				EXTENDED_EXCEPTION(ExtendedException::ec_io_error, "File '" <<
671 					file_name.str() << "' has wrong md5 for data.");
672 			}
673 			file.seek(sizeof(MD5_DIGEST), SEEK_SET);
674 			file.read(sizeof(Uint32), &tmp);
675 			if (tmp != size)
676 			{
677 				EXTENDED_EXCEPTION(ExtendedException::ec_io_error, "File '" <<
678 					file_name.str() << "' is for wrong number of indices.");
679 			}
680 			file.read(sizeof(Uint32), &tmp);
681 			if (tmp != max_bones_per_mesh)
682 			{
683 				EXTENDED_EXCEPTION(ExtendedException::ec_io_error, "File '" <<
684 					file_name.str() << "' is for wrong number of bones.");
685 			}
686 
687 			file.read(size, data32);
688 
689 			loaded = true;
690 		}
691 	}
692 	CATCH_AND_LOG_EXCEPTIONS
693 
694 	if (!loaded)
695 	{
696 		std::ostringstream file_name;
697 
698 		for (i = 0; i < a->hardware_model->getHardwareMeshCount(); i++)
699 		{
700 			a->hardware_model->selectHardwareMesh(i);
701 
702 			count = a->hardware_model->getFaceCount();
703 
704 			optimize_vertex_cache_order(data32, a->hardware_model->getStartIndex(), count * 3, count * 3);
705 		}
706 
707 		file_name << get_path_config_base() << "cache/actor_" << a->actor_type << "_" << max_bones_per_mesh << ".elc";
708 
709 		LOG_INFO("Rebuilding file '%s'", file_name.str().c_str());
710 
711 		mkdir_tree(file_name.str().c_str(), 0);
712 
713 		std::ofstream file(file_name.str().c_str());
714 
715 		file.write(reinterpret_cast<char*>(digest), sizeof(MD5_DIGEST));
716 		file.write(reinterpret_cast<char*>(&size), sizeof(Uint32));
717 		file.write(reinterpret_cast<char*>(&max_bones_per_mesh), sizeof(Uint32));
718 
719 		file.write(reinterpret_cast<char*>(data32), size);
720 
721 		file.close();
722 	}
723 #endif	/* USE_ACTORS_OPTIMIZER */
724 
725 	if (max_index <= std::numeric_limits<Uint16>::max())
726 	{
727 		Uint16* data16;
728 
729 		data16 = new Uint16[a->hardware_model->getTotalFaceCount() * 3];
730 
731 		pack_indices(data16, data32, a->hardware_model->getTotalFaceCount());
732 		a->index_type = GL_UNSIGNED_SHORT;
733 		a->index_size = sizeof(GLushort);
734 
735 		ELglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
736 			a->hardware_model->getTotalFaceCount() * 3 * sizeof(GLushort), data16,
737 			GL_STATIC_DRAW_ARB);
738 		delete[] data16;
739 	}
740 	else
741 	{
742 		a->index_type = GL_UNSIGNED_INT;
743 		a->index_size = sizeof(GLuint);
744 
745 		ELglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
746 			a->hardware_model->getTotalFaceCount() * 3 * sizeof(GLuint), data32,
747 			GL_STATIC_DRAW_ARB);
748 	}
749 
750 	ELglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
751 
752 	delete[] vertex_buffer;
753 	delete[] normal_buffer;
754 	delete[] weight_buffer;
755 	delete[] matrix_index_buffer;
756 	delete[] texture_coordinate_buffer;
757 	delete[] indices;
758 	delete[] buffer;
759 	delete[] data32;
760 
761 	LOG_INFO("Build vertex buffers for '%s' done", a->actor_name);
762 }
763 
clear_buffers(actor_types * a)764 extern "C" void clear_buffers(actor_types* a)
765 {
766 	delete a->hardware_model;
767 }
768 
set_transformation_buffer(actor_types * a,actor * act,const Uint32 index,HardwareMeshData & hmd)769 static inline void set_transformation_buffer(actor_types *a, actor *act, const Uint32 index,
770 	HardwareMeshData &hmd)
771 {
772 	Sint32 i, count;
773 	const std::vector<CalBone *>& vectorBone = act->calmodel->getSkeleton()->getVectorBone();
774 
775 	a->hardware_model->selectHardwareMesh(index);
776 
777 	count = a->hardware_model->getBoneCount();
778 
779 	for (i = 0; i < count; i++)
780 	{
781 		const CalVector &translationBoneSpace = vectorBone[a->hardware_model->getVectorHardwareMesh()[index].m_vectorBonesIndices[i]]->getTranslationBoneSpace();
782 		const CalMatrix &rotationMatrix = vectorBone[a->hardware_model->getVectorHardwareMesh()[index].m_vectorBonesIndices[i]]->getTransformMatrix();
783 
784 		hmd.set_buffer_value(i * 12 +  0, rotationMatrix.dxdx);
785 		hmd.set_buffer_value(i * 12 +  1, rotationMatrix.dxdy);
786 		hmd.set_buffer_value(i * 12 +  2, rotationMatrix.dxdz);
787 		hmd.set_buffer_value(i * 12 +  3, translationBoneSpace.x);
788 		hmd.set_buffer_value(i * 12 +  4, rotationMatrix.dydx);
789 		hmd.set_buffer_value(i * 12 +  5, rotationMatrix.dydy);
790 		hmd.set_buffer_value(i * 12 +  6, rotationMatrix.dydz);
791 		hmd.set_buffer_value(i * 12 +  7, translationBoneSpace.y);
792 		hmd.set_buffer_value(i * 12 +  8, rotationMatrix.dzdx);
793 		hmd.set_buffer_value(i * 12 +  9, rotationMatrix.dzdy);
794 		hmd.set_buffer_value(i * 12 + 10, rotationMatrix.dzdz);
795 		hmd.set_buffer_value(i * 12 + 11, translationBoneSpace.z);
796 	}
797 }
798 
set_transformation_buffers(actor * act)799 extern "C" void set_transformation_buffers(actor* act)
800 {
801 	IntMap* im;
802 	IntMap::iterator it;
803 	actor_types* a;
804 
805 	im = reinterpret_cast<IntMap*>(act->calmodel->getUserData());
806 
807 	a = &actors_defs[act->actor_type];
808 
809 	assert(im);
810 
811 	for (auto& it: *im)
812 	{
813 		set_transformation_buffer(a, act, it.first, it.second);
814 	}
815 }
816 
build_actor_bounding_box(actor * a)817 extern "C" void build_actor_bounding_box(actor* a)
818 {
819 	CalSkeleton* cs;
820 	Uint32 i;
821 	float t;
822 
823 	if (a->calmodel)
824 	{
825 		cs = a->calmodel->getSkeleton();
826 		cs->getBoneBoundingBox(a->bbox.bbmin, a->bbox.bbmax);
827 
828 		for (i = 0; i < 3; i++)
829 		{
830 			t = a->bbox.bbmax[i] - a->bbox.bbmin[i];
831 			a->bbox.bbmin[i] -= std::max(t * 0.25f - 0.25f, 0.1f);
832 			a->bbox.bbmax[i] += std::max(t * 0.25f - 0.25f, 0.1f);
833 		}
834 	}
835 }
836 
model_new(CalCoreModel * pCoreModel)837 extern "C" CalModel *model_new(CalCoreModel* pCoreModel)
838 {
839 	CalModel* tmp;
840 
841 	tmp = new CalModel(pCoreModel);
842 
843 	tmp->setUserData(new IntMap());
844 
845 	return tmp;
846 }
847 
model_delete(CalModel * self)848 extern "C" void model_delete(CalModel *self)
849 {
850 	if (self)
851 	{
852 		delete reinterpret_cast<IntMap*>(self->getUserData());
853 		self->setUserData(0);
854 	}
855 
856 	delete self;
857 }
858 
model_attach_mesh(actor * act,int mesh_id)859 extern "C" void model_attach_mesh(actor *act, int mesh_id)
860 {
861 	IntMap* im;
862 	actor_types* a;
863 	int i, count;
864 
865 	assert(act);
866 
867 	assert(act->calmodel);
868 
869 	act->calmodel->attachMesh(mesh_id);
870 
871 	im = reinterpret_cast<IntMap*>(act->calmodel->getUserData());
872 
873 	assert(im);
874 
875 	a = &actors_defs[act->actor_type];
876 
877 	if (a->hardware_model)
878 	{
879 		count = a->hardware_model->getVectorHardwareMesh().size();
880 
881 		for (i = 0; i < count; i++)
882 		{
883 			if (a->hardware_model->getVectorHardwareMesh()[i].meshId == mesh_id)
884 			{
885 				std::pair<Sint32, HardwareMeshData> p = std::pair<Sint32,
886 					HardwareMeshData>(i, HardwareMeshData(mesh_id,
887 					max_bones_per_mesh * 3));
888 				im->insert(p);
889 				set_transformation_buffer(a, act, p.first, p.second);
890 			}
891 		}
892 	}
893 }
894 
model_detach_mesh(actor * act,int mesh_id)895 extern "C" void model_detach_mesh(actor *act, int mesh_id)
896 {
897 	IntMap* im;
898 	actor_types* a;
899 	int i, count;
900 
901 	assert(act);
902 
903 	assert(act->calmodel);
904 
905 	act->calmodel->detachMesh(mesh_id);
906 
907 	im = reinterpret_cast<IntMap*>(act->calmodel->getUserData());
908 
909 	assert(im);
910 
911 	a = &actors_defs[act->actor_type];
912 
913 	if (a->hardware_model)
914 	{
915 		count = a->hardware_model->getVectorHardwareMesh().size();
916 
917 		for (i = 0; i < count; i++)
918 		{
919 			if (a->hardware_model->getVectorHardwareMesh()[i].meshId == mesh_id)
920 			{
921 				im->erase(i);
922 			}
923 		}
924 	}
925 }
926 
927