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